TECHNICAL BLOG

2021/6/22 # TypeScript # 便利 # やってみた # Node.js 2021/6 WebdriverIOを使ったE2Eテスト

少し前にE2Eテスト検討で、WebdriverIOを利用してみました。そこでESEテスト、E2Eテストフレームワーク、そしてWebdriverIOについて紹介します。

E2Eテストとは

E2EテストとはEnd to Endテストの略で、システム全体を通したテストです。
Webシステムの場合は、ブラウザで色々操作し正常に動作するのか?表示するのか?というテストとなります。

テスト

E2Eテストフレームワーク

ブラウザを操作するテストといえば、実際に試験者がポチポチ操作して検証することをイメージされると思います。

しかし、世の中には自動的にブラウザ操作してテスト実施出来るツールがあり、以下のワークフローでツール(テストフレームワーク)を活用し自動化することができます。

  1. テストケースを考える
  2. テストコードを書く
  3. コードを実行しテスト実施
  4. テスト結果を確認

調べると色々なテストフレームワークがあり混乱しましたが、大別すると

  • GUIのあるデスクトップPCで使いたい
  • GUIのないサーバなどで完全自動化して使いたい

この2つに用途により選ぶフレームワークが分かれてくるようです。

Selenium

E2Eテストフレームワークとして古くからあり一番有名で、名前を聞いたことがある人も多いのではないでしょうか。
テストコードは、Java, Python, C#, Ruby, JavaScript, Kotlinと豊富な言語で記述することができるようです。
Selenium公式はこちら

Puppeteer

Seleniumはブラウザを自動操作できるツールからスタートしたのに対し、こちらはテストツールとしてスタートしました。
そのため、テストコード記述量が少なかったり、画面キャプチャ取得など便利さが目立つようです。
Puppeteer公式はこちら

WebdriverIO

色々なフレームワークがある中から、今回WebdriverIOを利用しました。
理由は2つあります。

TypeScriptサポート

WebdriverIOはTypeScriptでのテストコード記述がサポートされています。
E2EテストではUIの変更の影響を受けテストコードを度々修正することが予想されるので、
型があることは思い切った修正やタイポミスなどによる手戻りを減らし、効率的であると考えました。

環境構築が楽

WebdriverIOはNode.jsプロジェクトなので、WebdriverIOやTypeScript、いくつかのライブラリをnpm installしていくだけで環境構築することができます。

テストコード例

それではWebdriverIOを使った例を紹介します。

// test/pageobjects/top.page.ts

// トップページ
class TopPage {

    open () {
        return browser.url(https://www.cview.co.jp/osakatech/);
    }

    // セレクタ
    get logo () { return $('.cs-logo') }
    get latest () { return $('.cs-top-new a') }

    // 最新記事遷移
    clickLatest () {
        this.latest.click();
    }
}

export default new TopPage();

画面ごとのクラスを用意し、以下のように画面クラスを活用してテストシナリオコードを書きます。

// test/specs/example.e2e.ts

import TopPage from  '../pageobjects/top.page';
import LatestPage from  '../pageobjects/latest.page';

describe('トップページ', () => {

    it('タイトルロゴ確認', () => {
        TopPage.open();
        expect(TopPage.logo).toBeExisting();
        expect(TopPage.logo).toHaveText(
            'OSAKA ENGINEER BLOG');
    });

    it('最新記事確認', () => {
        TopPage.open();
        TopPage.clickLatest();
        expect(LatestPage.title).toBeExisting();
        expect(LatestPage.title).toHaveText(
            '2021/1 for文を使うその前に');
    });
});

そして、テストを実行すると実際にブラウザが起動され、テスト通りにページ遷移等されていきます。
全てのテストが終了するとコンソールには、以下のように出力され結果が確認できます。

[0-0] PASSED in chrome - /test/specs/example.e2e.ts
2021-02-14T07:43:19.139Z INFO @wdio/cli:launcher: Run onComplete hook

 "spec" Reporter:
------------------------------------------------------------------
[chrome 88.0.4324.150 mac os x #0-0] Spec: /work/webtest/test/specs/example.e2e.ts
[chrome 88.0.4324.150 mac os x #0-0] Running: chrome (v88.0.4324.150) on mac os x
[chrome 88.0.4324.150 mac os x #0-0] Session ID: d8a163cdae0985e52a581d81f47794c1
[chrome 88.0.4324.150 mac os x #0-0]
[chrome 88.0.4324.150 mac os x #0-0] トップページ
[chrome 88.0.4324.150 mac os x #0-0]    ? タイトルロゴ確認
[chrome 88.0.4324.150 mac os x #0-0]    ? 最新記事確認
[chrome 88.0.4324.150 mac os x #0-0]
[chrome 88.0.4324.150 mac os x #0-0] 2 passing (1s)

Spec Files:      1 passed, 1 total (100% completed) in 00:00:02 

WebdriverIO公式はこちら

終わりに

WebdriverIOはjQueryライクに要素を取得し、テストケースをわかりやすく完結に記述できることが実感いただけたと思います。

E2Eテストで、全ケースを網羅しようとすると膨大になるので難しいかもしれませんが、基本的なケースや重要な部分だけでも実施すると、横断的な変更やフレームワークバージョンアップした時にとても安心できると思います。