はじめに
みなさん、UIテスト書いていますか?
UIテストって作るの面倒ですよね。
私は普段Cypressを使っています。過去は別のものを使っていましたし、テストツールを自作していたこともあります。UIテストには長く関わってきたかと思います。
今回、T-DASHというテスト自動化ツールを使ってみました。
そして、T-DASH用のGitHub Actionsのカスタムアクションを作って、簡単にT-DASHテストをGitHub Actionsで実行できるようにしました。
以下のような流れで説明していきます。
- T-DASHとは
- テスト対象
- GitHub Actionsのカスタムアクションをなんで作ったの?
- GitHub Actionsへの組み込み方法
- T-DASHへの要望
1. T-DASHとは
T-DASHの特徴
T-DASHはCypressのようにテストを手動で作ります。操作記録型ではありません。
特徴はテストフローの可読性の高さです。
以下のスクリーンショットを見てください。
それぞれの行はコメントではなく、テストコマンドです。
つまり日本語でテストを記述するような仕組みになっているところが、T-DASHの最大の特徴だと思います。
画面定義
テストフローの高い可読性の反面、テストを書くまでには1つ手順が増えます。それが画面定義です。
画面定義では、ゲーム
という画面には、area1-1
というDOM要素があって、そのXPathはこれ、というような設定をします。
※ 今回僕がテストしたのがマルバツゲームなので、将棋のように右上のマスをarea1-1
と私が名付けています。普通のケースだともっとわかりやすい名前になるかと思います。
XPathを拾いやすくするためのツールも提供されており、Web画面にマウスオーバーでオススメのXPathなど表示してくれます。が、私はこの手の作業で慣れているChromeのデベロッパーツールを使いました。
テストケースの作成
テストスイートという単位があって、その中にテストケースを作っていきます。
テストケースはWeb UIで作成します。
左側のアクションを選ぶと、右側のスプレッドシートにアクションが追加されます。セルがたくさんあって迷うかもしれませんが、入力するのは右から3列分の設定値1~3だけで、白くなって入力可能になっているところだけを埋めます。
このサンプルでは、先程作った画面定義のゲーム
という画面を開いて、ゲーム
の中のarea2-2
という3x3マス盤の中央マス目が最初は空で、クリックしたらXに表示が変わって・・・ということをテストしています。
Cypressでは書き方によっては、謎のDOMをクリックして、謎のDOMのテキストを取得して、何してるんだっけ、みたいなことがありえますが、T-DASHではそういうことをさせない(できない)仕組みになってます。
テストラン
テストの実行計画のようなものです。
どのブラウザを使って、どのテストスイートを実行するかを決めます。これをしないと後述のGitHub Actionsでの実行ができません。このテストランの名前を指定するからです。
この例ではシンプルにallというテストラン名にしています。
ブラウザはchromeのみ指定しました。
2. テスト対象
Reactのチュートリアルにある、Tic-Tac-Toe(マルバツゲーム)でテストします。
2人で交互にコマを置いて、3つ並んだら勝ち、の有名なゲームです。
先程のテストケースでは、マス目をクリックしていって、先手(X)が勝つフローをテストしていました。
このプログラムは
% npm install
% npm start
で実行できる、ベーシックなフロントエンドです。npm start
を実行することで、http://localhost:3000
でサーバーが待ち受けるので、このURLをT-DASHから開いてテストすることが今回の目的になります。
3. GitHub Actionsのカスタムアクションをなんで作ったの?
T-DASHのチュートリアルでGitHub Actionsへの連携方法が書かれており、その中で、GitHub ActionsのWorkflowは以下のようになっています。
name: T-DASH CI Sample
# ワークフローのトリガーは以下を参照して変更してください
# このチュートリアルでは手動実行するトリガーとしています
# 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 }}
T-DASHのCI/CD対応は現在ベータ版なので、まだGitHubカスタムアクション化はされていないようです。
GitHub ActionsにはCompositeアクションという、GitHub Actionsの記述をモジュール化する仕組みがあります。これを使って、ユーザーは可変部だけを記載して、不要な部分は隠蔽していきましょう。
Compositeアクションを作ることで、利用者は上記のワークフローStepを4行で書けるようなります。
- uses: komasayuki/t-dash-action@v1_windows
with:
sync-path: test/t-dash/sync
test-run-name: all
ユーザーが意識すべき可変部は、T-DASHからエクスポートしたテストが入っているsyncパスと、実行するテストランの名前です。
T-DASHの実行には、tdashbeta.zip
という500MB超のファイルが必要ですが、このファイルもカスタムアクション内部でダウンロードするようにして、ユーザーが管理しないようにしました。
(tdashbetaはT-DASHログイン後しかダウンロードできないので、publicリポジトリで公開していいのか迷いましたが、T-DASH開発元のバルテスさんに問い合わせて、了承を頂きました。)
開発したカスタムアクションはこちらです。
特にcloneしなくても、自分のリポジトリで上記4行を書いてもらえれば使えます。
4. GitHub Actionsへの組み込み方法
T-DASHのGitHub Actions例として、サンプルプロジェクトを用意しました。
先程のt-dash-action
カスタムアクションを使って、GitHub Actionsへの組み込みを行っています。
name: Test by T-DASH
on:
push:
branches:
- '*'
workflow_dispatch:
jobs:
test-t-dash:
runs-on: windows-latest
name: T-DASH test
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Build & launch server
run: |
npm install
npm start &
shell: bash
- uses: komasayuki/t-dash-action@v1_windows
with:
sync-path: test/t-dash/sync
test-run-name: all
このWorkflowが実行されると、サーバーが立ち上がり、UIテストが実行され、テスト結果がArtifactとしてアップロードされます。
画面の下部のArtifacts -> test resultです。
この中にはテストレポートのhtmlが入っています。
5. T-DASHへの要望
T-DASHを使ってテストをGitHub Actionsに組み込むことができました。
T-DASHを使ってみて要望がありますので、ここに書いてみます。
テスト失敗したら終了コードを0以外に
tdashbeta.exeがテスト失敗でも、終了コード0を返すため、テスト失敗がハンドリングできない。
テストケースの作成画面(スプレッドシート)で、画面名や要素名を候補表示
画面定義で入力済の項目なので、選択するだけにして欲しい。
プロジェクトが壊れた・・・
Player O wins
というテストケースごと削除してもなお、このメッセージが表示されてプロジェクトのエクスポートが動きませんでした。プロジェクトを新しく作り直しました。
エラーメッセージをもっと優しくして欲しい
↑ 画面名を入力していなかった
↑ URLが単にアクセスできない状態だった(ブラウザに問題はなかった)
Linux対応
現在のところコマンドライン対応はWindowsだけなので、Linux対応があるとGitHub ActionsでUbuntu Runnerが使えるので、CI/CD化が容易になるし、コストも下げられます。
最後に
今までUIテストツールは色々と使ってきましたが、将来性を感じるテストツールでした。
「テストの可読性を最大にする!」というメッセージを感じますね。
大規模開発で、テストの可読性が課題になっているプロジェクトなどでT-DASHは効果を発揮しそうです。