mablによるE2EテストをCircleCIから呼び出す

この記事は、
- [CircleCI Advent Calendar 2022](https://qiita.com/advent-calendar/2022/circleci) の9日目
- [mabl Advent Calendar 2022](https://qiita.com/advent-calendar/2022/mabl) の9日目
の記事です。
---

# はじめに
アプリケーションの開発プロセスにおいて、単体テストはコードが変更されてからできるだけ時間を空けずに(リポジトリにコードがコミット、プッシュされてからすぐに)実行することで、テスト結果が想定と異なっていた場合、コードを書いた人の頭の中にロジックや変数などが鮮明に残っているうちに修正に取り掛かることで、「えっと、ここって何でこうしたんだっけか...」と思い出すところから修正を始める必要がなくなります。
その一方で、ユーザーと同じ状況で同じように利用してみることで見つかるような不具合というのも、確かに存在します。
今回は、そういった「ユーザーと同じ状況」でテストする、つまり、ここの機能ではなく、ユーザーの達成したいゴールが一連の操作の流れの中で実現できているかどうかを確認するEnd to End(E2E)テストを [mabl](https://www.mabl.com/ja/) というテスト自動化のソリューションを使って自動化してみたいと思います。

- CircleCIブログ: [E2E (エンドツーエンド) テストとは？](https://circleci.com/ja/blog/what-is-end-to-end-testing/)
- CircleCIブログ: [ソフトウェア開発におけるテスト自動化の重要性とメリット](https://circleci.com/ja/blog/unit-test-automation/)

# テスト対象
今回は、テスト対象として、Node.jsを使って1ソースコードで記述したToDo管理アプリ NodeToDo をテスト対象として使用します(リポジトリは[こちら](https://github.com/mayoct/nodetodo-mabl))。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/b20db836-23fb-a64f-1f41-57da411584eb.png)

# 自動化の流れ
さて、CircleCI を使って、
- ビルド(実際には依存関係があるライブラリをnpm installで取得) - build_webジョブ
- テスト(今回は単体テストではなく eslint を使ったチェック) - test_webジョブ
- リリース(Dockerコンテナ化し、イメージを [Amazon ECR](https://aws.amazon.com/jp/ecr/) に登録することで、[AWS App Runner](https://aws.amazon.com/jp/apprunner/) (のテスト用の環境)に自動デプロイ - release_imageジョブ

した後に、自動デプロイした NodeToDo を mabl を使ってテストしていきます。

# mabl と CircleCI との連携
CircleCI での自動化ワークフローは config.yml ファイル上で定義します。

- 本プロジェクトの [config.yml](https://github.com/mayoct/nodetodo-mabl/blob/master/.circleci/config.yml) ファイル

CircleCI では mabl のような自動化の中でアプリケーションやサービスとの連携を簡潔に行うための Orb という「部品化」「再利用」の仕組みを用意しています。これにより、決まりきった定型的な設定を何度も繰り返し記述しなくても良くなるわけです。

mabl との連携も、mabl/trigger-tests Orbを使うことで、(名前が示しているように) mabl を使った自動テストをCircleCI のワークフロー中でトリガーすることが容易になります。

- [mabl/trigger-tests orb](https://circleci.com/developer/ja/orbs/orb/mabl/trigger-tests)

この trigger-tests orbが提供するコマンドの中で、実際にテストを実行するのが、[run-tests](https://circleci.com/developer/ja/orbs/orb/mabl/trigger-tests#commands-run-tests)コマンドです。run-tests コマンドは次に挙げるように、いくつかのパラメータを取ることができます(指定可能なパラメータはこれ以外にもあります)。

|パラメータ|説明|
|:-------|:--|
|api-key|mablのAPIキー。未指定時は環境変数 `MABL_API_KEY` の値が参照される。|
|application-id|mablを使ってテストを実行するアプリケーションのID。|
|environment-id|mablを使ってテストを実行するテスト環境(environment)のID。|

これらの値が mabl の画面上でどのように取得できるのかと合わせて、テストを作っていきましょう。

# mabl を使ったテストの自動化
テストを自動化するにあたり、ワークスペース、テスト環境、プラン、テストの順番に説明していきます。

## ワークスペース
mabl のワークスペースとは、後述する環境やプラン、テストを包含する一番大きな単位です。例えば、無料トライアルを始めると、このワークスペースが1つ、割り当てられます。

下に挙げた mabl の画面でも示しているように、左側でワークスペースを選択し、APIタブを選択することで、mabl のAPIキーを作成したり、作成したAPIキーをコピーすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/802a26f0-c272-bed7-55dc-4c339f80b926.png)

コピーしたAPIキーは、CircleCI のプロジェクト設定(Project Settings)画面から環境変数(Environment Variables)を選び、 `MABL_API_KEY` の値として設定しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/58fe71db-6efa-9a84-1238-618c127938e1.png)

## テスト環境
mabl のテスト環境は、アプリケーション(WebアプリケーションであればURL)やクレデンシャル、DataTableから構成されます。今回は、(特にログイン操作は必要ないので) 任意のアプリケーション名(ここでは nodetodo-mabl)、NodeToDo アプリのデプロイ先のURL を指定しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/591083ca-5243-dd5a-9639-ab39c3a7dd53.png)

## プラン
mabl のプランとは、どのテスト環境(先ほど作成)、どのステージの中で、どのテスト(後述)を、いつ(トリガー)、どのブラウザで実行するのかを管理する単位です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/235b4372-46c6-6e92-ddcb-743a62cbb82c.png)

## テスト
mabl のテストとは、Webアプリケーション上での操作や、その操作の結果、画面のどの部分でどういった操作を行うのか(値の入力やボタンの押下)、画面上はどのように表示されているのかをチェックする(アサート)といったステップを順に定義したものです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/6dee7fe3-56fe-7249-2a5a-12d859a217b1.png)

ここで作成ボタンを押すことで、指定された大きさでブラウザが表示され、その右側にmablトレーナーが表示されます。
あとはブラウザ上で操作を行なったり、アサートボタンを押したあと、チェックすべき領域と期待する値を設定するなどして、一連の操作を記録しながらテスト手順を半自動的に定義していくことができます。
また、各ステップの順序の入れ替えや、チェックすべき値の変更・修正も容易に行うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/244afa01-8b9d-19af-3dfc-6b54fe2d57d2.png)

テスト手順を登録したら、テスト実行ボタンを押すことで、ローカル環境で(自分で一連の手順が自動実行、および確認されるのを)目視で確認しながら実行することも、mabl のクラウド側で実行することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/13b1fe00-ea76-389a-de42-560518c0c579.png)

# mabl で作成した自動テストを CircleCI から呼び出す
再び mabl アプリケーションのワークスペース＞API タブを見てみましょう。
冒頭ではAPIキーを参照しただけでしたが、先ほど、アプリケーションと環境(つまりテスト環境)を作成し、プランとテストも定義しておいたので、これらを画面中ほどの「デプロイ時にテストを実行」上で、アプリケーション、環境、プランラベルを選択することで、mabl CLIのコマンド例が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/d84803b7-71e9-3b7e-9221-55a6de8bacf9.png)

trigger-tests orbの説明をした際、run-tests コマンドのパラメータをご紹介したうち、`application-id` と `environment-id` については値をどこから取得するかを説明していませんでしたが、ここから取得する、というのが答えになります。

さて、これらを反映したジョブ run_mabl_tests の定義は次のようになります。
```yaml
  run_mabl_tests:
    machine: true
    steps:
      - trigger-tests/run-tests:
          application-id: naMfa4ho96G0Al0ccA8KcA-a
          environment-id: Ba4jXgdJPoZdWrfPEzAFBw-e
      - trigger-tests/parse-results
      - store_test_results:
          path: ./test-results
```

ちなみに、普段 VSCode を使って開発作業をされているのであれば、CircleCI謹製 [CircleCI Extension](https://marketplace.visualstudio.com/items?itemName=circleci.circleci) をお勧めします！
config.yml の構文チェックもしてくれるので、pushしてから「スペルミスしてた！」的な悲劇も防止できますし、左側を見れば、修正した run_mabl_tests がちゃんと実行完了してることも(ブラウザでCircleCIのサイトにアクセスしてじっと見つめていなくても)すぐに分かります！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19248/a794af24-52df-737d-800a-0f81530b66c1.png)

# おわりに
アプリケーションやサービスに求められているのが、新たな機能をいかに多く羅列するかではなく、これまではできなかった、あるいは機能的には出来たとしても直感的な操作では辿り着けなかったゴールへの道筋を用意することであるとすれば、そういったユーザー体験をサポートするような開発がより一層求められ、それと合わせてE2Eテストの継続的な実行がより重要となることでしょう。
本ブログが、ビルド、テスト、リリースやデプロイの自動化に加え、E2Eテストの自動化の導入のきっかけとなれば幸いです。