morishitaです。
Nuxt.js で作っている SPA を Amplify Console で運用していることはこれまで数本のエントリで紹介してきました。
その Amplify Console に Cypress によるE2Eテストがサポートされたという発表が2019年の10月にありました。
その時から気になっていたのですが、ついに導入したので紹介します。
結論から言うと、Preview 機能と併用するとむちゃくちゃ便利です。
更にDependabotを組み合わせるとライブラリのアップデートもサクサク進みます!
Amplify ConsoleのE2Eテスト
次の手順で、E2E テストを追加できます。
- Cypressの導入
- テストの実装
- Amplify.yml への Test ステップの追加
Cypress の導入
まずは Cypress を追加します。
> yarn add -D cypress
追加できたら次のコマンドを実行します。
> cypress open
すると cypress ディレクトリが作成され、サンプルコードが生成されます。
と同時にCypressのテストランナーウィンドウが開きます。
初回だと次のようなダイアログが表示されます。
サンプルコードを追加したので試してみろって書いてありますね。
とりあえず、OKボタンをクリックで閉じます。 ダイアログが閉じて次のように表示されます。
先程のダイアログのメッセージにあったサンプルのテストコードが表示されていると思います。
右上の Run All specs をクリックすると新たにブラウザが開いて、サンプルのテストが実行されます。
パタパタと画面が進んでなかなか見ていて楽しいです。
うまく動けば、Cypressのインストールは成功です。
テストの実装
自分のアプリケーションのテストコードは cypress/integration ディレクトリに追加していきます。
*.ts ファイルでも実装できますが、特にトランスパイルされて実行されるわけではなく、JSとして解釈され実行されるようです。なので、TSならではの型アノテーション等を実装するとエラーとなります。
きちんとトランスパイルために次のサイトに紹介されている通りに設定していきます。
次のコマンドで @cypress/webpack-preprocessor
をインストールします。
トランスパイルには Webpack や ts-loader も使うのですが、SPAアプリケーションのプロジェクトに追加するならすでにインストール済みだと思うので足りないものだけインストールします。
> yarn add -D @cypress/webpack-preprocessor
そして次のように cypress/plugins/index.js を実装します。
const wp = require('@cypress/webpack-preprocessor'); module.exports = (on) => { const options = { webpackOptions: { resolve: { extensions: ['.ts', '.tsx', '.js'], }, module: { rules: [ { test: /\.tsx?$/, loader: 'ts-loader', options: { transpileOnly: true }, }, ], }, }, }; on('file:preprocessor', wp(options)); };
さて、あとは自分のアプリケーションに合わせてテストを書いていきます。
例えば、サイトトップにアクセスして、タイトルに特定の文字列(例では「ページタイトル」)が含まれるかを確認するテストは次のとおりです。
describe('Top Page', () => { beforeEach(() => { cy.viewport('iphone-x'); cy.visit('/'); }); it('Title is valid', () => { cy.title().should('to.match', /ページタイトル/); }); });
ページを操作するコマンドや、テストに利用するアサーションは多数用意されています。
詳しいドキュメントがあるので、それを参考にテストを実装していきます。
amplify.yml の設定
Cypressでテストが実装できたら、Testステップをamplify.yml に追加します。
そうすると次のように Amplify Console にテスト結果が表示されるようになります。
Preview機能を利用していると、プルリクエストを作ると自動的に実行されるので手間いらずです。
テストフェーズの前のビルドフェーズの実行結果がそのまま残っているので、テストフェーズでは改めてNuxtアプリケーションをビルドしたりする必要はありません。
E2Eテストを実行するためには次のように amplify.yml に追加します。
test: phases: preTest: commands: - mkdir noto # ① 日本語 Fonts のインストール [ここから] - curl -O -L https://noto-website-2.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip - unzip NotoSansCJKjp-hinted.zip -d ./noto - mkdir -p ~/.fonts/noto - cp ./noto/*.otf ~/.fonts/noto/ - chmod 644 ~/.fonts/noto/*.otf - fc-cache -fv # ① 日本語 Fonts のインストール [ここまで] - nvm use $VERSION_NODE_12 # ② Nodeバージョンの変更 - yarn install - yarn add wait-on # ③ mocha のインストール ↓ - yarn add mocha@~7.1.1 mochawesome@~5.0.0 mochawesome-merge@~4.0.3 mochawesome-report-generator@~4.1.0 - 'yarn start & npx wait-on http://localhost:3000' test: commands: - 'npx cypress run --reporter mochawesome --reporter-options "reportDir=cypress/report/mochawesome-report,overwrite=false,html=false,json=true,timestamp=mmddyyyy_HHMMss"' postTest: commands: - npx mochawesome-merge cypress/report/mochawesome-report/mochawesome_*.json > cypress/report/mochawesome.json # ④ HTMLファイルの生成 ↓ - ./node_modules/.bin/marge cypress/report/mochawesome.json -o cypress/report/html artifacts: baseDirectory: cypress configFilePath: '**/mochawesome.json' files: - '**/*.png' - '**/*.mp4' - '**/mochawesome.json' - 'report/html/**/*' # ④ HTMLファイルの生成
上記の設定は次の AWS Amplify のドキュメントほぼそのままですが、丸数字でコメントしている部分を変更しています。
以下にそのポイントを説明します。
ポイント① 日本語Fonts のインストール
Amplify Console の実行環境には日本語フォントがインストールされていません。
テスト実行時にテスト実行の様子が自動的にビデオが作成されます。エラーが発生するとその画面のスナップショットが取られます。しかし、そのままでは日本語部分に文字が表示されません。それではエラーが起こった際になんだかよくわからず、デバッグに役立ちません。
なので日本語フォントをインストールしておきます。ここでは Google Noto Fonts をインストールしています。
ポイント② Nodeバージョンの変更
Amplify Consoleの実行環境では複数のNode.jsのバージョン管理にnvmを使っているようです。
ということは、nvm use
で Nodeバージョンを切り替えられます。
次の環境変数に利用可能なNode.jsのバージョンが設定されています。
- VERSION_NODE_10=10.16.0
- VERSION_NODE_12=12
- VERSION_NODE_8=8.12.0
- VERSION_NODE_DEFAULT=10.16.0
指定しなければ、 VERSION_NODE_DEFAULT
の 10.16.0
で動作します。
今となってはちょっと古めなので、VERSION_NODE_12
を指定したほうがいいかと思います。
VERSION_NODE_12
はメジャーバージョンしか指定されていませんが、2020年3月の時点では 12.8.1
がインストールされます。
ポイント③ mocha 関連モジュールのインストール
テスト結果を mochawesome 形式で整形したいので、関連モジュールをインストールします。
前述したAWSのドキュメントだと、mocha@5.2.0
が指定されています。
これはE2Eテストサポートがリリースされた当初、mochawesome が mocha のバージョン5系にしか対応していなかったためです。
今は最新の mocha に mochawesome が対応しているのでバージョン指定なしでも構わないのですが、この先のアップデートで依存関係が壊れてエラーになっても嫌なのでバージョンを指定しています。
ポイント④ HTMLファイルの生成
結果は mochawesome 形式で出力され、Amplify Consoleではそれを使って表示が作られます。エラーが発生したときにはもっと見やすい詳細結果がほしいので、HTML形式の結果も出力しています。
アーティファクトにも含めておけば、ダウンロードして次のようなファイルで結果が確認できます。
注意点
既存のAmplify Consoleのアプリケーションにテストステップを追加しても、CIフロー内で実行はしてくれるのですが、Web Console上てテストフェーズが表示されないことがあります。
その場合は、アプリケーションを作り直してやると、Test が認識され Web Console上で反映されます。
まあ、独自ドメインの設定等をしていると作り直し自体が結構厄介なのですが...。
次のように Amplify Console のアプリの設定でフレームワークとして Cypress と表示されていれば、Web Console上でちゃんと表示されます。
まとめ
Amplify ConsoleのE2Eテストについて紹介しました。
この機能について紹介しているサイトはいくつかありますが、あまり触れられていない次の項目についても紹介しました。
- 日本語対応
- Nodeのバージョン指定
- HTML形式の結果出力
Amplify Consoleでは Preview という超便利な機能があります(参考:Amplify Console の Preview は超便利)。
設定しておくとプルリクエスト毎にプレビュー環境を作成する際に、E2Eテストも実行してくれます。
更にGithubのリポジトリにDependabotを設定しておくと、Dependabotが作ったプルリクエストでも同様にE2Eテストを実行してくれます。
NPMパッケージのアップデートは結構頻繁に行われるのですが、しっかりE2Eテストを作っておくと自信を持ってマージでき、面倒なライブラリのアップデートがサクサク片付きます。
最後に
アクトインディではエンジニアを募集しています。 actindi.net