LoginSignup
45
18

More than 3 years have passed since last update.

テストコードは誤検知が発生しにくい書き方を選ぼう

Last updated at Posted at 2019-09-20

今現在RSpecの学習のために『Everyday Rails - RSpecによるRailsテスト入門』を読んでいるところなのですが、3章でわからない記述が出てきたので個人的に調べてみて理解した内容をまとめます。RSpec初学者向けの小粒な記事になります。

次のコードは、3章の「バリデーションをテストする」という見出しの最初に示されている実例です。Userモデルの存在性のバリデーションがうまく働いているかどうかをテストするexampleになります。

# 名がなければ無効な状態であること
it "is invalid without a first name" do
  user = User.new(first_name: nil)
  user.valid?
  expect(user.errors[:first_name]).to include("can't be blank")
end

このブロックの最後の2行についてなんですが、私が初めに見たときは
単に無効であることを調べるだけならexpect(user.valid?).to eq falseの1行で済む話じゃないの?なんでわざわざ「エラー文を生成→その内容を確認」なんていう書き方をするんだろうか
と、疑問に思ってしまったのでした(私だけでしょうか?)

しかし調べてみるとこれにはちゃんとした理由があるようです。

というのも、先程の2行をexpect(user.valid?).to eq falseという1行にしてしまった場合、

仮にテストがパスした(user.valid?がfalseを返した)としても、本当に存在性のバリデーションに引っかかったのかどうかが分からない(別のバリデーションが原因で無効になった可能性が生じてしまう)といった問題が出てくるのです。

一方で、元の記述であれば生成したインスタンスが無効であることを調べると同時に、無効になった原因まで特定することができるようになります。

user.valid? #エラー文を生成する
expect(user.errors[:first_name]).to include("can't be blank") # エラー文が存在性の検証に関するものであることを調べる

このように、テストの誤検知を防ぐためにも「今書こうとしているテストの目的は何か?」というところを、より突き詰めた書き方を意識していかないといけないようです。

45
18
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
45
18