E2Eテストを導入して自分を救う (TestCafe編)

こんにちは、自意識過剰な正義のヒーローでお馴染みの株式会社SCOUTERの石岡 将明( @masaakikunsan )です。

先月のブログで、フロントにおける unit test についてブログを書いている人がいたので、今回は E2E テストについて書いていこうかなと思います。

E2E テストとは

E2E (End to End)テストとは Web ブラウザを通して一通りの処理をテストすることです。

今回のデモで作成するものを例として挙げます。

  1. ユーザー登録画面を表示
  2. 名前を入力
  3. bioを入力
  4. 送信ボタンをクリック
  5. ユーザー一覧ページに遷移
  6. ユーザー一覧に追加したユーザーが追加されている

なぜ E2E テストが必要なのか

みなさんはリリース前にテストをして最終確認をすると思います。 その際に全ページの UI の確認と挙動が想定どおりになるかどうかのテストを毎回していたらかなり時間の無駄です。

そこで、 E2E テストをすることで手を動かさずに全ページの UI と挙動のテストをすることができ、時間もコストもかなり下がり生産性があがるでしょう。

また、このような経験はありませんか?

実装した箇所以外のテストが漏れていてリリースしたらバグがあった。みたいな E2E テストを実行すれば基本的にこれは防げます。

全画面のテストを自動でやることで、影響範囲の漏れもなくなり品質担保にも繋がります。

つまり、 E2E テストはコストを下げる為だけでなく自分を救うことにも繋がります。

Nuxt.js に E2E テストを導入しよう

json-server を追加する

今回はテストに使う mock サーバーとして json-server を利用します。

さっそく導入していきます。

$ yarn add -D json-server

次に json を追加していきます。

db/db.json を追加して以下を記載します。

{
  "user": [
    {
      "id": 1,
      "name": "masaakikunsan",
      "bio": "自意識過剰な正義のヒーロー"
    }
  ]
}

最後に json-server を実行するために package.json に scripts を追加しましょう。

"server": "json-server --watch db/db.json --port 4000"

これで、 $ yarn server を実行し、 localhost:4000/user にアクセスすると db.json に記載したデータが表示されるでしょう。

f:id:masaakikunsan:20190416172936p:plain

次に、ユーザー一覧ページとユーザー作成ページを作っていきます。

ユーザー一覧とユーザー作成ページ

下記のようなページを作成しました。

f:id:masaakikunsan:20190416185539p:plain

f:id:masaakikunsan:20190416185657p:plain

コードはURLを載せて置くのでみてください。 github.com

TestCafe の導入

E2E テストですと、Puppeteer がかなり主流になってきていますが今回は TestCafe を使います。 理由としては、ブラウザを指定することでそのブラウザでのテストが可能だからです。

あと Puppeteer よりドキュメントが読みやすくて個人的に好きというのもありますw

まぁ他にも理由はあるので自分で調べてみてください。

devexpress.github.io

それではさっそく導入していきましょう。

$ yarn add -D testcafe

次に TestCafe を実行するために package.json に scripts を追加しましょう。

"e2e": "testcafe chrome test/e2e/*.js --speed 0.5"

speed を指定することで E2E の実行スピードを指定できます。

それでは、テストコードを書いていきましょう。

test/e2e/test.js を作成し下記コードを記載していきます。

import { Selector } from 'testcafe'

fixture('ユーザー追加').page('http://localhost:3000/create')

const customDataAttribute = name => `[data-test='${name}']`

test('必要項目を入力後、送信して遷移先を確認', async t => {
  const userName = await Selector(customDataAttribute('name'))
  const userBio = await Selector(customDataAttribute('bio'))
  const submitButton = await Selector(customDataAttribute('submit-button'))

  await t
    .setNativeDialogHandler(() => true)
    .typeText(userName, 'test')
    .typeText(userBio, 'bioだよ〜')
    .click(submitButton)

  const tableUserName = await Selector(customDataAttribute('user-name')).nth(-1)
    .innerText

  await t.expect(tableUserName).eql('test')
})

Selector は、テスト内の要素を識別するものです。 ここでは、data属性を定義しそれを元に要素を識別しテストを実装していきます。

それでは実行していきましょう。

テストで正しく挙動していることが確認できました。

scripts の testcafe の横の chromesafari にすれば safari が起動しますし、 firefox にしたら firefox が起動します。 これでブラウザテストの時間もかなり削減できます。

まとめ

E2E テストでの実装例を紹介していきました。いかがだったでしょうか?

E2E を実際のプロダクトにいきなり導入するのはコスト的にも難しいでしょう。 ただ、E2Eテストを絶対にバグっててはいけないところだけ導入するだけでもかなりテストの工数も下がり良いでしょう。

ずっと、言っていますが自分を助けることになります。

ちなみに、僕はフリーランスのときに実装した箇所がクレカ決済の箇所に影響が及んでいてクレカ決済が死ぬっていうバグを起こして以来テストはまじ大事自分を助けるって気持ちになっています。

現在、back check チームでは、エンジニアの募集をしております。 僕と一緒にフロントエンドを朝まで語り尽くしたいフロントエンドエンジニアやレベルの高いフロントエンドチームと最高のプロダクトを作って行きたいサーバーサイドエンジニアは是非ご応募お願いいたいします!

www.wantedly.com

www.wantedly.com