T-DASHのGitHub Actions向けカスタムアクションを作った

# はじめに

みなさん、UIテスト書いていますか？

UIテストって作るの面倒ですよね。

私は普段Cypressを使っています。過去は別のものを使っていましたし、テストツールを自作していたこともあります。UIテストには長く関わってきたかと思います。

今回、T-DASHというテスト自動化ツールを使ってみました。

https://service.valtes.co.jp/t-dash

そして、T-DASH用のGitHub Actionsのカスタムアクションを作って、簡単にT-DASHテストをGitHub Actionsで実行できるようにしました。


以下のような流れで説明していきます。

1. T-DASHとは
2. テスト対象
3. GitHub Actionsのカスタムアクションをなんで作ったの？
4. GitHub Actionsへの組み込み方法
5. T-DASHへの要望


## 1. T-DASHとは

### T-DASHの特徴

T-DASHはCypressのようにテストを手動で作ります。操作記録型ではありません。

特徴はテストフローの可読性の高さです。
以下のスクリーンショットを見てください。

**それぞれの行はコメントではなく、テストコマンドです。**

つまり日本語でテストを記述するような仕組みになっているところが、T-DASHの最大の特徴だと思います。


![Screenshot 2023-07-08 at 21.08.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/884c77b9-f7a5-5cb7-d8b1-1f5418b0fbea.png)


### 画面定義

テストフローの高い可読性の反面、テストを書くまでには１つ手順が増えます。それが画面定義です。

画面定義では、`ゲーム`という画面には、`area1-1`というDOM要素があって、そのXPathはこれ、というような設定をします。

![Screenshot 2023-07-08 at 21.10.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/0b77d345-7b74-c552-bbce-f9b3424daf94.png)

※ 今回僕がテストしたのがマルバツゲームなので、将棋のように右上のマスを`area1-1`と私が名付けています。普通のケースだともっとわかりやすい名前になるかと思います。


XPathを拾いやすくするためのツールも提供されており、Web画面にマウスオーバーでオススメのXPathなど表示してくれます。が、私はこの手の作業で慣れているChromeのデベロッパーツールを使いました。

### テストケースの作成

テストスイートという単位があって、その中にテストケースを作っていきます。

テストケースはWeb UIで作成します。

左側のアクションを選ぶと、右側のスプレッドシートにアクションが追加されます。セルがたくさんあって迷うかもしれませんが、入力するのは右から３列分の設定値1~3だけで、白くなって入力可能になっているところだけを埋めます。

![Screenshot 2023-07-08 at 21.21.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/db1d3dcc-02fd-0195-c254-52c1c213da6b.png)

このサンプルでは、先程作った画面定義の`ゲーム`という画面を開いて、`ゲーム`の中の`area2-2`という3x3マス盤の中央マス目が最初は空で、クリックしたらXに表示が変わって・・・ということをテストしています。

Cypressでは書き方によっては、謎のDOMをクリックして、謎のDOMのテキストを取得して、何してるんだっけ、みたいなことがありえますが、T-DASHではそういうことをさせない（できない）仕組みになってます。



### テストラン

テストの実行計画のようなものです。

どのブラウザを使って、どのテストスイートを実行するかを決めます。これをしないと後述のGitHub Actionsでの実行ができません。このテストランの名前を指定するからです。

![Screenshot 2023-07-08 at 21.29.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/71163632-335d-8eb5-b6e7-6635390167bb.png)

この例ではシンプルにallというテストラン名にしています。
ブラウザはchromeのみ指定しました。





## 2. テスト対象

Reactのチュートリアルにある、Tic-Tac-Toe(マルバツゲーム)でテストします。
２人で交互にコマを置いて、３つ並んだら勝ち、の有名なゲームです。

![Screenshot 2023-07-08 at 21.14.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/6a0f0988-b951-7d76-a665-114e22ab2e15.png)

先程のテストケースでは、マス目をクリックしていって、先手（X）が勝つフローをテストしていました。

このプログラムは

```bash
% npm install
% npm start
```

で実行できる、ベーシックなフロントエンドです。`npm start`を実行することで、`http://localhost:3000`でサーバーが待ち受けるので、このURLをT-DASHから開いてテストすることが今回の目的になります。




## 3. GitHub Actionsのカスタムアクションをなんで作ったの？


T-DASHのチュートリアルで[GitHub Actionsへの連携方法](https://service.valtes.co.jp/t-dash/function/tutorial/commandline_vol_004)が書かれており、その中で、GitHub ActionsのWorkflowは以下のようになっています。

```yaml
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アクション](https://docs.github.com/en/actions/creating-actions/creating-a-composite-action)という、GitHub Actionsの記述をモジュール化する仕組みがあります。これを使って、ユーザーは可変部だけを記載して、不要な部分は隠蔽していきましょう。

Compositeアクションを作ることで、利用者は上記のワークフローStepを４行で書けるようなります。

```yml
- 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行を書いてもらえれば使えます。

https://github.com/komasayuki/t-dash-action




## 4. GitHub Actionsへの組み込み方法

T-DASHのGitHub Actions例として、サンプルプロジェクトを用意しました。

https://github.com/komasayuki/t-dash-example

先程の`t-dash-action`カスタムアクションを使って、GitHub Actionsへの組み込みを行っています。

```yaml
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です。

![Screenshot 2023-07-08 at 22.01.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/a5b56ef2-c3e4-42bc-d1e9-1d9d58723ed9.png)


この中にはテストレポートのhtmlが入っています。

![Screenshot 2023-07-08 at 22.02.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/788a795a-b6ea-07ab-b997-d1bfa27edd53.png)


## 5. T-DASHへの要望

T-DASHを使ってテストをGitHub Actionsに組み込むことができました。
T-DASHを使ってみて要望がありますので、ここに書いてみます。

### テスト失敗したら終了コードを0以外に
tdashbeta.exeがテスト失敗でも、終了コード0を返すため、テスト失敗がハンドリングできない。

### テストケースの作成画面（スプレッドシート）で、画面名や要素名を候補表示
画面定義で入力済の項目なので、選択するだけにして欲しい。

### プロジェクトが壊れた・・・

- ![Screenshot 2023-07-08 at 16.49.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/c70be116-af8d-ac3f-089b-99c7fd62e6f8.png)

`Player O wins`というテストケースごと削除してもなお、このメッセージが表示されてプロジェクトのエクスポートが動きませんでした。プロジェクトを新しく作り直しました。


### エラーメッセージをもっと優しくして欲しい

![Screenshot 2023-07-06 at 16.08.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/f71f9089-daf4-7b79-c2c3-40061dc29ac1.png)

↑ 画面名を入力していなかった


![Screenshot 2023-07-08 at 19.32.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141013/f673d491-b4ca-a8fd-81ff-16a601db6d63.png)

↑ URLが単にアクセスできない状態だった（ブラウザに問題はなかった）


### Linux対応

現在のところコマンドライン対応はWindowsだけなので、Linux対応があるとGitHub ActionsでUbuntu Runnerが使えるので、CI/CD化が容易になるし、コストも下げられます。


## 最後に

今までUIテストツールは色々と使ってきましたが、将来性を感じるテストツールでした。

「テストの可読性を最大にする！」というメッセージを感じますね。

大規模開発で、テストの可読性が課題になっているプロジェクトなどでT-DASHは効果を発揮しそうです。