Test · 設定
Test ファミリはオプトインで、既定では無効です。cargo llvm-cov、pytest --cov、nyc、scoverage のどれかが出力した lcov.info がある(または用意するつもりがある)なら、有効にしてください。heal 自身がテストを実行することはありません。テストスイートを実際に動かさないと分からないもの(不安定なテスト、ミューテーションスコア、実行時間の推移)は扱いません。
各メトリクスが何を見つけるかは Test › メトリクス を、スキルについては Test › スキル を参照してください。
すぐに有効にする
Section titled “すぐに有効にする”[features.test]enabled = true
[features.test.coverage]enabled = true既定値は、Rust / TypeScript / JavaScript / Python / Go / Scala のテストの慣習に合わせてあります。lcov.info も、よく使われる 4 か所を探します。ほとんどのプロジェクトでは、何も上書きする必要はありません。
lcov.info がまだないなら、セットアップ用スキルの tests の手順を実行してください。使っている技術スタックを調べてカバレッジのリポータを設定します。各手順の前には確認を求めます。Claude Code で次を実行します。
/heal:setup tests詳しくは Test › スキル を参照してください。
[features.test]
Section titled “[features.test]”[features.test]enabled = false # ファミリ全体のスイッチtest_paths = [ "tests/**", "**/*_test.rs", "**/*.test.ts", "**/*.test.tsx", "**/*.test.js", "**/*.test.jsx", "**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.spec.jsx", "**/__tests__/**", "**/*_test.go", "**/test_*.py", "**/*_test.py", "**/*Test.scala", "**/*Spec.scala",]enabled(既定false)— ファミリ全体のスイッチ。false のあいだ、テストのオブザーバはどれも何もしません。test_paths(既定は上の言語ごとの慣習)— どのソースファイルがテストかを示す、gitignore 形式のグロブ。skip_ratioのオブザーバはこのファイルをたどります。主なファイルがこれに一致する Finding には、is_test_file = trueも付きます。
test_paths が空のときは、同じ慣習をカバーする組み込みの判定を使います。
グロブは .gitignore と同じように、置き場所が固定されます。既定の tests/** は、プロジェクトのルートにある tests/ ディレクトリにしか一致しません。crates/<name>/tests/ のようにテストのディレクトリが入れ子になった workspace では、**/tests/** を使ってください。test_paths を自分で設定すると、Semantic (Jev) のタスクもそのグロブだけを使います。既定のままなら、組み込みの判定も加わり、test/ という名前のディレクトリはすべてテストとして扱われます。
is_test_file フラグ
Section titled “is_test_file フラグ”[features.test] を有効にすると、すべての Finding に is_test_file: bool のフラグが付きます。スキルはこのフラグで絞り込み、テスト側と本番側の Severity を分けて読みます。/heal:tests はテストの Finding に、/heal:refactor は本番コードの Finding に集中します。
フラグが false のときは JSON の出力から省くので、test ファミリを有効にしていないプロジェクトの latest.json は、以前とバイト単位で同じです。
[features.test.coverage]
Section titled “[features.test.coverage]”[features.test.coverage]enabled = falselcov_paths = [ "lcov.info", "coverage/lcov.info", "target/llvm-cov/lcov.info", "coverage/lcov-report/lcov.info",]enabled(既定false)— カバレッジの部分だけのスイッチ。リポータの設定はまだだが、is_test_fileのタグ付けとskip_ratioは使いたいときは、[features.test]をオンにして[features.test.coverage]をオフにしておきます。lcov_paths— 順に探す、プロジェクトからの相対パス。存在するファイルはすべて読んでマージするので、多言語のモノレポでもパッケージごとのlcov.infoを並べれば、どれも集計に入ります。2 つのファイルが同じソースファイルを扱っているときは、カウンタの大きいほうを取ります(1 つの lcov ファイルの中で記録が重複したときと同じ扱いです)。見つからないファイルは黙って飛ばし、起動時の警告も出しません。存在するのに読めないファイルは、標準エラーに警告を出します。リポータがパッケージのルートからの相対パスで書いたSF:のパス(vitest、jest、scoverage)は、その lcov ファイルが置かれたディレクトリを基準に解決します。そのため、マージ用のスクリプトがなくてもパッケージごとのファイルがそのまま使えます。post_commit_refresh(既定は未設定)— post-commit フックが、コミットのたびにリポータを実行し直すためにバックグラウンドで起動するシェルコマンド(任意)。プロセスは切り離され、出力も捨てるので、コミットの流れを待たせません。/heal:setup testsが提案するのと同じコマンド(cargo llvm-cov --workspace --lcov --output-path lcov.info --locked --ignore-run-fail、pytest --cov=...など)を設定すれば、次のheal statusが新しいlcov.infoを読めます。[features.test]か[features.test.coverage]がオフのときは、黙って実行しません。
heal が読むのは、CI や手元のリポータが出力したものです。既定で探す場所は、次のリポータに対応しています。
| リポータ | 書き出すパス |
|---|---|
cargo llvm-cov --lcov |
target/llvm-cov/lcov.info |
pytest --cov --cov-report=lcov |
coverage/lcov.info |
nyc --reporter=lcov |
coverage/lcov-report/lcov.info |
scoverage(Scala) |
設定による。必要なら lcov.info へのシンボリックリンクを置く |
lcov の読み込みは寛容に作っています。知らない種類の記録があっても止まらず、リポータが集計のフィールドを省いた場合も行ごとの記録から合計を求めるので、たいていのリポータの方言はそのまま使えます。
Calibration
Section titled “Calibration”test ファミリを有効にした状態で heal calibrate --force を実行すると、.heal/calibration.toml に 2 つの節が加わります。
[calibration.coverage_pct]# heal は値を反転して(100 - coverage_pct)保存する。ほかのメトリクスと# 同じ「value >= p95 なら Critical」の段階をそのまま使えるようにするため。# 最も悪いものが Critical になる点は変わらない。p50 = 30.0 # カバレッジ 70%p75 = 50.0 # カバレッジ 50%p90 = 70.0 # カバレッジ 30%p95 = 85.0 # カバレッジ 15%floor_critical = 95.0 # カバレッジ 5% 以下 → パーセンタイルにかかわらず Criticalfloor_ok = 25.0 # カバレッジ 75% 超 → パーセンタイルにかかわらず Ok
[calibration.skip_ratio]p50 = 0.0p75 = 1.0p90 = 5.0p95 = 10.0floor_critical = 20.0 # skip が 20% 超 → Criticalfloor_ok = 0.5 # skip が 0.5% 未満 → Okこれは、heal calibrate --force を実行するまで heal が使う、文献に基づく代わりの値です。フロアは calibration をやり直しても消えないように、ここではなく config.toml に書きます。
[metrics.coverage_pct]floor_critical = 90.0 # 「カバレッジ 10% 以下なら Critical」に厳しくする
[metrics.skip_ratio]floor_ok = 0.0 # skip されたテストが 1 つでもあれば表示する(coverage_pct の上書きは、反転した値に対して効きます。floor_critical = 90.0 は「行カバレッジが 10% 以下」という意味で、「90% 以下」ではありません。)
post-commit の通知
Section titled “post-commit の通知”[features.test.coverage] がオンのとき、post-commit フックの通知には、字下げした 2 行目が加わります。
heal: recorded · 3 critical, 7 high · heal status · 2 uncovered hotspotこの数は、High か Critical の coverage_pct の Finding のうち、hotspot=true も付いているものの件数です。カバレッジの機能がオフのときは、この行は出ません。
ほかの節と同じく、[features.test] と [features.test.coverage] も、定義されていないキーがあるとエラーにします。
[features.test]test_path = ["tests/**"] # ✘ 知らない項目 — heal はここでエラーを出す # (正しくは複数形の `test_paths`)