-
Notifications
You must be signed in to change notification settings - Fork 2k
RSpecとCapybaraを使ってChromeでjsをレンダリングした結果の画面内容をテストする #5961
RSpecとCapybaraを使ってChromeでjsをレンダリングした結果の画面内容をテストする #5961
Conversation
- http://localhost:3000 を対象にテストする - ChromeDriver を使って Headless Chrome を iPhone6/7/8 デバイスエミュレーションモードでテストする
- SiteTopUpper の高さ (約1600px) の分をスキップ - div.v-lazy の中に div.row が2つ入ってる - min-height (600px) ずつスクロールする
- 各言語に対応した h3
- 各言語に対応した h3
- 各言語に対応した h3
@suzuryo PRありがとうございます!これって、どのように使うのでしょうか...?手順を教えていただけると助かります。 |
@kaizumaki issue #5960 の方に実行手順を書いてありますが、もっと詳しく手順書が必要でしょうか? |
ああ、なるほど!issueに書いてくださってたんですね。ありがとうございます。 |
手順書はissueだと流れてしまうので、ソースコード内のどこかに書いておいてもらえると嬉しいです 🙏 |
@kaizumaki FOR_DEVELOPERS_RSPEC.md にまとめました |
あと |
@suzuryo ドキュメントありがとうございます!私の手元環境でやってみました。 まず、環境構築のChromeDriverの「PATHを通す」というところがピンときませんでした(macなので、あまりその辺のお作法をわかっておらず...)。 その後無事動いたのですが、そもそもブラウザテストのことをよくわかってなかったです。これって「動作テスト」が主な役割なのですかね?「表示」についてのテストは、カードのタイトル部を確かめているのでしょうか。 それと、動作テストであるなら、各グラフの下のテーブルも開閉するかどうかがあるといいなと思いました。 また、テストの内容のメンテナンスが心配になりました。今後もコンポーネントが増えたりレイアウトが変わったりする可能性は十分にあるので。 お願いが多くて恐縮です 🙇♀️ できる範囲で、段階的にでも構いません。まずはご意見伺いたく思います。 |
環境構築はいろんな作法があるので最低限の条件「PATHを通す」とだけ書いておきました。
などいろんな方法があります。 「動作テスト」としてDOMの要素をクリックして、結果として求めるDOM構造に変化したか、などの動作をテストできます。 682eeed#diff-15ab8ca31a3d32bfc064f0e6176824baa252939c5ab5e90fae74550b4213fc0dR19-R22 の部分では
という構造がブラウザ内に存在することをテストしています。 「表示テスト」として、特定のDOMに求める属性が設定されていることをテストできます。 1a9de9b#diff-5b22336129d546b6e79911431ca0f14a893e79cbd29f6f76c7442a6ab0b3fad0R13-R15 の部分では http://localhost:3000/ にアクセスしたら、
という構造が存在し、 http://localhost:3000/en/ にアクセスしたら、
http://localhost:3000/zh-cn/ にアクセスしたら、
と言語ページによってロゴ画像のsrc属性が差し代わっていることをテストしています。 259bb6f#diff-dc36b9cee656b5f983f8903f63b7c53b438831cd89bf8752a73cdee4731112ffR14 の部分では
のd=の中身が M3,14L3.5... (指定したSVGの文字列)であること、 つまり 259bb6f#diff-dc36b9cee656b5f983f8903f63b7c53b438831cd89bf8752a73cdee4731112ffR18 の部分では http://localhost:3000/ にアクセスしたら、
http://localhost:3000/en/ にアクセスしたら、
http://localhost:3000/zh-cn/ にアクセスしたら、
という文字列になっていることをテストしています。 「何のテストが通ったか」を全部出力すると冗長なので、「失敗したテスト項目」だけが出力されるようにしています。 テストを実行するコマンド
に formatオプションを渡して
と実行すると、今どのテストが成功・失敗しているのか、もう少し詳細が出力されます。
岩手版では「データを表示 をクリックしてv-expantion-panel開いて、そこに表示されたテーブルの上から4行目のtdの中身が期待した値になっているか」など詳しくチェックしています。 これも、どこまで詳しくテスト項目に含めるか、ということなので、東京版ではどこまでテストを求めるかを決めていただければ。 「内容のメンテナンス」は仕様が変化すれば、それに追従してテスト内容も変化する必要があります。 テストコードを充実させたり、仕様の変更に追従させるのは、そこそこ体力が必要になります。 |
@suzuryo 解説ありがとうございます!丁寧に書いていただき助かります。 表示テストについて、h3タイトルのテキストなどはよっぽどのことがない限り変更がかかることはないと思っているんですが、ここのテストが失敗する場合っていうのは、どういう状況が考えられるでしょうか?例えば、カードごとまるっと非表示になってしまうとかですかね? というのも、いまご提示いただいた内容でテストを回すと3分30秒かかっており、github actionsで回す際の負荷がどれぐらいかかるかが気になっています。
これはまったくその通りですね。そのあたりは運営で方針を考えようと思います。 いずれにせよ、当サイトの運用での決めの問題であると理解しました。少しお時間いただけると助かります 🙏 |
例えば h3 のテキストの中身が期待した値とイコール(eq)かどうか、翻訳が正しく当たっているかだけをテストしているコードに見えますが、 実際には
というアプリケーションの実装の動き
を、結果としてテストしていることになります。 なので、このテストが失敗するとしたら
という、nuxtアプリケーションの実装面での出来事や、
という、関連ライブラリのバージョンアップによる意図しない挙動の変更(当初の目的の更新負荷低減のためにリグレッションテスト) これらを暗に含んだ「jsがブラウザで表示されるまで」の項目をテストしていることになります。 |
failする多くは、タイミング問題で、lazyで読み込んでいる部分を、読み込み完了する前のタイミングでテストが動いてしまった場合です。何かの要素をclickするテストを書いたら、その後にsleep 1とかすると回避できるような問題です。本来はlazy処理が完了するまでテストの実行を待つような仕組みを実装すると良いですが、今はsleepで回避しています。 ほか、
など細かい挙動の部分でfailしたことがありました。 ほか、ページ上の全てのaタグに設定されているhrefのURLが存在しているかリンク切れ(実際にアクセスして200 OK)をチェックをしているので、 |
全ての言語の
が出ててもよい(対応する翻訳キーが準備できていなくてもよい)ならば、全言語に対してテキストの確認は回さなくても良いかもです。
テストを実行するときに # 全部のテストを並列に実行 (parallel_rspec)
$ bundle exec parallel_rspec spec のコマンドを使うと、搭載しているCPUをフルに使って並列実行するので、16コアならば16並列で処理しますが、Github Actionsを動かすGitHub-hosted runnersのスペックは 2-core なので、2並列の処理になるので、そこそこ時間がかかります。 岩手版だとja/enの2言語しか対応していないので2言語分ですが、7分くらい https://github.com/MeditationDuck/covid19/actions?query=workflow%3AgoogleSheetMenu_development |
岩手版はテストを回してpassすることを確認できているので、node は 14.15.4 の最新安定板で運用しています。 |
@suzuryo 丁寧な解説ありがとうございます!わかりやすくて助かります。 #5961 (comment) については、なるほどです。この工程は必要ですね。そもそもRenovateの更新負荷低減が動機でしたから。
これは出ててもいいと思っています。
これは非常にいいですね! いま運営で、どのPRのActionsに紐付けるか検討していますので、しばしお待ちください。導入後も、もし負荷が目に余る状態になってきたら、解除することもありえますこと、ご了承いただけたらと思います。 あと、追加でテストしたいのは、テーブルの開閉ですかね。 |
Rubyの環境によっては vendor/bundle に Gem がインストールされるかも
Rubyの環境構築方法によっては vendor フォルダが生成されるので、ignoreしました Cardにid属性が付与されていないとテストのセレクタを書きづらいので、cards以下のコンポーネントにid属性を付与しました nth-child()を使ったセレクタから、id属性を使ったセレクタに書き換えました
がテストされなくなります。 |
つまり nth-child でセレクタを指定しないので ``` CardsReference のカードの位置を変えた、つまり、<cards-lazy-row :rows="rows" />のrows[]の配列の順番が変わった ``` という暗黙的なテスト項目はテスト対象要素から外れた
d111635
to
90ece95
Compare
@suzuryo もろもろありがとうございます 🙇♀️
ということで、軒並み失敗してしまいました。 |
@kaizumaki Finished より前に、どんなエラーが出力されているかによりますが、ローカルのwebサーバーが立っていなくて http://localhost:3000 にアクセスできていないとか? |
workflowsとして on:
push:
branches:
- 'renovate/**' と書くと、renovate が |
@suzuryo
|
@kaizumaki 手順の2.2 / 2.3 のproductionコードをbuildして |
@suzuryo いやー、 |
@kaizumaki Finished の前にもログが出力されていると思いますので、全ログをgistなどでコピペください |
@kaizumaki これは、 45a87a3 に実装を変更してあります。なので、cardに対してidが割り振られていないproduction buildに対してrspecするとfailすると思われます。 |
@suzuryo いや、cardにidはふってありますね。このPRをpullして試しているので。それともキャッシュでしょうか... |
@kaizumaki |
@suzuryo いろいろ試してみて、わかりました!ビルドされたコードからid属性が除去されているパターンがありました。
最終的に |
@kaizumaki ではidじゃなくてclass付与で実装してみます |
ビルドされたコードからid属性が除去される場合があるため Tokyo-Metro-Gov#5961 (comment)
@kaizumaki id付与からclass付与に実装を変更しました |
@suzuryo 最新のコミット、pullして試しました。テストは無事に通りました。ドキュメントの更新もありがとうございます! |
@kaizumaki |
@suzuryo ありがとうございます。かなりいい感じになったなと思っています。
あとはどこにフックするかですね。運営内で相談しますので、もうしばらくお待ちください 🙇♀️ |
``` bundle update ``` - capybara 3.34.0 -> 3.35.3 - regexp_parser 1.8.2 -> 2.0.3 - rspec-mocks 3.10.1 -> 3.10.2 - rspec-support 3.10.1 -> 3.10.2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTMです。workflowへの組み込みは運営側で行います。
ビルドされたコードからid属性が除去される場合があるため Tokyo-Metro-Gov#5961 (comment)
👏 解決する issue / Resolved Issues
📝 関連する issue / Related Issues
⛏ 変更内容 / Details of Changes