【TestCafe】画像が遅れて表示されるので、テスト結果がコロコロ変わる件

5 min read読了の目安(約4700字

概要

僕は現在TestCafeというツールを使ってE2Eテストを作成しています。

テストを作成をしていると、以下の異常が発生しました。

同じコード、同じテスト対象、同じ環境なのに
テストを実行するたびに結果が違う!!!

どのような状況だったか説明していきます。

for (let i = 0; i < 19; i++) {
      // リストごとにいいねボタンの確認
      const likeBtnExists = await Selector("ul.senior-list")
        .child("li.senior-item")
        .nth(i)
        .child("div.message")
        .child("div.message-content")
        .child("div.like_button")
        .child("a.like_button")
        .child("img.like_before").exists;
	
   console.log(likeBtnExists)

上記のコードは、

  • 20件のリストがあり、existsオプションを使用して、20件のリストそれぞれにlikeBtnExistsが存在しているか。を判定するテストです。(実際は少し違います)
  • 期待する結果としては、全てにlikeBtnExistsが存在するので、console.log(likeBtnExists)の結果が、for文で回している20回分全てtrueになることを期待しています。

テスト対象のサイトと、検証画面はこんな感じです。↓↓


"イイネする"という画像が今回、likeBtnExistsで指定しているセレクターです。
この画像が20件のリストそれぞれに存在しています。

しかし、何度もテストを実行していると、

  1. 20回全てtrueの場合。(正常で期待している結果)
  2. 最後までfalse判定になることはないが、途中までfalse判定が出る。true判定が出だすと,そこから全てtrue。(原因不明の異常結果)

上記2パターンが結果として返ってきます。

1. 20回全てtrueの場合
0 true
1 true
2 true
3 true
4 true
5 true
6 true
7 true
8 true
9 true
10 true
11 true
12 true
13 true
14 true
15 true
16 true
17 true
18 true
19 true
2. 途中までfalse判定が出て、true判定が出だすと,そこから全てtrueが帰ってくる場合。
0 false
1 false
2 false
3 true
4 true
5 true
6 true
7 true
8 true
9 true
10 true
11 true
12 true
13 true
14 true
15 true
16 true
17 true
18 true
19 true

false判定されて、存在しないのなら問題ないのです。
しかし、falseが帰ってきているリストを確認すると、likeBtnExistsが存在しているのにも関わらず、
テスト結果では存在していたり、存在していなかったりする結果が返ってきている。

まとめると

  • なぜ、存在するのにfalse判定されているのか、
  • なぜ、同じコード、同じテスト対象なのにテストの結果が異なっているのか。

このような事象に悩まされていました。

結論

TestCafeの処理が始まったに画像が反映されている場合があることが原因。

TestCafe公式ドキュメントに以下の表記がありました。

Wait Mechanism for Assertions

Note that the Smart Assertion Query Mechanism does not wait for page elements to appear. If you need to wait for an element before executing an assertion, add another assertion that checks the selector's count or exists property.

日本語訳

スマート・アサーション・クエリ・メカニズムは、ページ要素の表示を待たないことに注意してください。アサーションを実行する前に要素を待つ必要がある場合は、セレクタの count または exists プロパティをチェックする別のアサーションを追加します。

つまり、

TestCafe(existsオプション)は要素の表示を待たない。
TestCafeはページ移動後に処理を開始するが、
"イイネする"画像はHTMLに組み込まれたJSのスクリプトが読み込まれた後に表示されるので、
ページ移動完了時と、画像表示完了時にタイムラグが発生している。

"イイネする"画像は、


上記画像に表示されている

<script type="text/javascript">

の中の処理が終わってから画像が反映されるという流れになっているということ。
(初めて知った)

なので、TestCafeの処理が

for (let i = 0; i < 19; i++) {
      // リストごとにいいねボタンの確認
      const likeBtnExists = await Selector("ul.senior-list")
        .child("li.senior-item")
        .nth(i)
        .child("div.message")
        .child("div.message-content")
        .child("div.like_button")
        .child("a.like_button")
        .child("img.like_before").exists;
	
   console.log(likeBtnExists)

ここのコードに辿り着くまでに、画像が表示されている時はtrue,間に合っていなければfalseになっていた。

ということです。

つまり先述した、2点の疑問については、

  1. 結果が20回全てtrueの場合。(正常で期待している結果)
    TestCafeの処理がlikeBtnExistsにたどり着くまでに、20件のリスト全てに画像が反映されている

  2. 途中までfalse判定が出て、true判定が出だすと,そこから全てtrueが帰ってくる場合。(原因不明の異常結果)
    TestCafeの処理がlikeBtnExistsにたどり着くまでに、20件のリスト全てに画像が反映されておらず、表示が追いついていない最初の方の部分がfalse判定されて、for文で回している間(タイムラグ)に画像が反映されて、途中からtrueに変化している

ってことでした!!!!
(こんなん気づかんて。。。)

なので対応策としてこちらを追加しました。

await Selector("img.like_before").with({ visibilityCheck: true })();

TestCafe visibilityCheck

visibilityCheckオプションは
テスト対象のページに、
指定した要素の有無をを判定してくれるメソッドです。

修正したコードがこちら。

修正したコード

// ここでいいね画像が表示されるまで待機(追加)
 await Selector("img.like_before").with({ visibilityCheck: true })();
  
  for (let i = 0; i < 19; i++) {
      // リストごとにいいねボタンの確認
      const likeBtnExists = await Selector("ul.senior-list")
        .child("li.senior-item")
        .nth(i)
        .child("div.message")
        .child("div.message-content")
        .child("div.like_button")
        .child("a.like_button")
        .child("img.like_before").exists;
	
   console.log(likeBtnExists)

このコードを追加することで、
コメント通りですが、画像の表示を確認してから、
以降のテストを実行することが出来、

  • なぜ、存在するのにfalse判定されているのか、
  • なぜ、同じコードなのにテストの結果が異なっているのか。

上記の問題を解決することが出来ました。

まとめ

今回学んだことは、

  1. 画像の表示にはタイムラグが発生する。
  2. TestCafe(existsオプション)は要素の表示を待たない。

結論、TestCafeの罠でもなんでもなく、
僕の知識不足、TestCafeの仕様確認不足でした。

この2点を知っていれば、このような問題に手こずらなかったはず。笑

TestCafe導入方法

TestCafeでCSVダウンロードテスト