📝

Rspecテスト

2023/06/25に公開

はじめに

ポートフォリオ作成中のプログラミング初学者です🔰
テストコードを書く前にテストはなぜするのか?Rspecとは何なのか?ちゃんと理解しておこうと思います!

テストの種類について

一般的にテストとして出てくるものとして「単体テスト」と「結合テスト」が存在する!

単体テスト UnitTest(UT)

単体テストとはクラスやメソッド(関数)といった単位でのテストのこと。
機能単体でプログラムが正常に動くかを検証するもの。

  • 空白チェック
  • 文字列チェック
  • 数値チェック

など!

単体テストの目的は、個々の部分が正しく動作することを確認し、エラーやバグを早期に見つけ出すことです。

結合テスト Integration Test(IT)

結合テストでは単体テストの組み合わせで期待とする動作が行えているかをテストします。
機能を組み合わせて正常に動くかを検証するもの。

例として挙げると、「フォームに値を入力して、送信ボタンを押すと値が保存される」といったものです。

結合テストの目的は、システム全体が一緒に動作するときに問題が発生しないことを確認することです。

TDD

現場によっては機能要件からテストを先に記述して、テスト要件を満たすように実装とリファクタリングをするテスト駆動開発(TDD = Test Driven Development)といった開発手法もあるらしい!

Rspecとは

RubyやRuby on Railsで作ったクラスやメソッドをテストするためのドメイン特化言語 (DSL)を使ったフレームワークのこと。(テスト専用のプログラム言語とも言える!)

ドメイン特化言語とは(Domain-Specific Language)
特定の作業や問題解決を目的に設計されたプログラミング言語。

  • Gemでインストール可能なので、導入が簡単

  • コードが読みやすく、ドキュメントも豊富

  • BDD(Behavior Driven Development:振る舞い駆動開発)を強く支持している。

BDDはTDD(Test Driven Development:テスト駆動開発)の一種であり、ソフトウェアの期待される振る舞いに焦点を当てた開発手法のこと。

Rspecを行う目的

ソフトウェアの品質を向上させること。

  • バグを見つけやすくする
  • 自動化で効率的
  • 手動で行うよりも信頼性・再現性がある
  • コードの品質を維持しながら柔軟に開発が行える

Rspecの構成

Rspecは、テストケースを記述するためのDSL(Domain-Specific Language)を提供しています。これにより、自然言語に近い形式でテストを書くことができます。

DSLとは?
特定の作業の遂行や問題の解決に特化して設計されたコンピュータ言語

Rspecでは以下のような概念や要素を使用します。

RSpecのテスト例
describe Calculator do
  describe "#add" do
    it "adds two numbers correctly" do
      calculator = Calculator.new
      expect(calculator.add(1, 2)).to eq 3
    end
  end
end

上記の例では、Calculatorクラスがテスト対象で、その中の #add メソッドが機能を満たしているかをテストしています。具体的には、1 と 2 を加算した結果が 3 になることを期待しています。

expect().toの部分は「()内の値が期待値となるように」という意味があり、エクスペクテーションと呼ばれます。
eqはeqに続く値が期待値と同値であるかを判定しています。eqの部分はマッチャーと呼ばれます。

マッチャーはeqではなく後にも記載があるように、様々な種類が存在しています。RSpecでは基本的にエクスペクテーションと様々なマッチャーの組み合わせでテストを行っていきます。

  • Describe
    describe ブロックは、「テストの対象」となる「何か」を定義します。これは通常、クラス名やメソッド名を引数として取ります。describe ブロックの中には複数の it ブロックを持つことができます。

  • Context
    Describeブロック内で、異なる状況や条件を示すためにContextブロックを使用します。複数のテストケースをまとめる際に便利です。

  • It
    DescribeやContextブロック内で、具体的なテストケースを記述します。it ブロックは、テストの対象が行うべき「何か」を定義します。このブロックの中にはテストコードが含まれ、その結果に基づいてテストが成功するか失敗するかが決まります。

  • Expect
    expect メソッドは、テスト結果の期待値を表現します。これは通常、it ブロック内で使用され、結果が期待通りであるかどうかを判断します。

Rspecでは、これらの要素を組み合わせてテストスイートを構築します。テストスイートは複数のDescribeブロックやContextブロック、Itブロックから成り立ち、各テストケースが順に実行されます。テスト結果は合格(パス)または不合格(失敗)として表示されます。

よく使われるマッチャー

マッチャーとは、「期待値と実際の値を比較して、一致した(もしくは一致しなかった)という結果を返すオブジェクト」のこと。

マッチャー名 機能
be_valid 有効であるか
be_invalid 無効であるか
include 配列に指定の値が含まれているか
find 要素の検索を行う
click クリックを行う
have_content 文字列が存在するか
have_link 指定の値のリンクが存在するか
eq 期待値と値を比較して一致するか
have_selector HTMLタグやCSSに指定の文字列が存在するか
have_field 入力フォームが存在するか
find_all ページ上の指定のHTMLタグを全て取得する
match メソッドを使用して期待値と一致するか
have_button ページ上に指定のボタンが存在するか
click_button 指定のボタンをクリックする
have_current_path パスを取得できる
change ある動作Aに対してBが変動するか

さいごに

今は仕事ではない+時間がなく、全ての項目においてのテストコードは書くことができず、大事なロジックのところだけ作成しますが、実務では開発よりテストの方にかける時間の方が多いそうでとても重要な部分です!

わたしはテストはテストを書く担当がいるんだと思い込んでいましたが、自分のコードは自分でテストコードを書けるのが当たり前みたいです。もちろんテストを任せるところもあるようですが、そちらは商品を守る、開発者はコードを守るイメージ?小さい会社では違うかも?

もしデプロイ後に、金額面などでバグが出てしまうと会社の売上や信頼に大きく関わってきます!
いろんな可能性を見据えてテストコードを書かなければいけないとのことですが、
まだその段階ではないのでまずは書けるように、やってみます!💪🏻

参考にさせていただいた記事🌱

https://qiita.com/jnchito/items/2a5d3e15761fd413657a

https://zenn.dev/yuji_developer/articles/52cc0e356b3748

https://qiita.com/takutoy/items/c684f761c655d832e5d2

Discussion