【Rspec】data-testidを使ってテスト対象を明確にする
Capybaraでsystem specを書いている際に、「ある操作をしたら、特定の要素が画面に表示されているか確認したい」時が出てきました。
そんな時に、data-testidタグをテスト対象のタグに追加すると便利だったという話です。
使用例
例えば、/hoge へアクセスして、hogeボタンをクリックした時に、画面にHoge Hogeが表示されていることをテストしたい場合。
context 'when click button Hoge'
visit hoge_url
click_on("Hoge")
it '' do
expect(page).to have_selector("Hoge Hoge")
end
end
context 'when not click button Hoge'
visit hoge_url
it '' do
expect(page).to have_no_selector("Hoge Hoge")
end
end
ただ、画面にHoge Hogeがすでに表示されている場合(フッターやヘッダーに同じ文言のリンクが存在している時など)は、上記のテストだと網羅できません。
idを使えば?
idにtest-hogeのようなタグを追加すると、下記のような問題点が出てきます。
- テストの時しか使わないのに、idにtest-〇〇が使われてると他のDOM操作がしづらい。
- id名にテストが依存する
id名よりdata-testidの方が変更頻度が少ない。
なので、依存するならdata-testid名に依存した方がいいですよね。
Why you shouldn't use ids in E2E testing | Autify Blog
data-testid
そこでdata-testidを使う。見るからにテスト専用のタグだとわかるので、開発者からすればありがたい。
<%= model,class: 'btn', data-testid: ‘hogehoge’>
testは下記のように書きます。
expect(page).to have_css("[data-testid='hogehoge']")
いちいち[data-testid=’~~’]と書くことが面倒な場合は、capybara.rbに下記を追加します。
Capybara.add_selector(:testid) do
css do |val|
%([data-testid="#{val}"])
end
end
そうすると、テストは下記にように変わります。便利ですね。
expect(page).to have_css(:testid, 'hogehoge')
非推奨?
「ユーザーに表示したい要素ではないから、他のquery(javascriptだとgetByRoleやetByLabelText)を使えるのであれば、極力testidの使用は控えるべき」との意見もあります。
Why You Should Avoid Testing React Components With Test IDs
確かに、実際の環境下で表示されないものをE2Eで使うべきではないかもしれないです。
ただ、現状使い勝手がいいという理由でdata-testidを使っています。
rubyでdata-testid以外に、テスト時に使えるよさそうなタグがあれば教えていただきたいです。
参考文献
Why you shouldn't use ids in E2E testing | Autify Blog
Discussion