コードを出荷する前に、カバレッジのギャップと影響を受けるテストを把握しましょう。テスト影響分析(TIA)をCIパイプラインに追加すると、これらの分析結果をまとめたプルリクエストのコメントが自動で投稿されます。ビルドが失敗したりマージがブロックされたりする心配はありません。
以下の手順に従って、TIAをCIワークフローに組み込みます。
TIAをローカルで試してみませんか?
AIコーディングエージェントを使用している場合は、mablテスト影響スキルを使うと、同じ分析をエディターから実行できます。スキルが変更内容を説明し、選択したテストを実行します。
前提条件
パイプラインにテスト影響分析を追加する前に、次のものを用意します。
- mabl APIキー。 「Command Line Interface」タイプのAPIキーをお勧めします。APIキーの管理を参照してください。
- 分析するアプリケーションのID。 mablリソースIDを参照してください。
-
パイプラインにインストールされたmabl CLI。 下のGitHub Actionsの例のように
npm install -g @mablhq/mabl-cliでグローバルにインストールするか、npm install --save-dev @mablhq/mabl-cliで開発依存関係としてインストールします。開発依存関係としてインストールした場合は、mablの代わりにnpx @mablhq/mabl-cliでコマンドを実行します。
GitHub Actionsのワークフローにテスト影響分析を追加する
このワークフローは、プルリクエストごとに分析を実行し、プルリクエストのタイトルと本文から変更の説明を作成して、結果をプルリクエストのコメントとして投稿します。ワークフローはGitHub CLI(gh)を使用します。GitHubホステッドランナーにはghがプリインストールされています。セルフホステッドランナーを使用する場合は、先にランナーにghをインストールしてください。
-
GitHubリポジトリで、mabl APIキーを
MABL_API_KEYという名前の暗号化されたシークレットとして保存し、アプリケーションIDをMABL_APPLICATION_IDという名前のリポジトリ変数として保存します。 -
.github/workflowsにtest-impact.ymlなどのワークフローファイルを追加し、次の内容を記述します。name: Test impact analysis on: pull_request: types: [opened, synchronize, reopened, edited] jobs: test-impact: runs-on: ubuntu-latest if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' permissions: contents: read pull-requests: write steps: - name: Analyze test impact continue-on-error: true env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} MABL_API_KEY: ${{ secrets.MABL_API_KEY }} PR_URL: ${{ github.event.pull_request.html_url }} APPLICATION_ID: ${{ vars.MABL_APPLICATION_ID }} run: | npm install -g @mablhq/mabl-cli mabl auth activate-key "$MABL_API_KEY" { echo "Title: $(gh pr view "$PR_URL" --json title --jq .title)" echo gh pr view "$PR_URL" --json body --jq .body } > change.md mabl tests impact \ --application-id "$APPLICATION_ID" \ --change-description-file change.md \ --output json > impact.json jq -r ' "## Test impact analysis (advisory)\n\nImpacted: \(.tests | length) · Coverage gaps: \(.coverage_gaps | length)\n" + (if (.tests | length) > 0 then "\n**Impacted**\n" + ([.tests[] | "- " + .test_name + " — " + .context] | join("\n")) else "" end) + (if (.coverage_gaps | length) > 0 then "\n\n**Coverage gaps**\n" + ([.coverage_gaps[] | "- " + .] | join("\n")) else "" end) ' impact.json > impact.md gh pr comment "$PR_URL" --body-file impact.md -
プルリクエストを開くか、既存のプルリクエストにプッシュします。ジョブが完了すると、分析結果がプルリクエストのコメントとして表示されます。
ワークフローをそのまま追加した場合の動作は次のとおりです。いずれもパイプラインに合わせて変更できます。
-
プルリクエストが編集されると再実行されます。 GitHubは既定で、プルリクエストが開かれたとき、再度開かれたとき、新しいコミットが追加されたときにのみプルリクエストのワークフローを実行します。このワークフローはプルリクエストのタイトルと本文から変更の説明を作成するため、
editedも監視します。これにより、誰かが説明を更新すると分析が再実行され、コメントに最新の内容が反映されます。 -
分析を実行できなくても、ジョブは失敗しません。 分析ステップは、分析の結果によって失敗することはありません。失敗するのは、APIキーが機能しないなど、何らかの問題が発生した場合だけです。
continue-on-error: trueにより、そうしたエラーが発生してもジョブは成功のままになります。分析を実行できなかったときにジョブを失敗として表示したい場合は、この行を削除してください。 -
フォークとDependabotからのプルリクエストはスキップされます。 これらのプルリクエストはリポジトリのシークレットを読み取れないため、mabl APIキーを使用できません。ジョブの
if:条件により、これらのプルリクエストは失敗させずにスキップします。
チームに通知する
次のステップを、同じジョブの「Analyze test impact」の後に2つ目のステップとして追加します。このステップは分析を再実行せず、前のステップで保存したimpact.jsonを読み取ります。そのため、1回の分析結果をプルリクエストのコメントとチームへの通知の両方に使用できます。
- name: Notify the team
continue-on-error: true
env:
WEBHOOK_URL: ${{ secrets.TEAM_WEBHOOK_URL }}
run: |
summary=$(jq -r '
"Test impact: \(.tests | length) impacted tests, \(.coverage_gaps | length) coverage gaps"
+ ([.tests[0:3][] | "\n- " + .test_name] | add // "")' impact.json)
jq -n --arg text "$summary" '{text: $text}' \
| curl -sS "$WEBHOOK_URL" -H 'Content-Type: application/json' -d @-
SlackのIncoming WebhookとMicrosoft TeamsのIncoming Webhookは、どちらもtextフィールドを含むJSON本文を受け付けます。TeamsのワークフローWebhookは異なるペイロードを想定しているため、設定する前にWebhookが求める形式を確認してください。
他のCIツールから分析を実行する
mabl CLIを実行できるCIジョブであれば、APIキーで認証してからmabl tests impactを実行します。
mabl auth activate-key "$MABL_API_KEY"
mabl tests impact \
--application-id {application-id} \
--change-description-file change.md \
--output markdown
説明をファイルに書き出しておくと、複数行のテキストをシェルの引用符で囲む必要がなくなります。1行で済む説明であれば、代わりに--change-descriptionでインラインに渡せます。
そのまま投稿できるレポートが必要な場合は--output markdownを、後続のステップで結果を読み取る場合は--output jsonを使用します。すべてのオプションについては、mabl CLIコマンドリファレンスのmabl tests impactを参照してください。
--timeoutは既定値のままにしてください。タイムアウトを短くすると、完了間近の分析が打ち切られる可能性があります。分析自体が約5分で停止するため、長くしても効果はありません。
終了コード
分析結果が返ってくれば、影響を受けるテストが1つも見つからなかった場合も含めて、コマンドは0で終了します。0以外で終了するのは、呼び出し自体が失敗した場合だけです。たとえば、APIキーで認証できない、アプリケーションIDを解決できない、タイムアウトした、アカウントで生成AI機能が利用できない、といった場合です。コマンドが403で失敗する場合は、トラブルシューティングを参照してください。
終了コードは見つかったテストの数に左右されないため、このコマンドで件数に基づいてマージを制御することはできません。これは意図的な設計です。結果はレビュー担当者のための情報であり、合否の判定ではありません。
結果の例
--output markdownを指定すると、コマンドはそのまま投稿できるレポートを出力します。
## Test impact analysis (advisory)
Impacted: 2 · Coverage gaps: 1
**Impacted (2)**
- [Checkout postal code](https://app.mabl.com/workspaces/{workspace-id}/train/tests/{test-id}/current) - _validates_ · Asserts the inline error text while typing a postal code at checkout.
- [Account settings address edit](https://app.mabl.com/workspaces/{workspace-id}/train/tests/{test-id}/current) - Reaches the same validator when a saved address is edited.
**Coverage gaps (1)** — no credible coverage found for these areas; inconclusive, not proof they are untested
- No test covers the saved-payment expiry field.
**Summary** — the analysis agent's own account
> Searched checkout and account settings; the change reaches both.
Impacted: … · Coverage gaps: …の行の後には、さらに次の2行が表示されることがあります。
-
more_may_existがtrueの場合:「More relevant tests likely exist beyond the N returned; the list hit the result ceiling.」(返されたN件以外にも関連するテストが存在する可能性が高く、一覧が結果の上限に達しました)と、それに続く注記。 - 実行履歴を完全に解決できなかった場合:「Run history could not be fully resolved for some tests; treat missing run details as unknown.」(一部のテストの実行履歴を完全に解決できませんでした。欠けている実行の詳細は不明として扱ってください)
変更の説明を書く
コード変更を読み取るmablテスト影響スキルとは異なり、CIでのTIAは差分を参照できません。TIAが把握できるのは変更の説明に書かれている内容だけで、GitHub Actionsのワークフローではプルリクエストのタイトルと本文がそれに当たります。TIAは、そのテキストをステップの説明、アサーション、ページ名など、テストの内容と照合します。説明がテストでの製品の表現に近いほど、適切なテストを多く見つけられます。
CIでのTIAを最大限に活用するには、次のガイドラインに従ってください。
- プルリクエストから始めます。 人間のレビュー担当者に向けて書かれたタイトルと説明は、それだけで良い変更の説明の大部分を占めています。上のGitHub Actionsの例では、プルリクエストのタイトルと本文をそのまま使用しています。
-
実装の詳細ではなく、製品の言葉で変更を説明します。 mablのテストはファイルやクラスについて記述しないため、「
FieldGroup.tsxのバリデーションフックをメモ化した」のような説明では何も見つかりません。「バリデーションがフォーカスを外したときではなくキー入力ごとに実行されるようになり、ユーザーが入力している間にエラーテキストが表示される」のような説明のほうが適しています。 - 共有コードの場合は、変更が影響するユーザー向けの領域をすべて挙げます。 たとえば、あるバリデーターがチェックアウトと、顧客が保存済みの住所を編集する画面の両方で使われている場合は、説明にその両方を記載します。
コードのパスと製品の領域を対応付ける小さなマップをパイプラインに用意しておくと、差分だけでは得られない製品の言葉を補えます。
apps/web/src/checkout/** = checkout and payment
apps/web/src/account/** = account settings and saved payment methods
apps/web/src/search/** = product search and filtering
packages/forms/** = form validation
たとえば、packages/forms/**とapps/web/src/checkout/**に触れる変更では、説明に「Product areas touched: form validation, checkout and payment.」のような行が追加されます。
トラブルシューティング
分析が403で失敗する
アカウントで生成AI機能が利用できないか、APIキーに分析に必要なスコープがありません。別のワークスペースのキーや古いキーには、そのスコープがない場合があります。そうしたキーを使用したリクエストは、開始時ではなく途中で失敗し、再試行しても解決しません。新しいCommand Line Interface APIキーを作成して使用してください。