Next.jsで作ったアプリのテストをT-DASHで自動化してみた
はじめに
この記事は、Qiita Engineer Festa 2023 「コマンドライン実行機能が実装される「T-DASH」を使って、CI/CD連携をしてみよう!」に参加するために作成した記事です
概要
テストのやり方はプロダクトによって様々です
しっかりやるとそれなりにメンテナンスコストがかかるので悩むところかと思います
今回は手軽に導入できてすぐに運用可能な自動テストツール「T-DASH」を使ってみます
T-DASHを使ってどれだけ簡単にテストを自動化できるのかを紹介します!
やりたい事
以下の3つをT-DASHでやっていこうと思います!
-
E2Eテスト
パターン別でフォーム申請できる事をテストする -
スナップショットテスト
レスポンシブでUIが崩れていないかをテストする
ブラウザ別でも同じUIになっているかをテストする -
GithubのCI/CD連携
GithubとT-DASHを連携して、プルリクエスト作成時にテストが実行ができる事を確認する
アプリの準備
T-DASHのテスト用にNext.jsで簡単なアプリを作成しました!
その名も「PS5くださいフォーム」…!笑
※イベントの景品がPS5の為
こちらのアプリに対してT-DASHでテストを作ります
アプリは以下の様な仕様となっています
- 入力・確認・完了の3画面構成のフォーム
- 全ての項目に入力がない場合は画面を移れず、エラーメッセージを表示する
- 入力画面・確認画面は簡単なレスポンシブ対応をしている
- 全てのブラウザで同じUI表示になるようにしている(リセットスタイルの適用)
T-DASHのセットアップ
まずはT-DASHのインストール・初期設定をします
今回はMacへの導入方法を記載しますが、Windowsの場合でも公式にマニュアルがあるので、
それを見れば簡単にインストールできるかと思います
-
T-DASHをダウンロードする
T-DASHのトライアル申し込みページから利用申請を行います
トライアルお申し込み
申請後に指示に従って進めるとT-DASHのダウンロードリンクに行き着くので、
そこからダウンロードする事ができます
-
T-DASHのインストール(Mac)
同封されているPDFマニュアルに詳しくは記載されているのでそれに従えばいいです
ダウンロードしたファイルのt-dash_*.dmg
、tdashcap-*.dmg
の二つをインストールすれば終わりです -
Pythonのインストール
インストールしたT-DASHがlocalhost:8686
で立ち上がります
動作環境としてPythonがインストールされている必要があるので、
別途インストールしてパスを入力します
Pythonの設定が終わるとホームディレクトリのT-DASHフォルダにファイルが生成されます
T-DASH内でプロジェクトを作成してもこのフォルダ内に生成されるようです
-
サンプルプロジェクトでテスト
T-DASHにはデフォルトでサンプルアプリが入っていて、
一通りのテスト内容が全部登録されていますので実行するとテストの様子がすぐに見れます
(勝手にブラウザが立ち上がって色々自動で操作されるテストが始まります)
ちなみにサンプルアプリの内容はこんな感じ
Storybookとかを使っているプロジェクトであれば、
このサンプルアプリと同じように簡単にコンポーネントテストもできそうですね!
これでT-DASHのセットアップは終わりです!
申請から20分もあればテストを試すことができちゃいます!
T-DASHのテスト
用意したアプリに対してT-DASHでテストを作ります
公式でマニュアルが用意されているのでこれに沿って進めます
まずはすごく単純に「アプリを開いてボタンを押す」というテストを作ってみます!
-
プロジェクトを作成する
新しくプロジェクトを作成します
作成したプロジェクトを開くと以下のようなページが開きます
サイドバーの項目ごとの機能はざっくりこんな感じです-
ダッシュボード
テストの実施状況を確認する事ができ、
全体での成功率などをグラフで表示する事もできます -
テストスイート
テストスイートはテストケースをまとめたものを指します
ここにテストのシナリオを作って1つのテストスイートとして管理します -
テストラン
テストスイートをまとめて実行する事ができます
また、外部連携を行う場合はテストランを作る必要があります -
画面定義
テストするアプリをURL毎に管理する事ができます
画面毎にどの要素が特定のUIになるかを設定できます -
動作定義
「画面のURLをブラウザで開く」「テキストを入力する」などの、
テストスイートで使用するテストに使用する「操作」を管理できます
-
-
テストスイートを作成
次にテストスイートを作成します
テストスイートを作成すると以下のような画面になるので、
テストケースを作成からテストシナリオを追加していきます
テストスイートの作成は、
直感的にわかりやすい仕様なので説明は不要かと思います以下の内容でテストスイートを作ってみました!
アプリを開く
↓
フォームの「名前」に入力
↓
フォームの「内容確定ボタン」を押下
↓
入力内容が足りていないので「エラーメッセージ」が表示される -
画面定義を作成
最後に画面定義を作成します
画面定義に移動するとテストスイートで定義した「フォーム」が追加されているので、
それを選択してその画面が表示される「URL」を入力して画面キャプチャを押下します
画面キャプチャツールが起動するので、
このツールでどの要素がどのUIに当てはまるのかを紐づけます
-
テストを実行する
これでテストスイートが完成です!
テストスイートに戻ってテストを実行してみました!
機能テスト
アプリのテストをしっかり作ってみます
先ほど作成したテストと同じ様にテストスイートを作成するだけです!
- 作成したテストスイート
フォーム入力
↓
フォーム入力失敗
↓
フォーム入力
↓
フォーム内容確認
↓
フォーム再入力
↓
フォーム内容確認
↓
フォーム申請完了
実行した結果がこちら!
スナップショットテスト
スナップショットテストとは名前の通り、
想定している画面のスナップショットを予め用意しておいて、
テストでレンダリングされた画面と想定しているスナップショット画像を比較するテストです
T-DASHでも「画像比較検証」という方法で同じような事ができるので、
これを使って以下のテストをしてみようと思います!
- レスポンシブでUIが想定通りの動きをしているかのテスト
- ブラウザ毎でUIに違いがないかのテスト
まずは想定している画面のスナップショット「期待画像」を準備します
入力画面と確認画面の2つを用意しました
入力画面の期待画像 | 確認画面の期待画像 |
---|---|
次に「画像比較検証」のテストスイートを作成します
使う操作は3つで以下の様に使用します
- [ブラウザ制御]現在のブラウザサイズを変更する
- メディアクエリーで画面UIが変化するサイズまで画面サイズを調節する
- [画像認識操作]現在の画面と機体画像を比較する
- 期待画像とレンダリングされた画面の差分をチェックする
- [画像認識操作]比較した画像の一致率が指定%以上であることを検証する
- 期待画像とレンダリングされた画面の一致度を測定する
今回は予め期待画像をローカルに用意していますが、
テストスイートの中でスナップショットを用意する事も可能です
テストスイートを実行すると「テストレポートを開く」から、
テスト結果の詳細を確認する事ができます
こちらで表示されている画像は、
左から「レンダリング結果」「期待画像」「検証差分」となります
検証差分は画面全体が黒くマスクされていて、
白くなっている部分だけが差分となります
入力画面の画像検証結果 | 確認画面の画像検証結果 |
---|---|
ブラウザ別で確認する方法はテストランを作る事で可能です
環境毎にテストランを作成したら
テストランで実行するテストスイートを紐付けて
ブラウザ毎で同じ様にテストランを作成する事で、
簡単にブラウザ事でのテストを作る事が可能です
GithubのCI/CD連携
T-DASHとGithub Actionsを連携させて、PR作成時に自動テストをさせてみます
連携方法は公式でマニュアルが用意されているのでこれに沿って進めます
まず初めにリポジトリですが、
リポジトリフォルダ内にsyncファイルというT-DASHのプロジェクトからエクスポートしたファイルを置かなくてはいけない為、
プライベートリポジトリを使用します
こちらのリポジトリをコピーしてPrivateリポジトリを作っておきます
次にT-DASHからsyncファイルをエクスポートして、
作成したリポジトリにpushします
さらにQUINTEEマイページからコマンドラインツールをダウンロードして、
ダウンロードしたファイルの中の「tdashbeta」というファイルもリポジトリにpushします
(QUINTEEマイページは最初にT-DASHをダウンロードしたページ)
そして最後に.github/workflows
に任意の名前でymlファイルを追加する
内容はマニュアルに載っていたものとほぼ同じ
name: T-DASH
# ワークフローのトリガーは以下を参照して変更してください
# このチュートリアルでは手動実行するトリガーとしています
# https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows
on:
workflow_dispatch:
env:
TDASH_ROOT_PATH: "$HOME/AppData/Local/Programs/T-DASH"
TDASH_CMD_EXE_PATH: "$HOME/AppData/Local/Programs/T-DASH/tdash.exe"
TDASH_BETA_ZIP_PATH: "/tdashbeta/tdashbeta.zip.001"
TDASH_BETA_EXE_NAME: "tdashbeta.exe"
ZIP_INSTALLER_URL: "https://www.7-zip.org/a/7z2300-x64.exe"
ZIP_INSTALL_EXE_PATH: "7zip/7z2300-x64.exe"
ZIP_EXE_PATH: "C:/Program Files/7-Zip/7z.exe"
REPORT_PATH: "C:/Users/runneradmin/AppData/Local/Programs/T-DASH/projects/commandlinetestrun/reports"
jobs:
build:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v3.5.2
- name: Setup Chrome (Test browser)
uses: browser-actions/setup-chrome@v1.2.0
with:
chrome-version: latest
- name: 7-zip install
run: |
New-Item -Path "7zip" -ItemType Directory
Invoke-WebRequest -Uri "${{ env.ZIP_INSTALLER_URL }}" -OutFile "${{ env.ZIP_INSTALL_EXE_PATH }}"
Start-Process -FilePath "${{ env.ZIP_INSTALL_EXE_PATH }}" -ArgumentList "/S" -NoNewWindow -Wait
- name: T-DASH cmd decompress
run: |
cmd /c "${{ env.ZIP_EXE_PATH }}" x -o${{ github.workspace }} "${{ github.workspace }}${{ env.TDASH_BETA_ZIP_PATH }}"
- name: make root dir
run: |
# T-DASHルートディレクトリがない場合は作成
if (-not (Test-Path -Path ${{ env.TDASH_ROOT_PATH }})) {
New-Item -Path ${{ env.TDASH_ROOT_PATH }} -ItemType Directory
}
- name: T-DASH cmd copy
run: |
$sourcePath = '${{ github.workspace }}/${{ env.TDASH_BETA_EXE_NAME }}'
# 実行ファイルが存在する場合は削除
if (Test-Path ${{ env.TDASH_CMD_EXE_PATH }}) {
Remove-Item ${{ env.TDASH_CMD_EXE_PATH }} -Force
}
Move-Item $sourcePath ${{ env.TDASH_CMD_EXE_PATH }}
- name: Run initial setup
run: |
# T-DASHの実行環境はexeを実行したフォルダに作成されるためカレントディレクトリを移動する
cd ${{ env.TDASH_ROOT_PATH }}
# T-DASHの実行環境構築
Start-Process -FilePath ${{ env.TDASH_CMD_EXE_PATH }} -ArgumentList "setup","--silent" -NoNewWindow -Wait
- name: Run the application
run: |
# リポジトリ管理しているテストを実行するsyncフォルダパス
$sourcePath = '${{ github.workspace }}\sync'
# コマンドライン実行するテスト実行環境のsyncフォルダパス
$destinationPath = '${{ env.TDASH_ROOT_PATH }}\projects\commandlinetestrun\sync'
# 共有フォルダが既に存在する場合は一度フォルダごと削除する
if (Test-Path $destinationPath) {
Remove-Item $destinationPath -Recurse -Force
}
# リポジトリのsyncをコマンドライン実行テスト環境のsyncへコピー
Copy-Item $sourcePath "${{ env.TDASH_ROOT_PATH }}\projects\commandlinetestrun\" -Recurse -Force
cd ${{ env.TDASH_ROOT_PATH }}
# テスト実行
Start-Process -FilePath ${{ env.TDASH_CMD_EXE_PATH }} -ArgumentList "testrun","ホテルテストラン","--background" -NoNewWindow -Wait
- name: Save results to artifacts
uses: actions/upload-artifact@v3.1.2
with:
name: results
path: ${{ env.REPORT_PATH }}
全部pushしたら、Github > ActionsからT-DASHのworkflowを実行
テストが完了すると、Artifactsに実行結果のファイルが吐き出されるので、
そのファイル(html)から実行結果を確認する事ができます
T-DASHを使って思った事
良かったところ
-
とにかく導入が簡単
「T-DASHのテスト」でも書いたように、
導入が簡単で申請から20分程度でテストを試す事ができました! -
操作方法が直感的にわかりやすい
主に「テストスイート」「画面定義」の操作は、
マニュアルを見ずとも理解できるくらい直感的にわかりやすかったです! -
テストの実行結果がわかりやすい
テストスイートでの実行レポートはとてもわかりやすく、
これなら大量にテスト項目を用意しても管理しやすそうだと思いました
エラーが発生した場合のエラーメッセージもわかりやすかったです! -
マニュアルが豊富で利用者に優しい
公式でのマニュアルがかなり豊富で使い方がわからないという事はありませんでした
マニュアル以外にもデフォルトで入っているサンプルアプリも結構参考になりました!
改善されると良いなと思ったところ
-
テストの並列実行ができない
大きなサービスで運用した場合ではテスト時間が結構かかるのではと思いました、
テストランではテストスイートを並列実行できても良いのかなと思いました -
Github連携がまだあまり実用的ではない
CI連携がまだベータ版というのもあるので、これから使いやすくなる事を期待したいです -
テストのスケジュール実行ができない
スケジュール実行できると完全な自動テストになるので、あったら良いなと思いました -
モバイルアプリ対応
現状Webメインにないっているので、モバイルアプリの対応も期待しています
こちらは公式の開発ストーリーによると実装予定となっていました!
Discussion