smart-test について
Python プロジェクト向けに、インポート依存関係とテストの信頼性を分析して対象テストを選ぶスキルです。素早い確認から全テストまで、段階的な pytest 実行方法を提供します。
主な機能
- 01Python のインポート依存関係のマッピング
- 02直接・間接テストの選択
- 033 段階の pytest 戦略
- 04信頼性に基づく高速テストの絞り込み
- 05YAML によるマッピングと信頼性データ
活用シーン
- 01変更した Python ファイルに対応するテストの選択
- 02コミット前の高速テスト実行
- 03不安定なテストの特定と調査計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ rysweet/ amplihack --skill smart-testインストール後、Claude Code で/smart-testを入力して読み込まれたか確認します。
同梱ファイルREADME.md
詳細
スマートテスト選択スキル
目的
コードの変更に基づいて実行するテストをインテリジェントに選択し、テストの実行を最適化します。毎回テストスイート全体を実行する代わりに、このスキルは以下を行います。
- インポート依存関係の分析により、コード変更の影響を受けるテストファイルを特定します
- フィードバックループのニーズに応じた段階的なテスト戦略を提供します
- テストの信頼性を追跡し、高速実行では安定したテストを優先します
有効になるタイミング
以下のような表現があると、自動的に読み込まれます。
- 「影響を受けるテストを実行」または「影響のあるテストを実行」
- 「スマートテスト」または「インテリジェントテスト」
- 「どのテストを実行するか」または「テスト選択」
- 「高速テスト」または「クイックテスト」
- 「変更に対するテスト」または「この PR のテスト」
主な概念
テスト階層
Tier 1:高速テスト(1 分未満)
- 直接影響を受ける単体テスト(変更されたファイルをインポートするテスト)
- 信頼性の高いテストのみ(不安定なテストを除外)
- 保存時またはコミット前に実行
- コマンド:
pytest -m "not slow and not integration" [selected_tests]
Tier 2:影響を受けるテスト(5 分未満)
- 変更の影響を受けるすべてのテスト(直接および推移的な依存関係)
- 変更されたモジュールの統合テストを含む
- コミット前または PR のドラフト作成時に実行
- コマンド:
pytest [selected_tests]
Tier 3:テストスイート全体
- テストスイート全体
- PR がレビュー可能な状態になったとき、または CI で実行
- コマンド:
pytest
インポート依存関係の分析
このスキルは Python のインポートを分析して依存関係グラフを構築します。
source_file.py
|
+-- Imported by: module_a.py, module_b.py
| |
| +-- Tested by: test_module_a.py, test_module_b.py
|
+-- Tested by: test_source_file.py (direct test)
直接テスト:パターン test_{module}.py または {module}_test.py に一致するファイル
間接テスト:変更されたファイルをインポートするモジュールをインポートするテスト
信頼性の追跡
テストの信頼性を 0.0 から 1.0 の範囲で評価します。
- 1.0:常に成功(安定)
- 0.5-0.9:ときどき失敗(調査が必要)
- < 0.5:頻繁に失敗(不安定なため、Tier 1 から除外)
信頼性は ~/.amplihack/.claude/data/test-mapping/reliability.yaml に記録されます。
使い方
変更を分析してテストコマンドを取得する
User: What tests should I run for my changes?
Claude (using smart-test):
1. Analyzes git diff or staged changes
2. Maps changed files to test dependencies
3. Returns tiered test commands
Example Output:
------------------------------------------
Smart Test Analysis
------------------------------------------
Changed Files:
- src/amplihack/core/processor.py
- src/amplihack/utils/helpers.py
Tier 1 (Fast - 45s estimated):
pytest tests/unit/test_processor.py tests/unit/test_helpers.py -v
Tier 2 (Impacted - 3m estimated):
pytest tests/unit/test_processor.py tests/unit/test_helpers.py \
tests/integration/test_pipeline.py -v
Tier 3 (Full - 12m estimated):
pytest
Recommendation: Start with Tier 1 for quick feedback.
マッピングキャッシュを構築または更新する
User: Build the test mapping for this project
Claude:
1. Scans all Python files
2. Builds import dependency graph
3. Maps source files to test files
4. Saves to .claude/data/test-mapping/code_to_tests.yaml
テストの信頼性を確認する
User: Show flaky tests
Claude:
1. Reads reliability.yaml
2. Lists tests with reliability < 0.8
3. Suggests investigation or quarantine
処理の流れ
ステップ 1:変更されたファイルを特定する
# For staged changes
git diff --cached --name-only --diff-filter=ACMR
# For all uncommitted changes
git diff --name-only --diff-filter=ACMR
# For PR changes (vs main)
git diff main...HEAD --name-only --diff-filter=ACMR
Python のソースファイルのみを対象に絞ります(マッピングの対象からテスト自体は除外します)。
ステップ 2:インポートグラフを構築する
各 Python ファイルからインポートを抽出します。
# Patterns to detect:
import module
from module import item
from package.module import item
from . import relative
from ..parent import item
双方向のマッピングを構築します。
- 順方向:ファイル -> インポート先
- 逆方向:ファイル -> インポート元
ステップ 3:テストにマッピングする
変更されたファイルごとに、次の方法でテストを検索します。
- 直接的なテストの一致:
test_{filename}.pyまたは{filename}_test.py - インポートベース:変更されたモジュールをインポートするテスト
- 推移的:変更されたモジュールをインポートするモジュールをインポートするテスト(1 レベル)
ステップ 4:信頼性フィルターを適用する
Tier 1 のみ、信頼性が 0.8 未満のテストを除外します。
ステップ 5:コマンドを生成する
適切なマーカーを指定した pytest コマンドを出力します。
# Tier 1
pytest -m "not slow and not integration" tests/a.py tests/b.py
# Tier 2
pytest tests/a.py tests/b.py tests/c.py
# Tier 3
pytest
データの保存
code_to_tests.yaml
# .claude/data/test-mapping/code_to_tests.yaml
version: 1
last_updated: "2025-11-25T10:00:00Z"
mappings:
src/amplihack/core/processor.py:
direct_tests:
- tests/unit/test_processor.py
indirect_tests:
- tests/integration/test_pipeline.py
transitive_tests:
- tests/e2e/test_full_workflow.py
src/amplihack/utils/helpers.py:
direct_tests:
- tests/unit/test_helpers.py
indirect_tests:
- tests/unit/test_processor.py # processor imports helpers
reliability.yaml
# .claude/data/test-mapping/reliability.yaml
version: 1
last_updated: "2025-11-25T10:00:00Z"
tests:
tests/unit/test_processor.py::test_basic:
passes: 98
failures: 2
reliability: 0.98
last_failure: "2025-11-20"
tests/integration/test_api.py::test_timeout:
passes: 45
failures: 15
reliability: 0.75
last_failure: "2025-11-24"
flaky_reason: "Network dependent"
ワークフローとの統合
このスキルは DEFAULT_WORKFLOW.md と統合されます。
ステップ 12:テストと pre-commit フックを実行
- pre-commit には Tier 1(高速)を使用
- 変更されたコードへの迅速なフィードバックを提供
ステップ 13:必須のローカルテスト
- コミット前に Tier 2(影響を受けるテスト)を使用
- 影響を受けるコードパスがテストされていることを確認
CI パイプライン
- ドラフト PR では Tier 2 を使用
- レビュー可能な状態の PR では Tier 3(全体)を使用
マーカーとの統合
pyproject.toml にある既存の pytest マーカーを使用します。
slow- Tier 1 から除外integration- Tier 1 から除外e2e- Tier 1 と Tier 2 から除外neo4j- 特別な環境が必要requires_docker- Docker デーモンが必要
クイックリファレンス
| シナリオ | ティア | 所要時間 | コマンドパターン |
|---|---|---|---|
| コミット前 | 1 | < 1 分 | pytest -m "not slow" [affected] |
| プッシュ前 | 2 | < 5 分 | pytest [affected + transitive] |
| ドラフト PR | 2 | < 5 分 | pytest [affected + transitive] |
| レビュー可能な PR | 3 | フル | pytest |
| CI main | 3 | フル | pytest |
哲学との整合性
徹底したシンプルさ
- シンプルなティアシステム(1、2、3)
- データベースではなく YAML に保存
- 複雑な AST 解析ではなくインポート解析
BS なしの実装
- 実際の pytest コマンド(コピーしてすぐ実行可能)
- テスト数に基づく実際の所要時間の見積もり
- プレースホルダーデータや見せかけの信頼性スコアなし
テストピラミッド
- ティア 1 ではユニットテストを優先(60%)
- ティア 2 では統合テストを追加(30%)
- ティア 3 では E2E テストを含む(10%)
補完的なスキル
- test-gap-analyzer:不足しているテストを特定します
- qa-team:E2E テストとパリティテストのシナリオを作成します(
outside-in-testingエイリアスにも対応) - tester agent:不足分を補う新しいテストを作成します
- pre-commit-diagnostic:コミット前チェックの失敗を修正します
よくあるパターン
パターン 1:すばやい反復
[Developer makes small change]
Claude: Run affected tests (Tier 1)
[45 seconds later]
Claude: 3/3 tests passed. Ready for commit.
パターン 2:プッシュ前の検証
[Developer about to push]
Claude: Run impacted tests (Tier 2)
[3 minutes later]
Claude: 12/12 tests passed including integrations.
パターン 3:不安定なテストの調査
User: Tests keep failing randomly
Claude: Checking reliability data...
Found 2 flaky tests (< 0.8 reliability):
- test_api_timeout (0.75) - Network dependent
- test_concurrent_write (0.68) - Race condition
Recommend: Quarantine these tests or fix root cause.
制限事項
- Python のインポート解析のみ
- 推移的な解析は 1 階層のみ(より深い依存関係は対象外)
- 信頼性データを得るには、最初にテスト実行によるデータの作成が必要です
- 動的インポートや文字列ベースのインポートは検出されません
使用を避ける場合
次の場合は smart-test を使用しないでください。
- テストを初めてセットアップするとき - マッピングキャッシュがまだないため、最初にテストスイート全体を実行してください
- 大規模なリファクタリング - モジュール構造が大きく変わると、マッピングが古くなります
- 設定の変更 -
pytest.ini、conftest.py、またはフィクスチャの変更は、すべてのテストに影響します - CI 環境変数の変更 - 環境に依存するテストは、すべて再実行が必要になる場合があります
- データベーススキーマのマイグレーション - データベースに触れるテストはすべて実行してください
- 不安定なテストの調査 - 正確な信頼性データを得るには、テストスイート全体を実行してください
- マージ前の最終確認 - main にマージする前に、必ずティア 3(テストスイート全体)を実行してください
目安:迷ったときは、テストスイート全体を実行してください。Smart-test は反復速度を最適化するものであり、正しさを保証するものではありません。
エラー処理とトラブルシューティング
よくある問題
問題:「変更されたファイルに対応するテストが見つかりません」
Cause: File is new or not yet mapped
Fix: Rebuild the mapping cache
User: "Rebuild test mapping cache"
問題:「インポート解析に失敗しました」
Cause: Syntax error in Python file or circular imports
Fix: 1. Check file for syntax errors: python -m py_compile file.py
2. Resolve circular imports
3. Rebuild mapping cache
問題:「信頼性データがありません」
Cause: No test runs have been recorded yet
Fix: Run full test suite once, then:
User: "Update test reliability with these results"
問題:「ティア 1 のテストに時間がかかりすぎます」
Cause: Too many tests marked as "fast" or slow tests not marked
Fix: 1. Add @pytest.mark.slow to tests > 1 second
2. Add @pytest.mark.integration to integration tests
3. Review test granularity
問題:「キャッシュが古い/誤ったテストが選択されます」
Cause: Module structure changed since last cache build
Fix: Delete cache and rebuild:
rm -rf .claude/data/test-mapping/*.yaml
User: "Rebuild test mapping cache"
復旧コマンド
# Verify test mapping is valid
python -c "import yaml; yaml.safe_load(open('.claude/data/test-mapping/code_to_tests.yaml'))"
# Check reliability data
python -c "import yaml; print(yaml.safe_load(open('.claude/data/test-mapping/reliability.yaml')))"
# Force full suite (bypass smart-test)
pytest --ignore-glob='**/test_slow_*'
# Find tests with no source mapping (orphaned tests)
find tests -name "test_*.py" -exec basename {} \; | sort > /tmp/tests.txt
キャッシュのメンテナンス
次の場合は、マッピングキャッシュを再構築してください。
- 新しいテストファイルを追加したとき
- モジュール構造が大きく変わったとき
- キャッシュが 7 日を超えたとき
手動で実行するには:「テストマッピングキャッシュを再構築」
注:すばやくフィードバックを得るため、ティア 1 から始めてください。テストに合格すれば、ほとんどのリグレッションを検出できている可能性があります。コミット/プッシュの節目が近づいたときにのみ、上位のティアに進んでください。