ログインをともなうE2Eテストのコツ

ここ数週間ログインをともなうE2Eテストを実装していたので、 そこで得られた学びをロギングしておく。

環境

Node.js v6.11.0
Nightmare v2.10.0
Mocha v3.4.0

コツ

  1. テストはリトライさせる
    E2Eテストは、ネットワークやディスクIOなど外部要因が絡んでくる。 ユニットテストと比較し、実行時間もかかるし、外部要因によってテストが失敗したりと、テスト結果が安定しない。そのため、テストに失敗したらリトライするような仕組みを用意する。mochaの場合はretryオプションがあるのでそれを使った。E2Eのためのオプションらしい。
    RETRY TESTS

    This feature is designed to handle end-to-end tests (functional tests/Selenium…) where resources cannot be easily mocked/stubbed.

  2. beforEachはリトライ対象にならない
    上記リトライオプションだが、mochaのbeforEachには適用されない。 参考issue
    beforeEachなどはあくまでsetup/teardownに使ってくれ。フックで安定しないロジック使ってるなら、それを関数化してくれ。ってことらしい。
    今回、ログインをともなうE2Eだったので、beforEachでログイン処理をしていたが、関数化して、ログイン処理をリトライに対応させた。
    最初、beforEachもリトライ対象になると思い込んでいて時間のロスをしてしまった。

  3. テストシナリオの各工程にはフィードバックを
    たとえば、「ログアウトできること」というテストシナリオの場合、ログイン>ログアウトという工程を経ることになる。ログインにはフォーム入力、ボタンクリックなど、ログアウトにはログアウトのボタンクリックなど、各工程にも作業がある。つまり、一つのテストシナリオは複数の工程から構成される。今回の案件の場合は10~20程度の工程があった。その各工程で、フィードバックがないとテストでコケたときに、原因特定に時間がかかってしまう。
    実際にあったのは、「ログアウトできること」というテストシナリオで、アサーションが「ログイン時に付与されるクッキーが削除されていること」だったのだが、自分の書いたテストは、ログインできていないのに、次の工程に進んでしまっていた。当然ログインしていないので、ログイン時に付与されるクッキーは無い。そのため、アサーションも通ってしまっていた。
    結局、別のテストが落ちることで、ログインできていないことが判明したが、テストが落ちる原因特定にかなり時間をロスしてしまった。(そして、そもそもログインできていない原因は、上記にあげた外部要因によるものだった。)

まとめ

ブラウザオートメーションはphantom.jsとかでやったことがあったし、ユニットテストも書いたことがあったが、E2Eテストは初めてだった。
感想としては、自動化はできるが、ユニットテストと違って時間もかかるので、安定させるのが難しく、テクニックを要するなぁという感じ。
しかし、E2Eテストで事前に検知できたバグもあるので、書いたかいがあった。手動で検証するよりは、繰り返し実行できるし、時間もかからないので書く価値は有ると思う。ただ、安定稼働にコストも割くので、テストを書くのはコアな機能に限定するなど、見極めが必要だとも感じた。