CADDi DRAWERにE2Eテスト自動化の導入を進めています

こんにちは、DRAWER Enabling QAチームの猿渡です。 この記事ではDRAWER QAチームで進めているE2Eテスト自動化についてご紹介します。

課題

CADDi DRAWERにはQAチームがあります。品質保証業務は、開発エンジニアや外部パートナーなど様々な方と連携し行っています。

現在QAが行っているテストは、システム全体をスコープにしたエンドツーエンド(E2E)テストです。。 CADDi DRAWERでは、DRAWER Product Testing Guidelineにより、以下のテストカテゴリを定義しており、E2Eテストでは、Test Size: Largeの「Story Tests」と「Scenario Tests」のCategoryに対してソフトウェアテストライフサイクル(STLC)を行っています。

[DRAWER Product Testing Guideline]
Category Test Size Description Run Timing Quality
Unit Tests Small 依存はStubする。そのDomainやDomain Service、Use Caseの振る舞いが正常なのか検証する。 Local, CI 内部品質
Integration Tests Medium コンポーネントが外部に依存するDBや外部サービスといった別コンポーネントとの結合をテストする。 Local, CI 内部品質
Component Tests Small 外部依存はStubする。そのService単体として振る舞いが正常に行われているかどうか検証する。 Local, CI 内部品質
Scenario-Based Integration Tests Medium システム全体としてシナリオテストが満たせるかどうかAPIのみで検証する。つまり、Scenario Test から UI 操作を除いたもの。Stubは使わない。 CI 内部品質
Story Tests Large 開発機能の受入条件が満たされているのか検証する。 Before Release 外部品質
Scenario Tests Large ユーザーの代表的な操作シナリオを定義してリグレッションが発生していないかUIから操作して検証する。 Before Release 外部品質

今のE2Eテストは全て手動テストで実行していることで、今後「E2Eテストがリリースのボトルネックになることによる、顧客に対する価値提供が遅れ」が顕在化することが想定されます。

CADDi DRAWERの開発チームは、事業の急成長に合わせて拡大し、開発生産性も向上しています。ソフトウェア開発ライフサイクルの高速化に合わせて、ソフトウェアテストライフサイクルも同期させる必要があります。 早くソフトウェアが価値を生み出すために、一定のQuality Gateとして機能しているE2Eテストを高速化させ、顧客への価値提供のリードタイムを短くすることが重要です。

さらに、将来的には、マイクロサービスでのE2Eテストによる品質保証にも課題があると考えます。今まで通りにシステム全体に対するE2Eテストでは、テストがフェールすると、その原因となった問題が解決されるまで、すべてのマイクロサービスのリリースがブロックされてしまいます。マイクロサービスがユーザーインターフェースを持っている場合のE2Eテストの扱いについては今後のテーマと捉えていますが、独立的なE2Eテストが必要になるのではと考えています。

目指すは『テストピラミッド』のようなShift Leftされた状態を思い描きながら、まずは、ピラミッドを登りながら改善を進めるのではなく、ピラミッドの頂上から改善を進め、「リードタイムの短縮」「マイクロサービスでの独立したE2Eテスト」をGoalとし、E2Eテストをできるだけ自動化することへの取り組みを始めました。

E2Eテスト自動化に向けて

QAチームが所属するEnablingチームには、ArchitectureチームとSREチームがいます。特にE2E自動化のCI/CDなど環境構築はSREチームと協力しながら進めています。

E2Eテスト導入のROIとテスト戦略

  • E2Eテスト導入のROIとして、ローコード系有償ツールを導入した場合の試算をしました。ただし、自動化によって得られる継続的な価値(Delivery高速化の価値など)を数値化することは難しかったので、金銭コスト、時間コストで効果測定しました。 E2E_ROI
  • To-BeのE2Eテスト戦略として、手動テストと自動テストの役割を決めました。自動テストの担当はテスト自動化アーキテクトをメインとしたエンジニア(SDET)が担当、手動テストはテストエンジニア(TE)が担当することでハイブリッドなSTLCとし、品質面で品質保証エンジニア(QA)が伴走する形を考えています。
    Category テスト担当 品質担当
    手動テスト Story Tests: Functional Tests Test Engineer(TE) Quality Assurance Engineer(QA)
    自動テスト Scenario Tests: Functional Regression Test Software Development Engineer in Test(SDET) Quality Assurance Engineer(QA)
    自動テスト Scenario Tests: Visual Regression Test Software Development Engineer in Test(SDET) Quality Assurance Engineer(QA)

自動化ツール選定 と実行環境

  • 選定はローコード系とオープンソース系で行いました。費用、学習コスト、汎用性、拡張性、コーディングスキルの観点でPros/Consを整理した結果、オープンソースのPlaywrightを採用しています。詳細は、次項に記載します。

上記のテスト戦略から、まずは「Visual Regression Test」の自動化から取り掛かることにしました。

Playwright + reg-suitで実践するVRT

E2Eテストの自動化を、CI/CDのパイプラインを利用して開発のサイクルに組み込む方針で実装を検討してみました。 上述の通りツールはPlaywrightを採用しており、Playwright単体でもVRTは実現できますが、reg-suitというツールを組み合わせるとより高機能なレポートを生成することができます。 (インストールやセットアップについては今回の記事では扱いません)

なぜreg-suitを採用したのか?

  • VRTをするためにシンプルかつ十分なUIが用意されている
  • シンプルにファイル名での比較をするので利用に際しての難易度が低く、合わせて利用するツールの自由度が高い
  • 外部ストレージへの保存がデフォルトで搭載されており、データのポータビリティ性が高い

実装方針

CADDi DRAWERの開発チームではgit tagを利用したリリースフローを採用しており、tag間の差分でVRTを実行する方針とします。 reg-suitにはreg-simple-keygen-pluginというプラグインがあり、任意のKeyを利用して比較を行うことができます。このプラグインのKeyをtagにすることによりtag間の比較を行います。 処理の流れとしては以下のようになります。 1. regconfig.jsonで設定されているactualDirに画像ファイルを出力する(playwrightのscreenshot機能を利用) 2. regconfig.jsonに直前のtagと現在のtagを比較するように設定する 3. reg-suitを実行してレポートを作成する

git tagベースのVRTの実装

regconfig.jsonは以下のようになります。

{
  "core": {
    "workingDir": ".reg",
    "actualDir": "directory_contains_actual_images",
    "thresholdRate": 0,
    "ximgdiff": {
      "invocationType": "client"
    }
  },
  "plugins": {
    "reg-simple-keygen-plugin": {
      "expectedKey": "EXPECTED",
      "actualKey": "ACTUAL"
    },
    "reg-notify-slack-plugin": {
      "webhookUrl": "<slack incoming webhook url>"
    },
    "reg-publish-gcs-plugin": {
      "bucketName": "<your bucker name>"
    }
  }
}

expectedKeyとactualKeyはGitHub Actionsの中で直前のtagと現在のtagで置換します。 GitHub Actionsのworkflowは以下のようになります。

name: VRT

on:
  push:
    tags:
      - 'v*'

jobs:
  tag_push:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - id: 'auth'
        name: 'Authenticate to Google Cloud'
        uses: 'google-github-actions/auth@v0.4.0'
        with:
          project_id: ${{ secrets.GCP_PROJECT_ID }}
          service_account: ${{ secrets.GCP_WIF_SERVICE_ACCOUNT }}
          workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
      - name: Checkout main branch
        uses: actions/checkout@v3
        with:
          ref: main
          fetch-depth: 0
      - name: Use Node.js
        uses: actions/setup-node@v1
        with:
          node-version: "18.x"
      - name: Run npm install
        run: |
          npm ci
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run playwright
        run: |
          npx playwright test
      - name: Replace reg-suit tag
        run: |
          sed -i "s/EXPECTED/$(git tag | tail -2 | head -1)/g" regconfig.json
          sed -i "s/ACTUAL/$(git tag | tail -1)/g" regconfig.json
      - name: Run reg-suit
        run: |
          npx reg-suit run

git tagがpushされるタイミングで実行されます。 reg-suitを実行する際にGCSへの読み取りと書き込みが発生するため、GitHub Actions内でGCSにアクセスするためにWorkload Identity連携を利用してアクセスできるように設定してあります。 実装方針に則りVRT関連の処理は以下の3 stepになります 1. playwrightを実行してscreenshotを取得する(Run Playwright) 2. regconfig.jsonの書き換え、expectedKeyとactualKeyをgit tagで置換する(Replace reg-suit key) 3. reg-suitを実行してレポートを出力する(Run reg-suit

実行が完了すると以下のようなslack通知とVRTのレポートが作成されます(サンプルのスクリーンショット)。 !

今後の課題

git tagを利用してのVRTを構築しましたが、実際のところアプリケーションのデプロイはArgoCDでのimage tagの書き換えを起点として実行されます。

なのでGitHub ActionsのTriggerを利用した実行ではなく、GKEにある該当Deploymentに対するArgoCDでのSyncオペレーションを起点として実行される仕組みが必要になります。

もう1点レポートはGCSに保存されるようになっていますが、レポートを閲覧するためにはBucketを公開設定にする必要がありセキュリティの懸念があります。キャディではCloudflareを利用しているため、Cloudflare Accessを利用することで特定のユーザーのみのアクセスに制限するなどの対策を今後実施していく必要があります。

今後のE2Eテスト自動化

Visual Regression TestのSTLCへの組込み後、Functional Regression Testの自動化を試みる予定にしています。CADDi DRAWERでは機能拡張が継続的に行われて、合わせてリグレッションテストもスケールしています。この増加に対処できるように機能テストの自動化が必須であると考えています。複雑度が高く、探索的テストが効果的なものは手動テスト、それに対して複雑度の低いテストは自動化を進める方針です。 E2Eテストでは手動と自動のハイブリッドなテストでプロダクト品質の管理を行いたいと考えています。


QAはチーム立ち上げ期で、不確実性の多い環境の中でQAエンジニアとして組織やプロダクト・サービス品質の向上に取り組んでいます。ソフトウェア品質保証、テストエンジニアリング、テスト自動化のご経験のある方、カジュアル面談もやっていますのでぜひお気軽にご連絡ください。

エンジニア向け採用サイト https://recruit.caddi.tech/

求人一覧 https://open.talentio.com/r/1/c/caddi-jp-recruit/homes/4139

参考文献 https://www.oreilly.com/library/view/software-engineering-at/9781492082781/ https://www.infoq.com/jp/news/2021/02/end-to-end-testing-microservices/ reg-viz/reg-suit: Visual Regression Testing tool