6
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

TestCafe×BrowserStackで行うマルチブラウザ対応のE2Eテスト

STORES.jp Advent Calendar 2019 - Adventar 19日目の記事です!
昨日は @upinetree さんによるコードの計測・可視化を、まずは手頃な道具(GAS+データポータル)ではじめてみるでした!

今回はTestCafeとBrowserStackを使ったマルチブラウザ対応のE2Eテストについて簡単に紹介します。

フロントエンドでは辛みの一つとして複数ブラウザにおける動作確認があります。
Chrome、Safari、Firefox、Edge、IEと様々なブラウザが存在し、OSはPCでMacOSやWindows、SPではiOS、Androidと様々あり手動テストでの動作確認には何時間と潰してしまう事もよくあるかと思います。
上記構成でこれらを解決しようという内容です。

なおサンプルコードもGitHubに公開していますので手元で確認したい場合はcloneして触ってみてください。
(Nuxt.js環境で構築しています)

GitHub - Kosuke0820/TestCafe-BrowserStack-E2E-Testing-on-Nuxt

TestCafeについて

image.png

TestCafeはOSSのE2Eテストフレームワークです。
E2Eテストフレームワークではその他に SeleniumNightwatch などがありますがTestCafeの特徴として

  • WebDriverのインストールなどの初期設定が不要で、導入がとても簡単
  • マルチブラウザテストが可能
  • テストの開始前および各アクションの後に、ページの読み込みとXHRを自動的に待機してくれる為、wait処理周りでの意図しないエラーになりづらい
  • async/awaitが使えるES2017やTypeScriptにも対応
  • Page ModelというSelectorの情報を再利用できるテストパターンを持つ

などがあります。

BrowserStackについて

image.png

BrowserStackは様々なデバイス、ブラウザでのテスト環境をWeb上で提供してくれるサービスです。

主な機能として

  • Live - 下記画像のように各デバイス、OS、ブラウザを起動できる仮想環境の提供。その組み合わせは2000以上!
  • Automate - Liveで提供している全ての環境下で自動テストを実行できる。並列テスト実行も可能

があります。

今回はE2Eテストの実行環境としてAutomateを使っていきます。

image.png

料金体系は以下の通りでAutomateが使用できるプランだと月129ドルで安くはありません。
なお新規の登録をするとLive30分、Automate90分のフリートライアルがついています。

image.png

今回のページサンプル

それでは本題に入っていきます。
今回はログインページを想定した題材に進めていきたいと思います。
画面は2画面で大きく ログインページマイページの2ページ構成です。
マイページはログイン状況に応じて表示が分岐されます。

ログインページ マイページ(ログイン前) マイページ(ログイン後)
image.png image.png image.png

TestCafeのみでローカルテスト

まずはBrowserStackは使わずTestCafeでローカルテストをするところまで進めます。
TestCafeにはCLIでトリガーする方法と、Runnerクラスを使う方法がありますが、今回はCLIでの実行で進めていきます。

簡易サーバーの準備

今回は簡易サーバーとして typicode/json-server を使用していきます

yarn add -D json-server

そして仮想DBとして db/db.json を作成しユーザーデータを登録します。

db/db.json
{
  "user": [
    {
      "name": "testuser",
      "password": "password"
    }
  ]
}

package.json のscriptsに以下を追記します

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

yarn server で立ち上げて準備完了です。

ログインページ

dbに保存されているデータとinputに入力したユーザーネームとパスワードが合致すればログインという設定でロジックを組みます。
※本来こんなログインロジックはあり得ませんがサンプルの為、ご容赦ください🙏

他ページのコードはリポジトリを参照してください

pages/login.vue
<template>
  <div class="login-wrapper">
    <h1>Login</h1>
    <hr class="line" />
    <p v-if="isError" class="error-message">
      ユーザーネームもしくはパスワードが誤っています
    </p>
    <label>
      UserName:
      <input v-model="name" type="text" class="name" />
    </label>
    <label>
      Password:
      <input v-model="password" type="password" class="password" />
    </label>
    <button @click="login">Login</button>
  </div>
</template>

<script>
export default {
  data: () => ({
    name: '',
    password: '',
    isError: false
  }),
  methods: {
    async login() {
      const users = await this.$axios.$get('http://localhost:8000/user')
      const isCorrect = users.some(
        (user) => user.name === this.name && user.password === this.password
      )
      if (isCorrect) {
        this.$store.commit('SET_USER', this.name)
        this.$router.push('/')
      } else {
        this.name = ''
        this.password = ''
        this.isError = true
      }
    }
  }
}
</script>

テストの作成

TestCafeをインストールします。

yarn add -D testcafe

続いてpackage.jsonのscriptsに追記します。

chromeと記載がある部分に safarifirefox などブラウザ名を指定します。
指定したブラウザはPC内にインストールされている必要があります。

対応ブラウザ一覧 - Locally Installed Browsers

--speedオプションはテストの実行スピードを指定できます。
今回は動きがわかるよう、少し遅めの0.8に設定しています。

オプションは他にも
テストが失敗するたびにスクリーンショットを撮影してくれる takeonfails
テスト実行のビデオを記録してくれる video
など便利なオプションが揃っています。

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

ログイン部分のテストを書いていきます。

API部分はRequestMockでmock化しておきます。
Selectordocument.querySelector() と同様にelementを指定することができます。
inputの入力 → Mypageに遷移 → ユーザーネーム表示の流れでテストしていますが、コードを見るだけでも直感的でわかりやすいかと思います。

test/e2e/login.js
import { Selector, RequestMock } from 'testcafe'

const resData = [
  {
    name: 'test',
    password: '1234'
  }
]

const mock = RequestMock()
  .onRequestTo('http://localhost:8000/user')
  .respond(resData, 200, { 'Access-Control-Allow-Origin': '*' })

fixture('ログイン')
  .page('http://localhost:3000/login')
  .requestHooks(mock)

test('正しいログイン情報を入力後、mypageにuserNameが表示されること', async (t) => {
  const nameInput = await Selector('.name')
  const passwordInput = await Selector('.password')
  const loginButton = await Selector('button')

  await t
    .typeText(nameInput, 'test')
    .typeText(passwordInput, '1234')
    .click(loginButton)

  // --- Mypageへ遷移 ---

  const loginUserName = await Selector('.user-name').textContent

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

テストを実行

yarn test:e2e を実行するとブラウザが立ち上がり、自動テストが実行されていきます。

Image from Gyazo

BrowserStackを導入

ここまではいい感じですね。
しかしTestCafeだけでは、自PCにインストールされているブラウザでないと使えません。
MacではIEのインストールはできない為IEのテストができません。
そこで登場するのがBrowserStack Automateです。

testcafe-browser-provider-browserstackのインストール

TestCafeが公式で提供しているtestcafe-browser-provider-browserstackをインストールします

yarn add -D testcafe-browser-provider-browserstack

環境変数の設定

環境変数に BROWSERSTACK_USERNAMEBROWSERSTACK_ACCESS_KEY を設定する必要があります。
https://www.browserstack.com/ から登録後、https://www.browserstack.com/accounts/settings のAutomateから上記2つの情報が取得できます。

image.png

取得した値をbash_profilezshrcなど利用しているシェルに合わせて環境変数を設定します。

テストの実行

scriptsを以下のように修正します。
先程とは違い、テスト実行するブラウザのバージョンやOSを設定しています。

"test:e2e": "testcafe browserstack:ie@11.0:Windows 10 test/e2e/*.js --speed 0.8"

yarn test:e2e のコマンドを叩き、https://automate.browserstack.com/dashboard/v2 を見てみるとテストが実行されていることがわかります。

image.png

テスト終了後、ログから実行結果を動画で確認することが可能です。
Windows環境でIEのテストができました!🎉

Image from Gyazo

所感

ローカルで試すだけであれば比較的容易に環境構築は可能。

E2Eのデメリットではありますが、効果的に書かないとテストの実行時間が膨大になってしまいます。
コアな部分でのピンポイントの利用に抑えて、できるだけ単体テストやスナップショットテストなどで担保するのが良さそうだなぁといった所感です。

手動テストとはお別れできないと思っていますが、このようなE2Eで手動テストのコスト、不安感は減る為、上手に活用していきたいですね!

明日20日目は Charlie・Msfm さんによる「Podcastを運用するまで」です!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
6
Help us understand the problem. What are the problem?