ランサーズ等のサービスを開発・運用する中で得た知識やノウハウを紹介しています。

Labels:  JavaScript 投稿者:yokoi

TestCafeでのE2EテストをBrowserStackでやろう

ランサーズCTOの横井です。

最近、個人でE2Eの画面テストを書く際にSeleniumからTestCafeに乗り換えつつあります。導入が(個人的には)Seleniumより楽っていうのと、要素の出現とかをよしなに待ってくれるので、テスト書くときにあんまりその辺を意識しないで書けるっていうのが良い感じです(まだでかいプロジェクトでがっつり使い込んでいないので、落とし穴にはまっていないだけかもしれません)。

とりあえず

$ npm install -g testcafe

やるだけでサクッと始められますが、今回はより色々な環境でのテストを行いたいので、BrowserStackと連携させてみます。

準備

まずは今回のテスト用の画面を作ってしまいます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>samplepage</title>
    <link rel="stylesheet" href="">
</head>
<body>
    <h1>hello world</h1>
    <script>
    !function() {
        if ( typeof history.pushState !== "function" ) {
            throw Error("under IE9!!");
        }
    }();
    </script>
    
</body>
</html>

だけのシンプルなindex.htmlを作ります。普通のプロジェクトであればローカルにサーバがいたりするかと思いますが、今回はサンプルなので、適当にテストコードの最初らへんで立てちゃいます。その上でテストを書いたのがこちら。

const nodeStatic = require('node-static');
const fileServer = new nodeStatic.Server('./public');

// サンプル用にサーバを立てる
const __server = require('http').createServer( (req,res)=>{
    req.addListener('end', ()=>{ fileServer.serve(req, res); }).resume();
} ).listen(3000);

fixture('Sample Test')
    .page('http://localhost:3000/')
    .after( async (ctx) => {
        __server.close();
    });

test('Assert page title', async (t) => {
    const title = await t.eval( () => window.document.querySelector('title').text );
    await t.expect( 'samplepage' ).eql( title );
});

この時点でもコマンドラインから

$ testcafe chrome tests/sample.test.js

で、Chrome上でのテストが動かせます。

BrowserStackを使用する

まずは、BrowserStackに登録したのち、ログイン後画面から「Account->Settings->Automate」のところにUsernameとAccessKeyが書いてあるのでコピっておきましょう。

次に、TestCafeから使えるようにtestcafe-browser-provider-browserstackを入れておきます。あとは環境変数に「BROWSERSTACK_USERNAME」と「BROWSERSTACK_ACCESS_KEY」をセットして

$ testcafe "browserstack:Chrome@53.0:Windows 10" tests/sample.test.js

上記を動かすと、BrowserStack上で指定したテストが動き、結果をコマンドライン上で確認できます。あとは、BrowserStackで指定できる組み合わせで色々指定すればOKというわけです。

もうちょいプロジェクトっぽくする

このままだと、環境変数毎回設定したり、どのブラウザでテストしているかの見通しが悪いのでプロジェクト化します。
まずはpackage.json

{
  "name": "sample_test",
  "description": "E2E test using testcafe",
  "scripts": {
    "test": "node runner.js"
  },
  "dependencies": {
    "dotenv": "^4.0.0",
    "node-static": "^0.7.9",
    "testcafe": "^0.15.0",
    "testcafe-browser-provider-browserstack": "^1.1.1"
  }
}

環境変数は.envファイルに逃がします。あとはブラウザの指定をコードで管理したいのでTestRunnerのキックをコードで行います。

require('dotenv').config();
const createTestCafe = require('testcafe');
let testcafe         = null;

createTestCafe('localhost', 1337, 1338)
    .then(tc => {
        testcafe     = tc;
        const runner = testcafe.createRunner();

        return runner
            .src('tests/sample.test.js')
            .browsers([ 'browserstack:Edge@15.0:Windows 10', 'browserstack:IE@10:Windows 8' ])
            .run();
    })
    .then(failedCount => {
        console.log('Tests failed: ' + failedCount);
        testcafe.close();
    })
    .catch(err => {
        console.log("err", err);
        testcafe.close();
    });

これをrunner.jsとして、npm test時にキックするようにすればOKです。あとは、browsersの引数の配列を増やしていくだけで、一個のテストを一気に色々な環境で動かすことができます。

実際に意味のありそうなことをやってみよう

冒頭のindex.htmlのscriptタグの中のコードはIE9以下であればErrorとなるはずです。なので、ブラウザーの指定で

.browsers([ 'browserstack:Edge@15.0:Windows 10', 'browserstack:IE@9:Windows 7' ])

IE9を指定してテストを実行してみます。

すると

Running tests in:
 - Edge 15.15063.0 / Windows 10 0.0.0
 - IE 9.0.0 / Windows 7 0.0.0

 Sample Test
 ✖ Assert page title

   1) Error on page "http://localhost:3000/":

      under IE9!!

      Browser: IE 9.0.0 / Windows 7 0.0.0



 1/1 failed (2s)

しっかり検知できました! IE9を外してあげるとテストはパスします。

まとめ

いい感じですね。

ランサーズではサービスを成長させてくれるエンジニア、デザイナーを募集しています!
ご興味がある方は、以下URLよりご応募ください。

PHPエンジニア
Rubyエンジニア
フロントエンドエンジニア
インフラエンジニア
新卒エンジニア
その他採用情報

関連記事

thumbnail
手軽に美しく実装!ファイルアップロード用JavaScriptライブラリ4選

ランサーズでは、現在、Webエンジニアを募集しています。 詳しくは、募集要項をご覧下さい。 こんにちは、keiです。 今回は、ブラウザからのファイルアップロードを実装する際に、お勧めなJavaScriptライブラリを4つご紹介致します。 ランサーズ上で、大容量 …

thumbnail
mocha のテスト実行前にグローバル変数をセットする方法

森です。 mocha のテスト実行前にグローバル変数をセットする方法を調べました。 コマンド引数か mocha.opts で、設定ファイルを require することで、うまくゆきました。以下の例では、–require ./test/setup.j …

ES6 + React.js + Redux で作るチャットシステム

アプリケーションエンジニアのyutakaです。 先日ランサーズのメッセージ機能をリニューアルしました。 ランサーズのメッセージ機能はリアルタイムのチャット形式で他のユーザーさんとコミュニケーションがとれる機能となっています。 リニューアルに伴って、フロントエン …