非同期処理テストの効率化:Cypress Commands「tick」の代替方法


「tick」の仕組み

「tick」は、時間単位(ミリ秒)を指定して、仮想的な時間の経過をシミュレートします。具体的には、以下の処理を実行します。

  1. 指定された時間だけ待機します。
  2. 待機中に発生するイベントを処理します。
  3. 待機が完了したら、テストコードを続行します。

「tick」の使用方法

「tick」は、以下の構文で使用します。

cy.tick(milliseconds);

ここで、milliseconds は待機する時間(ミリ秒)を指定します。

例:

cy.visit('/'); // ウェブサイトにアクセス

// ボタンをクリックして非同期処理を実行
cy.get('button').click();

// 非同期処理が完了するまで 1 秒待機
cy.tick(1000);

// 結果を検証
cy.get('.result').should('contain', '処理完了');

「tick」の利点

「tick」を使用する利点は、以下のとおりです。

  • テストの実行時間を短縮できる
  • テストコードをわかりやすく記述できる
  • 非同期処理の完了を確実に待機できる

「tick」を使用する際の注意点は以下のとおりです。

  • 必要以上に「tick」を使用しない
  • ループ内で「tick」を使用しない
  • 指定する時間は、実際の処理時間よりも長めに設定する


非同期処理の完了を待つ

cy.visit('/'); // ウェブサイトにアクセス

// ボタンをクリックして非同期処理を実行
cy.get('button').click();

// 非同期処理が完了するまで 1 秒待機
cy.tick(1000);

// 結果を検証
cy.get('.result').should('contain', '処理完了');

アニメーションの完了を待つ

cy.visit('/'); // ウェブサイトにアクセス

// アニメーションが開始される要素を取得
const element = cy.get('.animation');

// アニメーションが完了するまで待機
cy.tick(1000);

// アニメーションが完了したことを検証
element.should('have.css', 'opacity', '1');

Ajax リクエストの完了を待つ

cy.visit('/'); // ウェブサイトにアクセス

// Ajax リクエストを実行するボタンをクリック
cy.get('button').click();

// Ajax リクエストが完了するまで 1 秒待機
cy.tick(1000);

// レスポンスを検証
cy.get('@response').then(response => {
  expect(response.status).to.equal(200);
  expect(response.body).to.deep.equal({ message: 'success' });
});
cy.visit('/'); // ウェブサイトにアクセス

// カスタムイベントを発生させるボタンをクリック
cy.get('button').click();

// カスタムイベントが発生するまで 1 秒待機
cy.tick(1000);

// カスタムイベントが受信されたことを検証
cy.on('customEvent', (data) => {
  expect(data).to.equal('Hello, world!');
});


cy.wait()コマンド

cy.wait()コマンドは、特定の条件が満たされるまで待機する機能です。「tick」と同様に、非同期処理の完了を待つために使用できますが、「tick」よりも柔軟性と制御性に優れています。

例:

cy.visit('/'); // ウェブサイトにアクセス

// ボタンをクリックして非同期処理を実行
cy.get('button').click();

// 非同期処理が完了するまで待機
cy.wait(() => {
  return cy.get('.result').contains('処理完了');
});

// 結果を検証
cy.get('.result').should('contain', '処理完了');

「tick」との比較

  • cy.wait()は、待機中に発生するイベントを処理するため、「tick」よりも制御性に優れています。
  • cy.wait()は、特定の条件が満たされるまで待機するため、「tick」よりも柔軟性に優れています。

カスタムイベントの利用

カスタムイベントを使用して、非同期処理の完了を通知することができます。テストコード側でカスタムイベントを待ち受け、処理完了を確認してから検証を実行することができます。

例:

// app code loaded by index.html
window.addEventListener('customEvent', () => {
  document.getElementById('.result').textContent = '処理完了';
});

cy.visit('/'); // ウェブサイトにアクセス

// ボタンをクリックして非同期処理を実行
cy.get('button').click();

// カスタムイベントが発生するまで待機
cy.on('customEvent', () => {
  // 結果を検証
  cy.get('.result').should('contain', '処理完了');
});

「tick」との比較

  • カスタムイベントは、処理完了後の処理を柔軟に記述することができます。
  • カスタムイベントは、非同期処理の完了を明示的に通知するため、「tick」よりもコードがわかりやすくなります。

Promiseを使用して、非同期処理の完了を待機することができます。テストコード側でPromiseをチェーンして、処理完了後に検証を実行することができます。

例:

// app code loaded by index.html
function fetchData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ message: 'success' });
    }, 1000);
  });
}

cy.visit('/'); // ウェブサイトにアクセス

// 非同期処理を実行
fetchData().then(data => {
  // 結果を検証
  cy.get('.result').should('contain', data.message);
});

「tick」との比較

  • Promiseは、処理完了後の処理を非同期的に実行することができます。
  • Promiseは、非同期処理をより自然な形で記述することができます。

上記以外にも、非同期処理をテストする方法はいくつか存在します。具体的な状況に応じて、適切な方法を選択してください。

  • サードパーティ製のライブラリを使用する
  • cy.clock()コマンドと組み合わせる