Next.jsプロジェクトにCypressを導入してGitHub ActionsでE2Eテストをする
はじめに
※この記事は下記記事の延長です。下記記事を読まなくても問題ないように書いていますが、ご興味ありましたらご一読ください。
今回はNext.jsプロジェクトにCypressを導入してGitHub ActionsでVercelのPreview環境のE2Eテストをするまでの手順を書いていきたい思います。
前提
- Next.jsで
src
ディレクトリ配下にアプリケーションコードを配置していること - Vercelを使用しており、PRごとにPreview環境がデプロイされること
導入手順
- 必要なパッケージをインストール
- npm scriptsを
package.json
に追加 -
yarn cy:open
を実行し雛形を作成 - 設定ファイルを修正し初めてのテストを実行
- TypeScript対応
-
@testing-library/cypress
の設定 - GitHub Actionsの設定
必要なパッケージをインストール
yarn add cypress @testing-library/cypress --dev
@testing-library/cypress
はCypressのテストコードで使える便利コマンドを提供してくれます。
package.json
に追加
npm scriptsを"scripts": {
"cy:open": "cypress open",
"cy:run": "cypress run"
}
これでyarn cy:open
でテストのGUI実行などができるCypressアプリが起動し、yarn cy:run
でCypressによるテストのCLI実行が可能になります。
yarn cy:open
を実行し雛形を作成
yarn cy:open
初めてyarn cy:open
を実行すると、以下のような設定ファイルやサンプルのテストコードなどがcypress
ディレクトリの配下に作成されます。
-
cypress.json
: Cypressの設定ファイル -
cypress/fixtures
: Cypressのテストコードで使えるテストデータを配置するディレクトリ -
cypress/integration
: Cypressのテストコードを配置するディレクトリ -
cypress/plugins
: Cypressのプラグイン用設定ファイルを配置するディレクトリ -
cypress/support
: Cypressにカスタムコマンドを追加するための設定ファイルなどを配置するディレクトリ
設定ファイルを修正し、初めてのテスト実行
以下のようにcypress.json
にbaseUrl
を追加します。
{
"baseUrl": "http://localhost:3000"
}
次にcypress/integration
配下のファイルを全て削除し、以下のテストファイルを追加します。このテストはルートパスに訪問できるかを検証しています。
it('ルートパスに訪問できるか', () => {
cy.visit('/')
})
この状態でターミナルで以下のコマンドを入力して、テストを実行します。
yarn cy:run
するとCypressによるテストが実行されます。
ここでcypress/videos
を確認するとテストが実行されている様子を動画で確認できます。
またテストが失敗した場合はcypress/screenshots
にテストが失敗した時点のスクリーンショットを確認できます。
以下のように.gitignore
を修正してこれらのディレクトリがリポジトリに含まれないようにしておきましょう。
# cypress
cypress/screenshots
cypress/videos
またcypress.json
に設定を追加することで動画やスクリーンショットを保存しないようにすることも可能です。
TypeScript対応
以下のようにcypress
配下にtsconfig.json
を追加します。
// @see https://docs.cypress.io/guides/tooling/typescript-support#Clashing-types-with-Jest
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": ["cypress"],
"isolatedModules": false
},
"include": ["../node_modules/cypress", "./**/*.ts"],
"exclude": []
}
Jestを導入しているプロジェクトも多いと思うので、今回はCypressの型とJestの型が衝突してしまう問題を解消するための設定を紹介しています。
次にcypress
配下のファイルの拡張子を.ts
に変更します。
この時cypress/plugins/index.ts
の型エラーの解消とcypress.json
に設定の追加を行います。
- module.exports = (on, config) => {
+ module.exports = (_on: Cypress.PluginEvents, _config: Cypress.PluginConfig) => {
"baseUrl": "http://localhost:3000",
+ "pluginsFile": "cypress/plugins/index.ts",
+ "supportFile": "cypress/support/index.ts"
@testing-library/cypress
の設定
以下のように@testing-library/cypress
の設定をすることでCypressで使える便利コマンドを追加することができます。
+ import '@testing-library/cypress/add-commands'
"compilerOptions": {
+ "types": ["cypress", "@testing-library/cypress"],
例えば、CypressのBest Practicesでも紹介されている、data属性を使用した要素の取得を便利にするコマンドを使用できます。
以下のような設定をすることでcy.findByTestId
に取得したい要素のdate-test-id
属性の値を渡すことで要素を取得できます。
+ // @see https://github.com/testing-library/cypress-testing-library#config-testidattribute
+ import { configure } from '@testing-library/cypress'
+ configure({ testIdAttribute: 'data-test-id' })
<button data-test-id="hoge-button">hoge</button>
cy.findByTestId("hoge-button").click()
ちなみにfindByTestId
を使用せずに要素を取得する場合は以下のようになります。
cy.get("[data-test=hoge-button]").click()
GitHub Actionsの設定
ここまででローカル環境ではテストを実行するところまで完了したので、GitHub Actionsでも実行できるようにしましょう。
以下の設定ファイルを追加してください。
name: Cypress
on: deployment_status
jobs:
cypress:
if: |
github.event.deployment_status.state == 'success' &&
github.event.deployment_status.environment == 'Preview'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 14.x
- uses: actions/cache@v2
with:
path: ~/.cache/yarn
key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }}
restore-keys: ${{ runner.os }}-yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile --prefer-offline
- name: Run cypress
uses: cypress-io/github-action@v2
with:
install: false
config: baseUrl=${{ github.event.deployment_status.target_url }}
on: deployment_status
を指定することで、VercelがPreview環境へのデプロイを開始した時とデプロイを完了した時の2回、このワークフローが実行されます。
今回はVercelのPreview環境のE2Eテストをしたいので、デプロイを完了した時のみこのワークフローが実行されるようにif
に条件を指定しています。
Cypressの実行にはcypress-io/github-action@v2
を使用し、実行対象のURLにPreview環境のURLを指定しています。
この状態でGitHubでPRを作成すると、VercelがPreview環境へのデプロイを完了した時にCypressが実行されると思います。
おわりに
いかがでしたか。
これでNext.jsプロジェクトにCypreesを導入してGitHub ActionsでVercelのPreview環境のE2Eテストをすることができました。
ここまでしておけば機能追加や修正時の手動テストの削減につながると思うのでぜひ導入してみてください。
それではよいNext.jsライフを!
Discussion