タスク完了時にテストを自動で走らせる
「完了です」を信じない。テストが通るまで完了にさせない仕組み

目次

1.     はじめに
2.     postTaskExecutionとは
3.     実践:タスク完了時にテストを自動実行する
4.     IaC版:cfn-nagによるセキュリティチェック
5.     使い分けの指針:postTaskExecution vs userTriggered
6.     複数のrunCommandを組み合わせる
7.     まとめ

はじめに

前回の記事「Kiro Hooksで命名規約の逸脱を即座に検出する」では、ファイルが作成された瞬間にエージェントが規約違反を検出し、リネームまで自動でやる仕組みを構築しました。
今回はpostTaskExecution Hookを使って、「Specのタスクが完了した瞬間にテストを強制実行する」仕組みを作ります。テストが通るまで先に進めない — そういうガードレールになります。

postTaskExecutionとは

Specタスクのライフサイクル

Kiro Specsでは、タスクにステータスがあります。

not_started → in_progress → completed (この瞬間に Hook が発火)

postTaskExecutionは、タスクのステータスがcompletedに変わった直後に発火するイベントです。「実装が終わった」とエージェントが判断した瞬間、自動的にチェックが走ります。

前回(命名規約チェック)との違い

観点

命名規約チェック(fileCreated)

品質ゲート(postTaskExecution)

発火タイミング

ファイルが新規作成された時

Specタスクが完了した時

対象

個別のファイル

タスク全体の成果物

then.type

askAgent(判断が必要)

runCommand(コマンド実行)

ユースケース

命名規約チェック

テスト実行

粒度

ファイル単位

タスク単位

runCommand を使う理由

前回はaskAgentを使いました。命名規約の判断はエージェントに「考えさせる」必要があったからです。ファイル名がルールに合致するかはコンテキスト依存で、機械的なパターンマッチだけでは判定しきれません。
今回はrunCommandを使います。テスト実行に判断は不要です。mvn testを走らせて、通るか通らないか。結果は0か1です。

type

向いている用途

今回

クレジット消費

askAgent

判断が必要(命名チェック、コードレビュー)

あり(LLMを呼び出す)

runCommand

機械的な実行(テスト、リント、ビルド)

なし(ローカル実行のみ)

runCommandはローカルでコマンドを実行するだけなので、クレジットを消費しません。Hookを10個付けてもテストが全部通ればコスト増はゼロです。一方askAgentは毎回LLMを呼び出すため、発火するたびにクレジットが消費されます。
ただし、runCommandの出力結果をもとにエージェントが修正を試みる場合(テスト失敗→自動修正ループ)、その修正作業ではクレジットが消費されます。コマンド実行自体は無料でも、失敗が頻発すると修正ループでクレジットが消費される点は意識しておいてください。
なお、Kiro IDE版にはエージェントの最大試行回数を設定する機能はありません(Kiro CLIの/goal --maxとは別)。テスト失敗→修正→再テストのループが収束しない場合は、Supervisedモードに切り替えるか、チャットで中断してください。実際には2〜3回修正を試みて解決しない場合、エージェントは自発的にユーザーへ報告する傾向があります。
runCommandの出力結果はエージェントに自動的に返されます。テストが失敗すれば失敗内容がそのまま伝わるため、エージェントは自力で修正を試みます。

実践:タスク完了時にテストを自動実行する

Hook定義の作成

.kiro/hooks/run-tests-after-task.kiro.hook に以下を配置します。

{

  "name": "Run Tests After Task",

  "version": "1.0.0",

  "description": "Specタスク完了時にテストを自動実行し、失敗があればエージェントに通知する",

  "when": {

    "type": "postTaskExecution"

  },

  "then": {

    "type": "runCommand",

    "command": "mvn test -q"

  }

定義はこれだけです。when.typeがpostTaskExecutionなので、Specタスクが完了するたびにmvn test -qが走ります。
-q(quiet)オプションをつけているのは、テスト成功時の大量ログをチャットに流さないためです。失敗時はエラー内容が表示されるので問題ありません。
注意: postTaskExecutionにはファイルパターン(patterns)の指定は不要です。タスクレベルのイベントなので、ファイルではなくタスク全体に対して発火します。

Maven Wrapperを使う場合

実際のプロジェクトでは、グローバルのmvnコマンドではなくMaven Wrapper(mvnw / mvnw.cmd)を使うケースが多いです。Kiroのターミナル環境でPATHにmvnが通っていないとcommand not foundになります。
プロジェクトにMaven Wrapperが含まれている場合は、コマンドを以下のように変更してください。

{

"then": {

"type": "runCommand",

"command": "./mvnw test -q"

}

}

Windows環境の場合は mvnw.cmd test -q です。Gradle Wrapperの場合も同様に ./gradlew test としてください。Hookのコマンドはプロジェクトルートから実行されるため、Wrapperのパスは相対パスで指定できます。

動作の流れ(テスト成功時)

1. エージェントがSpecタスクの実装を完了
   ↓
2. タスクステータスが「completed」に変更
   ↓
3. postTaskExecution Hook が発火
   ↓
4. mvn test -q が実行される
   ↓
5. テスト全件合格 → 「BUILD SUCCESS」がエージェントに返る
   ↓
6. エージェントは次のタスクへ進む


成功した場合はスムーズに次のタスクに移ります。テスト実行のオーバーヘッドはありますが、品質が保証されるなら許容範囲です。
筆者のFileUploaderプロジェクト(jqwikプロパティテスト27件)で計測したところ、テスト実行時間は約7秒でした。タスク完了のたびに7秒待つ程度なので、実用上の問題にはなりません。

動作の流れ(テスト失敗時)

1. エージェントがSpecタスクの実装を完了
   ↓
2. タスクステータスが「completed」に変更
   ↓
3. postTaskExecution Hook が発火
   ↓
4. mvn test -q が実行される
   ↓
5. テスト失敗 → 失敗内容がエージェントに返る
   例: "FileUploadServiceTest.testUploadEmptyFile: expected 400 but was 500"
   ↓
6. エージェントがエラーを分析し、コードを修正
   ↓
7. エージェントが再度テストを実行し、合格を確認


ポイント: テスト失敗の結果はrunCommandの出力としてエージェントに戻ります。エージェントは何が壊れたかを把握できるため、自動的に修正を試みます。人間が「テスト通らないよ」と教える必要はありません。
「完了です」→「テスト落ちてます」→「修正しました」が全部自動で回ります。人間が介入する必要がないのがこの仕組みの利点です。

IaC版:cfn-nagによるセキュリティチェック

同じ仕組みはインフラコードにも応用できます。CloudFormationテンプレートのセキュリティスキャンを自動実行する例です。

{

"name": "Run cfn-nag After Task",

"version": "1.0.0",

"description": "Specタスク完了時にcfn-nagでセキュリティスキャンを実行",

"when": {

"type": "postTaskExecution"

},

"then": {

"type": "runCommand",

"command": "cfn_nag_scan --input-path templates/"

}

}

cfn-nagはCloudFormationテンプレートのセキュリティ問題を検出するツールです。S3バケットのパブリックアクセス設定、セキュリティグループの0.0.0.0/0許可、暗号化未設定など、よくある脆弱パターンを指摘してくれます。
テスト実行と同じ考え方です。エージェントが「インフラ定義を書きました、完了です」と言った瞬間にセキュリティスキャンが走ります。脆弱性があれば修正を試みるので、人間がレビューで指摘する前に解決されていることが多いです。
「実践編:ステアリングファイルとKiro Powerで実現するIaC品質管理」で構築したIaC Validator Power(Kiro Powerによるセキュリティ検証)と組み合わせれば、さらに強固なチェックが可能です。Powerは「エージェントの能力拡張」、Hookは「自動実行の仕組み」— 役割が異なるので併用が効果的です。

使い分けの指針:postTaskExecution vs userTriggered

postTaskExecutionはSpecsの各タスク(チェックボックス1つ)が完了するたびに発火します。タスクが10個あれば10回テストが走る。これが適切かどうかは、Specのタスク構成とプロジェクトの状況によります

Specのタスク構成パターン

パターンA: 機能単位で実装+テストをセットにする

- [ ] Task 1: FileUploadServiceの実装とテスト
- [ ] Task 2: FileUploadControllerの実装とテスト
- [ ] Task 3: エラーハンドリングの実装とテスト

各タスクが「実装+そのテスト」をワンセットで含みます。Kiroが自動生成するSpecは、たいていこのパターンになります。

パターンB: 実装とテストを分離する

- [ ] Task 1: FileUploadServiceの実装
- [ ] Task 2: FileUploadControllerの実装
- [ ] Task 3: エラーハンドリングの実装
- [ ] Task 4: 全テストの作成
Task 1〜3完了時点ではテストが存在しない。postTaskExecutionで走らせても「テストが0件」で素通りするか、ビルドエラーになる。

パターンC: TDD的にテスト先行で書く

- [ ] Task 1: FileUploadServiceのテスト作成
- [ ] Task 2: FileUploadServiceの実装
- [ ] Task 3: FileUploadControllerのテスト作成
- [ ] Task 4: FileUploadControllerの実装
Task 1完了時点ではテストだけあって実装がない。テストは当然失敗する。実装が来るまで失敗し続けるのは想定通りであり、ノイズになる。

判断フロー

すでにテストコードがある?
  ├── YES → postTaskExecution(毎タスクで回帰テスト)
  └── NO  → 各タスクが「実装+テスト」セットになっている?(パターンA)
              ├── YES → postTaskExecution(タスク単位で検証可能)
              └── NO  → userTriggered(全部書き終えてから実行)

両方のHookを.kiro/hooks/に置いておき、プロジェクトのフェーズやSpecの構成に応じて使い分けるのが現実的です。

複数のrunCommandを組み合わせる

実際のプロジェクトでは、テストだけでなくリント・ビルド・静的解析もまとめて走らせたいケースがあります。Hookは複数定義できるので、それぞれ個別に作成できます。

.kiro/hooks/
├── run-tests-after-task.kiro.hook         # テスト実行
├── run-lint-after-task.kiro.hook          # リント実行
├── run-cfn-nag-after-task.kiro.hook       # セキュリティスキャン
└── naming-convention-check.kiro.hook      # 命名規約チェック(前回)

同じpostTaskExecutionイベントに複数のHookを紐づけると、すべてが実行されます。1つでも失敗すればエージェントにフィードバックが返るため、品質ゲートとして機能します。

実行順序を制御したい場合

複数のHookファイルを定義した場合、実行順序は保証されません。「リントを通してからテストを走らせたい」のように順序が重要な場合は、1つのHookにコマンドを && で連結します。

{

"name": "Quality Gate - Lint then Test",

"version": "1.0.0",

"when": { "type": "postTaskExecution" },

"then": {

"type": "runCommand",

"command": "mvn checkstyle:check -q && mvn test -q"

}

}

&& で繋ぐと、前のコマンドが失敗した時点で後続は実行されません。軽いチェック(リント)を先に置くことで、コードスタイルが壊れている段階でテスト実行を省けます。
より複雑な制御(条件分岐、ログ集約)が必要な場合は、シェルスクリプトにまとめて "command": "./scripts/quality-gate.sh" とするのも有効です。

まとめ

今回構築したもの

•    ✅ postTaskExecution Hook(タスク完了時テスト自動実行)
•    ✅ runCommandによる品質ゲート(テスト・リント・セキュリティスキャン)
•    ✅ 「テストが通るまで完了にさせない」仕組み

Hook

イベント

then.type

役割

命名規約チェック(前回)

fileCreated

askAgent

コード構造の品質

テスト自動実行(今回)

postTaskExecution

runCommand

動作の品質

Steeringで「こう書いてね」、Hooksで「守ってなかったら止める」。前回はファイル単位の品質(命名)、今回はタスク単位の品質(テスト)。レイヤーの異なるガードレールを重ねることで、品質の穴を塞いでいきます。

次回予告

2026年6月にAWS Security AgentがKiro Powerに追加されました。次回はAWS Security AgentをKiroのSpecsと組み合わせて、設計段階のセキュリティチェックを行います。

参考リンク