yoshitake_1201’s diary

テストのこととか、ペンギンのこととか書きます。

ブラウザ自動化ツールのインストールとサンプル実行6選

この記事は「ソフトウェアテスト Advent Calendar 2018」の 20日目記事です。

qiita.com

昨日19日目は@e5rijunさんのISTQB 翻訳辞書を作ったでした。

e5rijun.hatenablog.com

ISTQBの翻訳辞書便利ですね!
そして整理したスプレッドシートまで共有してくださるとは…さすがrijunさん。感謝です。
せっかくなのでスプレッドシートのデータを活用できたらと思ってます。

この記事の内容

さてこの記事は、6つのブラウザ自動化ツールについて、セットアップ & サンプルの実行を紹介するものになります。
これをやろうと思ったきっかけは、 今月12/8(土)に参加した、システムテスト自動化カンファレンス2018の中で@Hnzさんのブラウザ自動化ツール カオスマップ風というLTを見たからです。

speakerdeck.com

この発表ではブラウザ自動化ツールがなんと16個も紹介されていました。
私はこの中の3つぐらいしか知らなかったので「こ、こんなにあるんだ!」とただただ驚いたんですが…まぁ、驚くだけではもったいないですよね。
ということで、とりあえず全部試してまとめるか…という経緯です。
本当はAdvent Calendarまでに全部やりきるつもりだったんですが、まぁ間に合わず(笑)とりあえず6個になりました…年末年始にがんばれたら良いなぁ…

なので、この記事では↑の発表で紹介された16個のツールのうち、JavaScript Injection系のツール3つとDevtool-protocol系のツール3つの合計6このツールの紹介になります。

※ とりあえず動かしてみたい人向けです。詳しく知りたい方は公式ページを参考ください。
※ サンプルコードは、公式ページで紹介されているものを引用しました。

紹介するツール一覧

※ クリックすると書くツールの公式ページが開きます。
※ 「JavaScript Injection」、「devtool-protocol」といった分類名は発表資料のものを引用させていただきました。

諸注意

紹介するすべてのツールに、node.jsnpmを使います。
インストールしていない場合はこちらの記事を参考ください。

1. Nightmare

f:id:yoshitake_1201:20181220192356p:plain

セットアップ & サンプル実行

※ 書いてある順番で実行していってください。
nightmare_testというディレクトリをプロジェクトフォルダにしています。
※ テストコードはnightmare_test/tests/の中にtest.jsとして保存しています。

$ mkdir nightmare_test
$ cd nightmare_test
$ npm init
$ npm install nightmare
$ mkdir tests
$ touch tests/test.js

test.jsの中身に以下をコピペし保存してください。

const Nightmare = require('nightmare')
const chai = require('chai')
const expect = chai.expect

describe('test duckduckgo search results', () => {
  it('should find the nightmare github link first', function(done) {
    this.timeout('10s')

    const nightmare = Nightmare()
    nightmare
      .goto('https://duckduckgo.com')
      .type('#search_form_input_homepage', 'github nightmare')
      .click('#search_button_homepage')
      .wait('#links .result__a')
      .evaluate(() => document.querySelector('#links .result__a').href)
      .end()
      .then(link => {
        expect(link).to.equal('https://github.com/segmentio/nightmare')
        done()
      })
  })
})

以下のコマンドをたたくと、テストが実行されます。

$ node tests/test.js

その他

mocha、chai、avaといったJavaScriptフレームワークと連携してテスト実行もできるらしいです。
詳しくはこちらの記事を参照ください。

2. Cypress

https://www.cypress.io/img/logo-dark.36f3e062.png

セットアップ & サンプル実行

※ 書いてある順番で実行していってください。
cypress_testというディレクトリをプロジェクトフォルダにしています。
※ テストコードはcypress_test/cypress/integration/の中で管理する仕様です。
※ インストール直後はexamplesディレクトリが既にあり、その中にsampleコードが入っています。

$ mkdir cypress_test
$ cd cypress_test
$ npm init
$ npm install cypress
$ ./node_modules/.bin/cypress open

↑を実行すると、cypressテスト用のGUIが起動します。
GUIに表示されるファイルをクリックするとそのファイルのテストが実行される。
action.spec.jsが、入力フォームなどを操作しているサンプルになるのでわかりやすです。

その他

Seleniumを使ったことがある方はこちらのブログを読むと、イメージしやすいかと思います。
また、弊社Tech Blogでも少し紹介しました。

3. TestCafe

f:id:yoshitake_1201:20181220193720p:plain

セットアップ & サンプル実行

※ 書いてある順番で実行していってください。
testcafe_testというディレクトリをプロジェクトフォルダにしています。
※ テストコードはtestcafe_test/testsの中にtest.jsとして保存しています。

$ mkdir testcafe_test
$ npm install --save-dev testcafe
$ mkdir tests
$ touch tests/test.js

test.jsの中身に以下をコピペし保存してください。

import { Selector } from 'testcafe'; // first import testcafe selectors

fixture `Getting Started`// declare the fixture
    .page `https://devexpress.github.io/testcafe/example`;  // specify the start page


//then create a test and place your code there
test('My first test', async t => {
    await t
        .typeText('#developer-name', 'John Smith')
        .click('#submit-button')

        // Use the assertion to check if the actual header text is equal to the expected one
        .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!');
});

以下のコマンドをたたくと、テストが実行されます。

$ testcafe chrome tests/
# Safariで実行したいときは↓
$ testcafe safari tests/
# Firefoxで実行したいときは↓
$ testcafe firefox tests/

その他

アプリ版(有償)や、GUI + Recorder機能付きのIDE: TestCafe Studioなどもあるようです。
こちらの記事を参考にするとわかりやすいかと!

4. Puppeteer

f:id:yoshitake_1201:20181220193511p:plain

セットアップ & サンプル実行

※ 書いてある順番で実行していってください。
※ puppeteer_testというディレクトリをプロジェクトフォルダにしています。
※ テストコードはpuppeteer_test/tests/の中にexample.jsとして保存しています。

$ mkdir puppeteer_test
$ cd puppeteer_test
$ npm init
$ npm i puppeteer
$ mkdir test
$ touch test/example.js

example.jsの中身に以下をコピペし保存してください。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});

  await browser.close();
})();

以下のコマンドをたたくと、テストが実行されます。

$ node tests/example.js

※ 実行すると、同じディレクトリ内にexample.pngというファイルが保存されます。
ファイルを開くと、アクセスしたときのスクショを確認できます。

※ Defaultがヘッドレスモードで実行されるので見えるようにするには 4行目 const browser = await puppeteer.launch();を以下に変更するとOKです。

const browser = await puppeteer.launch({
  headless: false,
  slowMo: 100
} );

その他

Googleが提供しているツールですよね。いろいろできそうな気がします。
こちらの記事がわかりやすいですね。

5. Puppeteer for Firefox

セットアップ & サンプル実行

※ 書いてある順番で実行していってください。
puppeteer_firefox_testというディレクトリをプロジェクトフォルダにしています。
※ テストコードはpuppeteer_firefox_test/tests/の中にexample.jsとして保存しています。

$ mkdir puppeteer_test
$ cd puppeteer_test
$ npm init
$ npm i npm i puppeteer-firefox
$ mkdir test
$ touch test/example.js

example.jsの中身に以下をコピペし保存してください。

const pptrFirefox = require('puppeteer-firefox');
 
(async () => {
  const browser = await pptrFirefox.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});
  await browser.close();
})();

以下のコマンドをたたくと、テストが実行されます。

$ node tests/example.js

※ 実行すると、同じディレクトリ内にexample.pngというファイルが保存されます。
ファイルを開くと、アクセスしたときのスクショを確認できます。

※ Defaultがヘッドレスモードで実行されるので見えるようにするには 4行目 const browser = await pptrFirefox.launch();を以下に変更するとOKです。

const browser = await pptrFirefox.launch({
  headless: false,
  slowMo: 100
});

その他

システムテスト自動化カンファレンスの前日に公開されてんですよね。
まだ記事が少ないですが基本的にChrome版と同じっぽいです。

6. TAIKO

f:id:yoshitake_1201:20181220194150p:plain

セットアップ & サンプル実行

※ 書いてある順番で実行していってください。
taiko_testというディレクトリをプロジェクトフォルダにしています。
※ テストコードはtaiko_test/tests/の中にtest.jsとして保存しています。

# taikoをインストールする
$ npm install -g taiko
$ mkdir taiko_test
$ cd taiko_test
$ mkdir tests
$ toucht tests/test.js

test.jsの中身に以下をコピペし保存してください。

const { openBrowser, goto, write, click } = require('taiko');
(async () => {
    try {
        await openBrowser();
        await goto("google.com");
        await write("taiko test automation");
        await click("Google 検索");
    } catch (e) {
        console.error(e);
    } finally {
        await closeBrowser();
    }
})();

以下のコマンドをたたくと、テストが実行されます。

$ taiko tests/test.js

※ Defaultがヘッドレスモードで実行されるので見えるようにするには、実行時に以下のようにしてください。

$ taiko tests/test.js --observe

その他

ここでは端折りましたが、TAIKOはREPLにテストコードを書きそのコードを保存する というのを推しているようです。
公式ページを見るとそんな感じになってました。
また、公式ページのサンプルでは、英語環境のためか検索ボタンのクリックが"Google Search"になっていたので、 日本語環境の場合は↑のように"Google 検索"に書き換える必要があります。
ご注意ください。
ちなみに、Integrationを使いたい場合はGaugeと合わせて使うようです。

おわりに

この記事を書きながら、もちろん動かしていたんですが、それぞれのツールで似たようなところもあれば、ぜんぜん違うところもあって面白いですね。
私は今Cypressをメインで扱っていたのですが、なにやらTestCafeから良さそうな雰囲気を感じました。
いろいろ目的によって選べるようになるといいなぁと思います。

Advent Calendarももうすぐ終わりですね。なにか物悲しくなりますね(笑) 明日は @acha_821さんですね。楽しみです。
では、ここまで読んでいただきありがとうございました!