CodeceptJS (+ Puppeteer) を触ってみた

#きっかけ
今までSelenium WebDriverでE2Eテストを書いてきました。
が、開発チームから「もっと楽に書こうよ」という話が出て調べてみたところ、CodeceptJSが良さそうなので触ってみた話。
CodeceptJS + WebDriverも出来るようですが、Puppeteerの方が手軽で実行速度も速いようなのでPuppeteerを選択。
ただクロスブラウザやBrowserStackでテストをしたいので将来的にはWebDriverに移行予定。けど今じゃない。

#CodeceptJSの何が良かったのか
* テストコードが自然言語っぽく書けて誰でも読みやすい
* 要素指定が簡単で分かりやすい（良い意味で雑に書ける）
* プラグインが充実してる
* WebDriverとかPuppeteerとか複数のヘルパーに対応してる

#インストール + 初期設定
```bash
$ npm init -y
$ npm install codeceptjs puppeteer --save-dev
$ npx codeceptjs init                                 # ここから対話形式
? Where are your tests located? (./*_test.js)　　　　  # 指定のファイル名を自動でテストファイルと認識してくれる
? What helpers do you want to use? (Use arrow keys)   # Puppeteerを選択
  WebDriver 
❯ Puppeteer 
  TestCafe 
  Protractor 
  Nightmare 
  Appium 
  Playwright
? Where should logs, screenshots, and reports to be stored? (./output)  # スクリーンショット等の出力先
? Do you want localization for tests? (See https://codecept.io/translation/) (Use arrow keys)  # 日本語を選択
  pl-PL 
  zh-CN 
  zh-TW 
❯ ja-JP 
  de-DE 
  English (no localization) 
  pt-BR 
(Move up and down to reveal more choices)
? [Puppeteer] Base url of site to be tested (http://localhost)  # ドメイン以降が同じ構成で、ドメインでテスト環境や本番環境を分けている場合はBase URLを指定すると便利
? [Puppeteer] Show browser window (Y/n)          # テスト時にブラウザを表示するかどうか
? [Puppeteer] Browser viewport size (1200x900)   # ブラウザサイズ
```

一旦ここで初期設定は終了です。初期設定が終わると必要なファイルやフォルダが作成されます。
`npx codeceptjs init`がうまく行かない場合があるようなので、その場合は代わりに`node node_modules/.bin/codeceptjs`を実行します。
作成されたファイルの中の`codecept.conf.js`に上記で設定した内容が書かれています。もちろん後からも内容変更可能です。
続いてテストケースファイルの作成が対話形式で行われます。

```bash
 Almost ready... Next step:
Creating a new test...
----------------------
? Feature which is being tested (ex: account, login, etc)  # テストケースファイル毎に付けられる名前
? Filename of a test (『上で付けたFeature名』_test.js)          # ファイル名
```

なお、この対話形式のテストケースファイル作成は、初期設定後に以下のコマンドでも呼び出せます。

```bash
$ npx codeceptjs gt
```

以下が作成されたテストケースファイルの中身です。
（ここではFeatureを`Qiita Test`とし、ファイル名を`Qiita_Test_test.js`としています）

```js
Feature('Qiita Test');    // ? Feature which is being tested で指定した名前

Scenario('test something', (I) => {

});
```

作成されたファイル・フォルダは以下になります。

```bash
.
├── codecept.conf.js
├── jsconfig.json
├── node_modules
├── output
├── package-lock.json
├── package.json
├── Qiita_Test_test.js
├── steps.d.ts
└── steps_file.js
```


#テストケースの書き方
最初にも上げましたが、CodeceptJSは自然言語っぽく書くので、テスト内容が分かりやすいです。
また要素指定もボタン名とかを書くと、いい感じに要素特定してくれて素敵です。具体的にはこんな感じになります。

```js
Feature('Qiita Test');

Scenario('test something', (I) => {
    I.amOnPage('https://qiita.com/');       // 指定URLにアクセスして
    I.seeInTitle('Qiita');                  // ページタイトルが「Qiita」になっていることを確認して
    I.see('How developers code is here.');  // 画面上に「How developers code is here.」と表示されていることを確認して
    I.click('マイルストーン');                  // 「マイルストーン」と書かれているところをクリックして
    I.wait(1);                              // 1秒待って
    I.seeCurrentUrlEquals('https://qiita.com/milestones');  // URLが期待値通りか確認して
    I.saveScreenshot('Qiita01.png', true);  // スクリーンショットを撮る（撮ったファイルはoutputフォルダの中に入る）
});
```

詳しくは[Testing with Puppeteer | CodeceptJS](https://codecept.io/puppeteer/#actions)を参照してみてください。

#テスト実施
テスト実施方法は複数あります。
まずは基本パターンです。
最初の初期設定`? Where are your tests located? (./*_test.js)`で設定したファイル形式のファイルをすべて実行します。

```bash
$ npx codeceptjs run
#### 以下結果 ####
CodeceptJS v2.6.6
Using test root "xxxxxxxxxxxxxxxx"

Qiita Test --
  ✔ test something in 6668ms

  OK  | 1 passed   // 9s
```

指定のファイルのみ実施したい場合はファイル名を指定します。

```bash
$ npx codeceptjs run [ファイル名]
```

上記のやり方だとテスト成功した場合、詳しい結果が分かりません。
なので詳しく知りたい場合は以下の3つの方法で実施します。


`--steps`をつけるとテストケースっぽく出力されます。

```bash
$ npx codeceptjs run --steps
#### 以下結果 ####
CodeceptJS v2.6.6
Using test root "xxxxxxxxxxxxxxxx"

Qiita Test --
  test something
    私は ページを移動する "https://qiita.com/"
    私は タイトルに文字が含まれるか確認する "Qiita"
    私は テキストがあるか確認する "How developers code is here."
    私は クリックする "マイルストーン"
    私は 待つ 1
    私は  U r lが等しいか確認する "https://qiita.com/milestones"
    私は スクリーンショットを保存する "Qiita01.png", true
  ✔ OK in 7568ms


  OK  | 1 passed   // 11s
```

もっと詳しく実施。

```bash
$ npx codeceptjs run --debug
```

さらに詳しく実施。

```bash
$ npx codeceptjs run --verbose
```

詳しい使い方は[Reporters | CodeceptJS](https://codecept.io/reports/#cli)を参照してみてください。

#レポート
プラグインを導入するとかっこいいレポートを出力できます。
##インストール

```bash
$ npm install -g allure-commandline --save-dev
```

`codecept.conf.js`の`plugins`にallureを追加します。

```js
// 編集前
  plugins: {
    retryFailedStep: {
      enabled: true
    },
    screenshotOnFail: {
      enabled: true
    }
  }
```

```js
// 編集後
  plugins: {
    retryFailedStep: {
      enabled: true
    },
    screenshotOnFail: {
      enabled: true
    },
    allure: {
      enabled: true
    }
  }
```
##起動
レポート出力するには以下のようにallureを有効にしてテストを実施します。

```bash
$ npx codeceptjs run --plugins allure
```

`output`フォルダがある場所（＝`codecept.conf.js`がある場所）で以下のコマンドを実行してレポートサーバを立ち上げます。

```bash
$ allure serve output
```

するとブラウザが自動で立ち上がり、レポートが表示されます。
<img width="1104" alt="スクリーンショット 2020-07-21 7.34.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361666/de45cf9c-62ec-036c-8688-45e837fff15f.png">
レポートサーバーは`Ctrl+c`で終了です。（macの場合）

#まとめ
Puppeteerはどの文字が2つ続くのか毎回分からなくなる :worried:

#We're hiring!
AIチャットボットを開発しています。
ご興味ある方は [Wantedlyページ](https://www.wantedly.com/projects/266837) からお気軽にご連絡ください！

#参考
[Testing with Puppeteer | CodeceptJS](https://codecept.io/puppeteer/#setup)
[Reporters | CodeceptJS](https://codecept.io/reports/#cli)
[Plugins | CodeceptJS](https://codecept.io/plugins/#allure)
[E2Eテストの面倒くさいことはCodeceptJSにお願いしよう - Qiita](https://qiita.com/Kesin11/items/11da1b4cf9d58e4dd9af)
[E2EテストでWEBサイトをチェック（CodeceptJS × Puppeteer） | HAFILOG](https://hafilog.com/e2e-test)