コンテンツにスキップ

Test · スキル

オプトインの Test ファミリでは、heal の Claude Code プラグインの 2 つのスキルを使います。ファミリを有効にしてカバレッジのリポータを設定する /heal:setup の tests の手順と、テストそのものに手を入れる /heal:tests です。プラグインの入れ方は Code › スキル を参照してください。

/heal:setup tests — ファミリの有効化と lcov の準備

Section titled “/heal:setup tests — ファミリの有効化と lcov の準備”

リポジトリに合わせた test_paths と lcov_paths で [features.test] をオンにします。そのうえで使っている言語を判定し、heal が読む場所に lcov.info が出力されるよう、カバレッジのリポータを設定します。

スタック リポータ
Rust cargo llvm-cov --lcov --output-path lcov.info
Python pytest --cov=src --cov-report=lcov(pytest-cov)
JS / TS nyc --reporter=lcov mocha / vitest --coverage --coverage.reporter=lcov
Go go test -coverprofile=coverage.out と gcov2lcov
Scala scoverage プラグインと lcov のリポータ
混在 スタックごとに 1 つずつのリポータ

リポータの導入、.heal/config.toml の編集、リポータの実行のどれも、行う前に確認を求めます。[features.test.coverage].post_commit_refresh も設定でき、そうすると post-commit フックがコミットのたびに lcov.info を新しくします。CI の変更は、コピーして使える提案として表示するだけで、自分では適用しません。カバレッジがオンなのに lcov ファイルがないと、heal doctor が test の項目を todo と報告するので、/heal:setup はこの手順をもう一度提案します。

/heal:tests — テストの見直しと改善

Section titled “/heal:tests — テストの見直しと改善”

/heal:refactor のテスト版です。テストの Finding を読んで変更を提案し、承認されたものだけを適用します。1 提案 1 コミットで、コミットの前には毎回テストスイートが通ることを確かめます。push や pull request の作成はしません。

  1. 診断: heal status --all --feature test --json を読み、フラグの立った各ソースファイルを、そのテストと一緒に読みます。テストのないコードは、テストピラミッドに沿って、どの層でテストすべきかで分けます。純粋なロジックには単体テスト、ほかのモジュールを取りまとめるコードには小さな結合テスト、I/O の境界にあるコードには薄い契約テストです。skip は、その理由(環境、遅い、壊れている、保留中)で分けます。
  2. 提案: まず、テストスイートの形を短く読み解きます(ピラミッドが逆になっている、テストのない Hotspot がある、skip がたまっている、ソースについていけていないテストがある、など)。続けて、優先度の高い Finding から順に、番号付きの提案を並べます。テストの提案には、どんなケースを確かめるかが書かれます。
  3. 選択: 適用する提案を、自分で選びます。
  4. 適用: 1 提案 1 コミットで適用します。テストスイートが通ることが条件で、カバレッジが変わるときはリポータも実行し直します。
  5. 報告: 何が変わり、何が残っているかを伝えます。

Finding ごとの提案の内容は次のとおりです。

メトリクス よくある提案
coverage_pct 仕様が文書化された純粋なロジックには単体テスト。取りまとめや I/O のコードには結合テストか契約テスト。
change_coupling.drift テストを、ソースの今の約束ごとに合わせて直す。振る舞いがほかへ移っていれば書き直す。
skip_ratio skip の理由がなくなったテストを再び有効にする。機能ごとなくなったテストは消す。それ以外は質問する。

同じ問題がいくつものファイルで繰り返されているときは、テストスイート全体の変更も提案します。逆になったピラミッドの立て直し、テストスイートの分割、共通のフィクスチャの切り出し、テストファイルの廃止などです。意図した振る舞いがどこにも書かれていないコードは、質問として投げかけます。そこでテストを書いても、推測を固めてしまうだけだからです。

しないこと: テストを通すためにアサーションを弱めることはしません。skip_ratio を下げるために不安定なテストを skip にすることも、実行していないテストをコミットすることもしません。Finding を消すためにカバレッジのしきい値を下げたり、ファミリを無効にしたりもしません。

Semantic (Jev) を有効にしていると、何も確かめていないテストを消すこともできます。対象は、test_value の Finding で高い確信度で delete と判定されたものです。1 コミットに 1 つずつ、テストスイートが通り、カバレッジが下がらない場合に限ります(そのテストが自分のモックしか確かめていないなら、カバレッジが下がっても消します)。重複したテストをまとめたり消したり(test_duplicate)、ただの値をモックにしている箇所を本物の値に置き換えたり(mock_scope)もします。各コミットの後には heal semantic ask --task verify_tests --diff HEAD~1..HEAD を実行し、新しいテストが自分のモックしか確かめていなければ、そのコミットを取り消します。

引数: パスを渡すとその下の Finding に、Finding の id を渡すとその Finding に絞ります。plan を渡すと、提案までで止まります。

呼び出しに使える言い方の例: 「テストの状態を見直して」「テストの Finding を直して」「heal が指摘したテストを足して」「役に立っていないテストを消して」「/heal:tests」。