Advent Calendar駆動開発でAutifyのCircleCI Orbを作りました

この記事は [Autify アドベントカレンダー2021](https://qiita.com/advent-calendar/2021/autify) の12日目のエントリです。

---

こんにちは、[AIを使ったテスト自動化プラットフォームを提供しているAutify](https://autify.com/ja)でCTOをしております[松浦](https://twitter.com/dblmkt)です。

タイトルの通りですが、Advent Calendarの記事を書くのをきっかけにAutifyの公式CircleCI Orbを作りました！

## 背景

![Screen Shot 2021-12-11 at 15.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107/8124c5e0-57f4-10f5-c09a-017c4e60e799.png)

という当社カスタマーサクセスチームの提案から始まった今年のAdvent Calendarの取り組み、CTOとしては参加しないわけにはいかないと思いすぐに枠を取りました。

しかし、枠を取った時点ではネタは何も決まっていませんでした。こういう時は何か作ってそれをネタに記事を書くのがお決まり。ということで、以前から作らねばと思っていたAutifyの[CircleCI Orb](https://circleci.com/docs/ja/2.0/orb-intro/)を作ることにしました。

これまでもAPI([Autify For Web](https://autifyhq.github.io/autify-api/#/)、[Autify For Mobile](https://mobile-app.autify.com/api/docs/index.html))を叩くスクリプトを書くことで、CircleCIなどのCI/CDパイプラインからAutifyのテストを実行することはできました。しかし、もう1歩手軽にCI/CDパイプラインとAutifyを組み合わせられる仕組みを提供するべきという声は、お客様からも社内からも以前からありました。その仕組みの1つがこのOrbです。

## Orbの紹介・使い方

現在Autifyでは、WebアプリケーションのE2Eテストを行う[Autify For Web](https://autify.com/)と、ネイティブモバイルアプリケーションのE2Eテストを行う[Autify For Mobile](https://autify.com/mobile)の2つのプロダクトを提供しています。今回は、一挙に両プロダクトのOrbを作りました。

- [Autify For Web Orb : `autify/web`](https://circleci.com/developer/ja/orbs/orb/autify/web)
- [Autify For Mobile Orb : `autify/mobile`](https://circleci.com/developer/ja/orbs/orb/autify/mobile)

どちらもリリース時点では、CircleCIジョブ内のコマンドとしてAutify上のE2Eテスト(より具体的にはテストシナリオの集まりであるテストプラン)を実行開始できます。

### Autify For Web Orbの使用方法

まず、Autify For Web Orbを使いたいCircleCIプロジェクトの`AUTIFY_FOR_WEB_API_TOKEN`という環境変数に、テストプランを起動する際に使用するユーザのパーソナルアクセストークンをセットしてください。

それから`config.yml`を変更します。

```yaml
# config.ymlの冒頭のOrb定義部分でautify/webを指定
orbs:
  autify-for-web: autify/web@1.0.0

# ジョブ内でコマンドを呼び出し
jobs:
  deploy:
    steps:
      - autify-for-web/run_test_plan:
          test_plan_id: "123" # 実行したいテストプランのIDを指定
```

これでこのジョブが実行される際に、Autify For Web上でテストプラン(ID : 123)が起動されます。

### Autify For Mobile Orbの使用方法

まず、Autify For Mobile Orbを使いたいCircleCIプロジェクトの`AUTIFY_FOR_MOBILE_API_TOKEN`という環境変数に、テストプランを起動する際に使用するユーザのパーソナルアクセストークンをセットしてください。

それから`config.yml`を変更します。

```yaml
# config.ymlの冒頭のOrb定義部分でautify/mobileを指定
orbs:
  autify-for-mobile: autify/mobile@1.0.0

# ジョブ内でコマンドを呼び出し
jobs:
  deploy:
    steps:
      - autify-for-mobile/run_test_plan:
          build_id: 4d5E6f7g     # テスト対象アプリケーションのビルドIDを指定
          test_plan_id: 1a2B3c   # 実行したいテストプランのIDを指定
```

これでこのジョブが実行される際に、Autify For Web上でテストプラン(ID : 1a2B3c)が起動されます。

### Autify社内での使い方

実際の利用例として、Autify社内での使い方をご紹介します。

Autify社内では、主にリグレッションテストにAutify For Webを使い、Autify自体(Autify For WebもAutify For Mobileも)をテストしています。CIツールとしてはCircleCIを使っており、これまではデプロイ後にAPIを叩くスクリプトを実行してAutifyによるテストを開始していました。せっかくですので、この部分を作ったばかりのOrbに早速置き換えてみました。

当社ではGitflowに近いブランチ戦略をとっており、以下のような流れでリグレッションテストを実行しています。なお、この例はAutify For Webでのワークフローです。

1. 開発者が、フィーチャーブランチあるいはdevelopブランチをビルドしステージングにデプロイするジョブを開始(CircleCIの`type: approval`ジョブを使い、手動で承認した場合にのみこの処理を行う一連のジョブが走る仕組み)
2. ビルド
3. デプロイ
4. Autify For WebのAPIを`curl`で叩きリグレッションテストのテストプランを起動(この部分をOrbに置き換え)
5. その際のレスポンスにテスト結果のURLが含まれるので、これをパースした上でSlackに投稿

この時、Autify For WebのAPIを叩いてSlackに投稿する部分の`config.yml`は以下のようになっています(実際のものから抜粋)。

```yaml
orbs:
  autify-for-web: autify/web@1.0.0

# (中略)

jobs:
  deploy:
    steps:
      # Autify For Webでテストプランを実行
      # ここで response-web-run-test-plan.txt にAPIレスポンスが保存される
      - autify-for-web/run_test_plan:
          test_plan_id: "123"

      # 前のステップで保存されたファイルからテスト結果のIDを取得し、URLを組み立て
      - run:
          name: Get the test result URL
          command: |
            set +o pipefail
            AUTIFY_TEST_PLAN_BASE_URL=https://app.autify.com/projects/xyz/results/

            test_plan_result_id=$(cat response-web-run-test-plan.txt | jq -r .data.id)
            echo "export TEST_PLAN_RESULT_URL=${AUTIFY_TEST_PLAN_BASE_URL}${test_plan_result_id}" >> $BASH_ENV

      # 前のステップで組み立てたURLと合わせSlackに通知
      - slack/notify:
          channel: engineering-notifications
          message: "A pull request has been deployed to staging by ${CIRCLE_USERNAME}!\nRegression tests: ${TEST_PLAN_RESULT_URL}"
```

For Web、For MobileどちらのOrbも、APIからのレスポンスをファイルに保存するようになっています(ファイルパスは `response_file_path` パラメータで指定可能)。

- Autify For Web Orb : `response-web-run-test-plan.txt`
- Autify For Mobile Orb : `response-mobile-run-test-plan.txt`

このファイルに保存されたAPIレスポンスを利用してテスト結果のIDを取得し、テスト結果のURLを生成し、それを含めたメッセージをSlackに投稿しています。このSlackのメッセージから、開発者はリグレッションテストの実行結果にすぐアクセスでき、テストが失敗した際にはその原因を探ることができます。

(この辺りは本当はAPIレスポンスに結果URLを含むようにしたい気持ちも。。！)

## 最後に

ひとまず最初のリリースとしてテスト実行ができるOrbをリリースしましたが、今後もっと便利に使えるOrbにするべくコマンドの追加なども行っていきたいと考えています。

リポジトリも公開していますので、欲しい機能があったり問題を見つけたりした場合はIssueという形で報告をいただいたり、Pull Requestを作っていただくのも大歓迎です。みなさまからのご意見やコントリビューションお待ちしております！

- Autify For Web Orb : https://github.com/autifyhq/autify-circleci-orb-web
- Autify For Mobile Orb : https://github.com/autifyhq/autify-circleci-orb-mobile

それから、Orbという手段に関わらずWebアプリケーション、モバイルアプリケーションのE2Eテスト体験をどんどん改善し、ソフトウェアの品質を高めたいと思っていらっしゃる方、ぜひ当社の[採用ページ](https://autify.com/ja/careers)をご覧ください！ ご応募お待ちしております〜

また、まだAutifyを使っていないけれどE2Eテストにお悩みの方は、ぜひ[デモリクエスト](https://autify.com/ja)をお送りください！