Cypressでテストを自動化する!e2eツールの比較とテストの書き方。

Cypressでテストを自動化する!e2eツールの比較とテストの書き方。

この記事では、e2eテストの特徴や目的について説明したうえで、Cypressを例にe2eテストの実装例を紹介したい。

Cypressは使い方が直感的で覚えやすい、またe2eテスト以外の目的にも転用できそうなおもしろい技術なので、ぜひ一度試してみてほしい。

この記事はAngularアプリをターゲットとしてe2eテストをおこなうパターンを想定しているが、React・Vue.jsなどでも同じような手順でCypressをプロジェクトに取り込むことができる。

e2eテストとは?

e2eテストはソフトウェア開発におけるテスト手法のひとつで、リアリスティックなシナリオに基づいて一連の画面操作をテストする。

「e2e」はEnd-to-Endの略であり、「最初から最後まで」といったニュアンスで考えると分かりやすいだろう。

e2eテストのテスト項目としては以下のようなものが考えられる。

(例)入力項目にユーザ名・メールアドレスを入力して送信ボタンをクリックして、新規のユーザアカウントが作成されたか検証する。

以前はこういったシナリオのテストは自動化するのが困難であったが、技術の進歩により多くの部分はフレームワークを用いて自動化できるようになっている。

単体テスト・結合テストとの違い

e2eテストと単体テスト・結合テストの違いについて説明しておこう。

ソフトウェア開発においてはおもに以下の3つのテストが用いられる。

  • 単体テスト(ユニットテスト)
    単体テストは個別のコンポーネントといった小さな単位のパーツを対象とした機能テスト。
    単体テストについて詳しく知りたい人はこちらの記事を参考にしてほしい。
  • 結合テスト(インテグレーションテスト)
    複数のコンポーネントが組み合わさった状態で機能するかどうか検証するためのテスト。
  • e2eテスト
    フロントエンド・バックエンドや含めたシステム全体でおこなうテスト。
    できるだけユーザが使用するのに近い環境でおこなうのが望ましいとされている。
    単体テスト・結合テストとは異なり、e2eテストは品質保証のためのチームにより実行・管理されることが多い。

なお、e2eテストと結合テストは企業によっては同じ意味で用いることもある。

e2eテストのJSフレームワーク

JavaScriptには多くのe2eフレームワークが存在する。

知名度の高いフレームワークを挙げるとすると以下のようになる。

  • WebdriverJS
  • Protractor
  • WebdriverIO
  • NightwatchJS
  • Cypress
  • Cucumber
  • TestCafe
  • Jest

これらのフレームワークの多くは「Selenium」というインターネットブラウザの操作を自動化するためのソフトをべ-スに作られている。

Cypressについて

Cypress公式サイト:: https://www.cypress.io

Cypressはe2eテストのためのJavaScriptフレームワーク。

ユーザの画面操作を模倣するかたちでテストを記述することができるので、より本番に近いかたちのテストを自動でおこなうことができる。

Cypressで書かれたテストはCI(継続型インテグレーション)ツールに取り込み、変更がマージされるたびに自動で実行するように設定できる。

なお、AngularにはProtractorという標準のe2eテストフレームワークが備わっているが、この記事では知名度が高く、使用している企業も多い「Cypress」を取り上げることにした。

Cypressの長所をまとめると以下のようになる。

  • 知名度が抜き出ており導入している企業も多い
  • コマンド(テストの指示内容)が直感的で分かりやすい
  • インターネット上の情報が多い

e2eテストの書き方

AngularプロジェクトにCypressをインストールして簡単なテストシナリオを作成してみよう。

Angularアプリを用意する

まずはe2eテストの対象となるアプリを用意しよう。

アプリは入力フォームなどの要素が含まれていれば、どういった内容のアプリでも構わない。

この記事では簡単なフォーム入力画面のみを持つアプリを用意した。

Cypressをインストールする

プロジェクトにCypressをインストールするために以下のコマンドを実行する。

npx ng add @briebug/cypress-schematic

Angularのプロジェクトの場合、Protractor(Angular標準のe2eフレームワーク)を削除するかどうか尋ねられる。

特に残しておく必要が無ければ削除してしまって問題ないだろう。

コマンドが正常に実行されたら、プロジェクト内に「cypress」フォルダとcypress.jsonファイルが作られているはずなので確認しよう。

また、「angular.json」「package.json」「package-lock.json」が更新されているはずだ。

Cypressを起動する

Cypressを起動する方法はいくつかあるがここではCypressのコンソールを使用したい。

アプリをスタートした状態で以下のコマンドを実行する。

cypress open

問題が無ければ以下のようなコンソールが新しいウィンドウにて表示されるはずだ。

*エラーが発生する場合は、cypress.jsonファイルの「basuUrl」プロパティに正しいURLが設定されているか確認してほしい。

このコンソールから「Run 1 integration spec」をクリックするとテストを実行できるが、まずはテストの内容を記述しよう。

テスト項目を作成する

ではテスト項目を作成していこう。

テストは「cypress > integration」フォルダにあるspec.tsに記述する。

以下のようにテストを書いてみよう。

describe('TryCypressApp', () => {
  it('loads page.', () => {
    cy.visit('/');
  });
})

describe構文にテストのタイトルを記述し、テスト項目はit構文内に記述する。

cy.vist(‘/’)はcypressのコマンドであり、デフォルトURLが開くかどうかのテストとなる。

テストを記述したらCypressコンソールから「Running integration tests」をクリックして、テストをスタートしよう。

ブラウザーが自動で開きテストが開始されるはずだ。

Cypressのコマンド

ではCypressのコマンドを少し勉強しよう。

コマンドとはテストをおこなうためのメソッド群であり、「入力欄にフォーカスを合わせる」「文字を入力する」といったユーザアクションを模倣できる。Cypressではこういったコマンドを組み合わせてテストを書く。

コマンド指示の内容
visitURLを開く
contains画面内に文字列が含まれているか検証する
getHTMLの要素を得る
type文字列を入力する
click要素をクリックする
wait指定した時間だけ処理をストップする
scrollTo指定した要素までスクロールする
おもなCypressコマンド

その他のコマンドを確認したい人はCypressのドキュメントを読んでほしい。

Cypressドキュメント:: https://docs.cypress.io/api

HTML要素を指定する

テストをするうえでは画面内の特定のHTML要素が簡単に識別できるようにする必要がある。

その際は要素にdataプロパティを付け加えるのがわかりやすい。

htmlファイルを開き指定したい要素に「data-e2e=”name-input”」といった具合にデータを記述しよう。

テストファイルでは、getコマンドを使用して指定した要素を得ることができる。

cy.get('[data-e2e="name-input"]')

各入力欄やボタンにdataプロパティを加え、簡単なテストを作成しよう。

describe('TryCypressApp', () => {
  it('loads page and check title.', () => {
    cy.visit('/');
    cy.contains('Login form page');
  });

  it('Input name and email and submit form.', () => {

    cy.get('[data-e2e="name-input"]').type('taro');

    cy.wait(1000);

    cy.get('[data-e2e="mail-input"]').type('a@b.jp');

    cy.wait(1000);

    cy.get('[data-e2e="submit-button"]').click();
  });
})

再度テストを実行する。

Cypressがユーザの画面操作を模倣しているのが確認できるはずだ。