今日はVisual Regression Test 導入その1の続きをします。
いろいろと端折っているのでこのままコピペしても動きません
技術選定
今回はアプリケーションにアクセスし画面を撮影できるツールが必要になります。E2Eテストツールとして採用しているPlaywrightが利用できそうだったので使う事にしました。
Playwright
E2Eテストツール。スクリーンショットの撮影、正解画像との比較、レポーティングすべてをこなせる。
構成図
CIはGitHub Actionsを使用しています。ビジュアルのテストなのでデータを固定しないといらぬ差分が生まれてしまいますが、開発環境のアプリケーションを使用するとテストデータの扱いがややこしくなるため、GitHub Actions上でアプリケーションを起動するスタイルを取りました。
作っていく
各種インストール
まずは選定した各種ツールをインストールします。
pnpm add -D playwright
VRTの設定
E2Eテストで使用するPlaywrightの設定ファイルとは分けてVRT用の設定ファイルを作成します。
import { defineConfig } from '@playwright/test';
import config from './playwright.config';
export default defineConfig({
// 基本的にはE2Eテストと同じ設定
...config,
// テストファイルをディレクトリごとE2Eテストとは分ける
testDir: './vrt',
// S3にアップロードしやすいようにsnapshotをひとつのディレクトリにまとめる
snapshotDir: './vrt/snapshot/',
use: {
...config.use,
// Service ContainersにGitHub Actionsランナーからアクセスする時はlocalhostを指定する
baseURL: 'http://127.0.0.1:3000',
},
reporter: 'html',
});
各種スクリプト
package.json
にVRT関連のスクリプトを追加します
"vrt.page": "playwright test --config playwright.vrt.config.ts",
"vrt.update": "playwright test --config playwright.vrt.config.ts --update-snapshots",
-
vrt.page
VRTを実行します。VRT用設定ファイルを指定します。 -
vrt.update
正解イメージを撮影します。
GitHub Actions
まずは pull request
時のVRT本体を作っていきます。前回と違うのはService Containerを利用しているところくらいです。
name: ビジュアルリグレッションテスト
on: pull_requst
# 実行内容
jobs:
# jobID
visual_regression_test:
name: ビジュアルリグレッションテスト
runs-on: ubuntu-latest
services:
# アプリケーションを起動する
app:
image: ${{ vars.image-path }}
credentials:
username: ${{ secrets.username }}
password: ${{ secrets.password }}
ports:
- '3000:3000'
permissions:
id-token: write # AWS認証のため
contents: read
packages: read
pull-requests: write
# 実行コマンドたち
steps:
# node installとか略
- name: AWS認証
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.aws-role-arn }}
- name: mainブランチの画像をダウンロード
run: aws s3 sync s3://${{ vars.snapshot-s3-bucket }}/ ./vrt/snapshot/
- name: playwrightのブラウザをインストール
run: pnpm exec playwright install --with-deps
- name: ビジュアルリグレッションテストの実行
id: visual-regression-test
run: pnpm vrt.page
continue-on-error: true # 差分があっても失敗とはマークしない
- name: テスト結果を保存
id: save-report
# VRTが実行された場合のみ保存
if: always() && (steps.visual-regression-test.outcome == 'success' || steps.visual-regression-test.outcome == 'failure')
run: aws s3 sync ./playwright-report/ s3://${{ vars.report-s3-bucket }}/
# 結果のPR連携 略
GitHub Actions内でアプリケーションを起動するためService Containersの機能を利用します。
services:
# アプリケーションを起動する
app:
image: ${{ vars.image-path }}
credentials:
username: ${{ secrets.username }}
password: ${{ secrets.password }}
ports:
- '3000:3000'
S3から画像をDLするのに必要なAWSの認証を済ませてから比較用の画像をDLします
- name: AWS認証
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.aws-role-arn }}
- name: mainブランチの画像をダウンロード
run: aws s3 sync s3://${{ vars.snapshot-s3-bucket }}/ ./vrt/snapshot/
Playwrightがテストに使用するブラウザをインストールします。既にインストール済みのコンテナがPlaywrightから公開されていますが、すべてが揃っている訳ではないようで結局差分のインストールが必要だったり、AWS CLIは手動でインストールが必要だったり、結果的に実行時間がさほど変わらなかったため、ランナーを使用しワンライナーで実行できるPlaywrightブラウザインストールの方を実施するようにしました。
- name: playwrightのブラウザをインストール
run: pnpm exec playwright install --with-deps
先ほど追加したスクリプトを利用して画像比較&レポートを出力します。ここでは省略していますがこの結果を以ってプルリクエストへコメントする内容を変更するため、差分が出ても失敗とはせずCIを続行させます。
- name: ビジュアルリグレッションテストの実行
id: visual-regression-test
run: pnpm vrt.page
continue-on-error: true # 差分があっても失敗とはマークしない
最後に結果レポートをS3へ保存します
- name: テスト結果を保存
id: save-report
# VRTが実行された場合のみ保存
if: always() && (steps.visual-regression-test.outcome == 'success' || steps.visual-regression-test.outcome == 'failure')
run: aws s3 sync ./playwright-report/ s3://${{ vars.report-s3-bucket }}/
次に merge
時のイメージの更新を作ります。
name: イメージ更新
on: pull_requst
# 実行内容
jobs:
# jobID
update_images:
name: 正解イメージ更新
runs-on: ubuntu-latest
services:
# アプリケーションを起動する
app:
image: ${{ vars.image-path }}
credentials:
username: ${{ secrets.username }}
password: ${{ secrets.password }}
ports:
- '3000:3000'
permissions:
id-token: write # AWS認証のため
contents: read
packages: read
pull-requests: write
# 実行コマンドたち
steps:
# node installとか略
- name: playwrightのブラウザをインストール
run: pnpm exec playwright install --with-deps
- name: スナップショットの更新
id: update-snapshot
run: pnpm vrt.update
- name: AWS認証
uses: aws-actions/configure-aws-credentials@v4
with:
aws-region: ap-northeast-1
role-to-assume: ${{ secrets.aws-role-arn }}
- name: スナップショットのアップロード
run: aws s3 sync ./vrt/snapshot/ s3://${{ vars.snapshot-s3-bucket }}/pages/ --delete
最後のスナップショットのアップロード以外はVRT本体と変わりません
最後に
まだ実運用前なのでいったんこれで様子見していきます。