sc-test について
sc-test は、テスト実行とカバレッジ改善のためのスキルです。テストの不足箇所を調べて段階的に補う開発作業を支援し、優先順位の確認、プロジェクトの規約に沿ったテスト生成、結果の再検証を行います。
主な機能
- 01各種テストの実行
- 02カバレッジレポートの生成
- 03カバレッジ不足箇所の特定と順位付け
- 04プロジェクトの規約に沿ったテスト生成
- 05テスト再実行とカバレッジ比較
活用シーン
- 01カバレッジが低いファイルの特定
- 02優先順位に沿った単体・統合テストの追加
- 03新規テストの検証とカバレッジ変化の確認
MCP 対応
PAL MCP のツールでテスト失敗の調査、テスト品質のレビュー、フレームワーク文書の検索ができます。Rube MCP はレポート連携の検索、通知、結果処理に利用できます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tony363/ superclaude --skill sc-testインストール後、Claude Code で/sc-testを入力して読み込まれたか確認します。
同梱ファイルIMPORT_NOTES.md
詳細
テストとカバレッジのスキル
カバレッジ分析、対話形式でのギャップ特定、テスト生成、反復的なカバレッジ改善を伴うテスト実行です。
クイックスタート
# Run all tests
/sc:test
# Unit tests with coverage
/sc:test src/components --type unit --coverage
# Coverage gap analysis - identify untested code
/sc:test --gap-analysis --target 80
# Generate missing tests to reach target coverage
/sc:test --generate --target 80 --module src/services
# Watch mode with auto-fix
/sc:test --watch --fix
# Fix existing failures before adding coverage
/sc:test --fix-first --generate --target 80
# Web search for testing guidance (uses Rube MCP's LINKUP_SEARCH)
/sc:test --linkup --query "pytest asyncio best practices"
基本方針:早めに、頻繁に確認する
このスキルでは、判断が必要な場面で積極的に AskUserQuestion を使用します。 テストカバレッジには、速度と網羅性の間にトレードオフがあります。ユーザーがどの範囲をカバーしたいかを推測せず、優先事項を確認してください。
- テストを作成する前に、優先するモジュールを確認する
- ギャップが大きい場合、まずどこに注力するかを確認する
- ソースコードにバグがありそうな場合、修正するかテストだけを行うかを事前に確認する
- カバレッジの実行後に、反復を続けるか終了するかを確認する
動作フロー
- 検出 - ランナーのパターンを使ってテストを分類する
- 設定 - テスト環境とパラメーターを設定する
- 実行 - リアルタイムで進捗を追跡しながらテストを実行する
- 分析 - カバレッジレポートと診断情報を生成する
- 優先事項の確認 - 対話形式のチェックポイントで、取り組む対象をユーザーに確認する
- パターンの調査 - テストインフラストラクチャと既存の規約を読み込む
- 生成 - プロジェクトの規約に沿って不足しているテストを作成する
- 検証 - 新しいテストを実行し、失敗を修正して、リンターを実行する
- カバレッジの確認 - カバレッジを再実行し、実行前後を比較する
- 反復 - 続行、終了、または対象の変更についてユーザーに確認する
- 報告 - 推奨事項と品質指標を提示する
フラグ
| フラグ | 型 | デフォルト | 説明 |
|---|---|---|---|
--type | 文字列 | all | unit、integration、e2e、all |
--coverage | bool | false | カバレッジレポートを生成する |
--watch | bool | false | 継続的な監視モード |
--fix | bool | false | 簡単な失敗を自動修正する |
--gap-analysis | bool | false | テストを生成せずにカバレッジのギャップを特定する |
--generate | bool | false | 目標に到達するため、不足しているテストを生成する |
--target | int | 80 | カバレッジの目標パーセンテージ |
--module | 文字列 | - | 特定のモジュールに対象範囲を限定する |
--fix-first | bool | false | 新しいテストを生成する前に既存の失敗を修正する |
--dry-run | bool | false | 書き込みを行わず、ギャップ分析とテスト計画を表示する |
--linkup | bool | false | ガイダンスをウェブ検索する(Rube MCP 経由) |
--query | 文字列 | - | LINKUP_SEARCH の検索クエリ |
有効化されるペルソナ
- qa-specialist - テスト分析と品質評価
MCP 連携
PAL MCP(品質とデバッグ)
| ツール | 使用する場面 | 目的 |
|---|---|---|
mcp__pal__debug | テストの失敗 | 失敗したテストの根本原因を分析する |
mcp__pal__codereview | テストの品質 | テストカバレッジと品質をレビューする |
mcp__pal__thinkdeep | 複雑な失敗 | 不安定なテストを複数段階で調査する |
mcp__pal__consensus | テスト戦略 | テストアプローチを複数モデルで検証する |
mcp__pal__apilookup | フレームワークのドキュメント | 最新のテストフレームワークのドキュメントを取得する |
PAL の使用パターン
# Debug failing test
mcp__pal__debug(
step="Investigating intermittent test failure",
hypothesis="Race condition in async setup",
confidence="medium",
relevant_files=["/tests/test_api.py"]
)
# Review test quality
mcp__pal__codereview(
review_type="full",
findings="Test coverage, assertion quality, edge cases",
focus_on="test isolation and mocking patterns"
)
# Validate testing strategy
mcp__pal__consensus(
models=[{"model": "gpt-5.2", "stance": "neutral"}, {"model": "gemini-3-pro", "stance": "neutral"}],
step="Evaluate: Is integration testing sufficient for this feature?"
)
Rube MCP(自動化と調査)
| ツール | 使用する場面 | 目的 |
|---|---|---|
mcp__rube__RUBE_SEARCH_TOOLS | CI/CD 連携 | テストレポートツールを探す |
mcp__rube__RUBE_MULTI_EXECUTE_TOOL | 通知 | 結果を Slack に投稿し、チケットを更新する |
mcp__rube__RUBE_REMOTE_WORKBENCH | 一括処理 | 大量のテスト結果を分析する |
Rube の使用パターン
# Search for testing best practices (--linkup flag uses LINKUP_SEARCH)
mcp__rube__RUBE_MULTI_EXECUTE_TOOL(tools=[
{"tool_slug": "LINKUP_SEARCH", "arguments": {
"query": "pytest fixtures best practices",
"depth": "deep",
"output_type": "sourcedAnswer"
}}
])
# Post test results to Slack
mcp__rube__RUBE_MULTI_EXECUTE_TOOL(tools=[
{"tool_slug": "SLACK_SEND_MESSAGE", "arguments": {
"channel": "#ci-results",
"text": "Test run complete: 95% pass rate, 87% coverage"
}}
])
エビデンスの要件
このスキルにはエビデンスが必要です。必ず以下を行ってください。
- テストの実行出力と成功・失敗の件数を示す
--coverageを使用した場合は、カバレッジ指標を参照する- 失敗があった場合は、実際のエラーメッセージを提示する
テスト種別の定義
| 種別 | テスト対象 | マーカー |
|---|---|---|
| ユニット | 分離した単一の関数/クラス。依存関係はモック化 | (なし、またはフレームワークのデフォルト) |
| インテグレーション | 複数のコンポーネントを組み合わせてテスト。フィクスチャ経由で実際の DB を使用 | @pytest.mark.integration、describe("integration") |
| E2E | 実際の、またはモック化した外部 API を使用したパイプライン全体 | @pytest.mark.slow、@pytest.mark.e2e |
フェーズ 1:カバレッジのベースライン
1.1 現在のカバレッジレポートを実行する
テストフレームワークを検出して、カバレッジを実行します。
# Python (pytest)
pytest --cov=src --cov-report=term-missing --cov-report=json:coverage.json -q --tb=no
# JavaScript (jest/vitest)
npx jest --coverage --coverageReporters=json-summary
# or: npx vitest run --coverage
# Go
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
# Rust
cargo tarpaulin --out json
1.2 カバレッジの不足箇所を解析する
カバレッジレポートを読み取り、次の情報を抽出します。
- ファイルごとのカバレッジ率
- ファイルごとの未カバー行番号
- プロジェクト全体のカバレッジ
--module が指定されている場合は、カバレッジデータを指定されたモジュールのみに絞り込みます。
1.3 不足箇所のレポートを作成する
カバレッジの不足が大きい順(カバレッジが低い順)にファイルを並べたリストを作成します。
## Coverage Gap Report
**Current Coverage**: 52% | **Target**: 80% | **Gap**: 28%
| File | Coverage | Missing Lines | Priority |
|------|----------|---------------|----------|
| src/services/payment.py | 0% | 1-120 | CRITICAL |
| src/utils/validator.py | 15% | 12-45, 67-89 | HIGH |
| src/api/routes/users.py | 42% | 55-70, 88-102 | MEDIUM |
優先度のルール:
- CRITICAL:カバレッジ 0%(テストがまったくない)
- HIGH:カバレッジ 30% 未満
- MEDIUM:カバレッジ 30~60%
- LOW:目標未満だが 60% 超
1.4 カバレッジの優先順位をユーザーに確認する
不足箇所のレポートを作成した後、何を優先するかユーザーに尋ねます。
AskUserQuestion:
question: "Found <N> files below target. Which should I tackle first?"
header: "Priority"
multiSelect: false
options:
- label: "Highest-impact first (Recommended)"
description: "<N CRITICAL + M HIGH priority files -- start with 0% coverage modules>"
- label: "Quick wins first"
description: "Start with files that need only 1-2 tests to reach target"
- label: "Specific module"
description: "I want to focus on a specific area of the codebase"
- label: "Dry run only"
description: "Just show me the gap report -- don't write any tests yet"
「Specific module」の場合:重点的に扱うモジュールを尋ねます。 「Dry run only」の場合:不足箇所のレポートを提示して終了します。
デフォルトでは、次のファイルをスキップします。
- ロジックを含まないプロトコル/インターフェース定義
- マイグレーションファイル
- 再エクスポートのみを行う
__init__.py/index.ts - 生成コード(protobuf、OpenAPI クライアント)
フェーズ 2:既存のテストパターンを分析する
テストを書く前に、必ずプロジェクトの規約を確認します。
2.1 テストインフラストラクチャを読む
テストのセットアップファイルを見つけて読みます。
| フレームワーク | 読むファイル |
|---|---|
| pytest | conftest.py、pyproject.toml [tool.pytest] |
| jest | jest.config.*、setupTests.*、__mocks__/ |
| vitest | vitest.config.*、setup.* |
| Go | *_test.go のヘルパー、testdata/ |
| Rust | tests/common/mod.rs |
2.2 パターンの例を見つける
不足箇所の各ファイルについて、テンプレートとして最も近い既存のテストを見つけます。
- 同じディレクトリ/モジュール内のテストを検索する
- インポートのパターン、フィクスチャの使用方法、アサーションのスタイルを確認する
- テスト用の基底クラスや共有ヘルパーがあれば記録する
2.3 利用可能なフィクスチャ/ヘルパーを特定する
利用可能なテストフィクスチャを用途に対応付けます。参照表を作成します。
| Fixture/Helper | Purpose | Used By |
|----------------|---------|---------|
| db_session | Database access | Integration tests |
| mock_api_client | Mock external API | Unit tests |
| ... | ... | ... |
2.4 関数をテスト種別に分類する
| 関数の特性 | テスト種別 |
|---|---|
| 純粋関数(I/O や DB なし) | ユニットテスト |
| バリデーションのみを使用 | ユニットテスト |
| データベース/ORM を呼び出す | インテグレーションテスト(DB フィクスチャが必要) |
| 外部 API を呼び出す | モックを使用したユニットテスト |
| HTTP エンドポイントのハンドラー | インテグレーションテスト |
| パイプライン全体の実行 | E2E テスト |
フェーズ 3:種別ごとにテストを生成する
優先度の高い順(CRITICAL が最初)に不足箇所を処理します。ファイルごとに、次の手順を実行します。
3.1 ソースモジュールを読む
次の項目を特定します。
- すべての公開関数とクラス
- それらのシグネチャ、戻り値の型、依存関係
- モック化が必要な依存関係と、実際のフィクスチャが必要な依存関係
- エッジケース:空の入力、None 値、エラー条件
3.2 ユニットテストを書く
AAA パターン(Arrange/Act/Assert)に従います。
# Python example
class TestFunctionName:
"""Tests for function_name."""
# Happy path
async def test_returns_expected_result(self):
"""function_name returns correct output for valid input."""
# Arrange
input_data = ...
# Act
result = await function_under_test(input_data)
# Assert
assert result.field == expected_value
# Edge cases
async def test_handles_empty_input(self):
"""function_name handles empty input correctly."""
...
# Error conditions (Let It Crash - verify errors propagate)
async def test_raises_on_invalid_input(self):
"""function_name raises ValueError for invalid input."""
with pytest.raises(ValueError):
await function_under_test(invalid_input)
// TypeScript/Jest example
describe('functionName', () => {
it('returns expected result for valid input', () => {
// Arrange
const input = { ... };
// Act
const result = functionName(input);
// Assert
expect(result.field).toBe(expectedValue);
});
it('throws on invalid input', () => {
expect(() => functionName(invalidInput)).toThrow();
});
});
// Go example
func TestFunctionName(t *testing.T) {
t.Run("returns expected result", func(t *testing.T) {
// Arrange
input := ...
// Act
result, err := FunctionName(input)
// Assert
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if result.Field != expected {
t.Errorf("got %v, want %v", result.Field, expected)
}
})
}
すべての言語に適用されるルール:
- コメントを付けて AAA パターン(Arrange/Act/Assert)を使用する
- docstring/説明には実装方法ではなく、期待される動作を記述する
- モック化するのは外部依存関係(API、DB、ネットワーク)のみ
- テストに try/except や try/catch を追加しない(Let It Crash の原則)
- テストを通すためにソースコードを変更しない(実際のバグがある場合を除く)
3.3 インテグレーションテストを書く
データベースや複数のコンポーネントが必要なテストでは、次のようにします。
- 適切なマーカー(
@pytest.mark.integration、タグ付きの describe ブロック)を付ける - 実際の DB フィクスチャまたはテストコンテナを使用する
- モック化したコンポーネントではなく、実際のコンポーネント間の連携をテストする
- フィクスチャのティアダウンにより、クリーンアップは自動的に行われる
3.4 E2E テストを作成する
パイプライン全体または API フローのテストでは、次のようにします。
- slow/e2e マーカーを付けます
- HTTP テストクライアント(httpx AsyncClient、supertest、net/http/httptest)を使用します
- フィクスチャを使って外部 API のレスポンスをモックします
- 認証を含むリクエスト/レスポンスの一連の流れをテストします
- レスポンススキーマが想定されるモデルと一致することを検証します
フェーズ 4:テストを検証する
4.1 新しいテストのみを実行する
# Run just the newly created/modified test file
pytest tests/test_<area>/test_<module>.py -v --tb=short
npx jest tests/<module>.test.ts --verbose
go test -v -run TestNewFunction ./pkg/...
4.2 失敗を修正する
テストが失敗した場合:
- エラー出力を注意深く読みます
- 失敗の原因がテストコードかソースコードかを判断します
- ソースコードの動作が正しい場合は、テストを修正します
- テストを通すためにソースコードを変更してはいけません(実際のバグがある場合を除きます)
- ソースコードにバグがある場合は、現在の動作をテストするだけにするか、修正するかをユーザーに確認します
4.3 全テストを実行する
新しいテストがすべて個別に合格した後:
# Full test suite - ensure no regressions
pytest -v --tb=short
npx jest --verbose
go test ./...
4.4 テストファイルをリントする
# Python
ruff check tests/ --fix && ruff format tests/
# TypeScript/JavaScript
npx eslint tests/ --fix && npx prettier tests/ --write
# Go
gofmt -w *_test.go
フェーズ 5:カバレッジの検証
5.1 カバレッジを再実行する
フェーズ 1 と同じカバレッジコマンドを実行し、更新後の指標を取得します。
5.2 実行前後を比較する
カバレッジの差分を報告します。
## Coverage Report
| Metric | Before | After | Delta |
|--------|--------|-------|-------|
| Total Coverage | 52% | 78% | +26% |
| Files with 0% | 5 | 1 | -4 |
### Per-File Improvements
| File | Before | After | Tests Added |
|------|--------|-------|-------------|
| src/services/payment.py | 0% | 85% | 8 |
| src/utils/validator.py | 15% | 72% | 5 |
5.3 継続するかどうかを尋ねる
カバレッジが目標に達していない場合は、自動で繰り返さず、ユーザーに確認します。
AskUserQuestion:
question: "Coverage is at <M%> (target: <N%>). Want to continue adding tests?"
header: "Iterate"
multiSelect: false
options:
- label: "Continue -- add more tests"
description: "<K files remaining below target -- next batch would cover <list>"
- label: "Good enough -- stop here"
description: "Accept current coverage and move on"
- label: "Raise the target"
description: "Current coverage exceeded expectations -- set a higher target"
- label: "Switch focus"
description: "Cover a different area instead of continuing the current batch"
継続する場合:
- フェーズ 1 を再実行して、残っている不足箇所を特定します
- 未カバー行数が最も多いファイルに重点を置きます
- 目標に達するかユーザーが停止するまで、フェーズ 3〜5 を繰り返します
最大反復回数:5(--loop の規約に従います)。
フェーズ 6:概要
最終結果を提示します。
## Test Coverage Update Summary
**Target**: N%
**Achieved**: M%
**Tests Added**: X unit, Y integration, Z e2e
### New Test Files Created
- tests/test_<area>/test_<module>.py (N tests)
- ...
### Modified Test Files
- tests/test_<area>/test_<module>.py (+N tests)
- ...
### Coverage by Category
| Category | Coverage | Status |
|----------|----------|--------|
| src/services/ | ??% | OK/NEEDS WORK |
| src/routers/ | ??% | OK/NEEDS WORK |
| src/models/ | ??% | OK/NEEDS WORK |
### Remaining Gaps (if any)
- src/services/transformer.py - Excluded (needs full pipeline data)
- ...
### Verification Commands
<framework-specific commands to re-run tests and coverage>
避けるべきアンチパターン
次のようなテストを書いてはいけません:
- プライベート/内部メソッドを直接テストする(公開 API 経由でテストします)
- 既存のテストカバレッジを重複させる(まず確認します!)
- 合格に実際の API キーを必要とする(外部サービスをモックします)
- テストの実行順序に依存する
- 非同期処理の同期に
time.sleep()を使用する - 伝播すべき例外を捕捉する(Let It Crash)
- 防御的な
if x is not Noneチェックを追加する(契約をテストします)
次のことをしてはいけません:
- テストしやすくするためにソースコードを変更する(既存のものをテストします)
- ソースファイルに型スタブや docstring を追加する(テストファイルのみを編集します)
- テスト用ユーティリティフレームワークや基底クラスを作成する(KISS)
- 3 ケース未満のパラメーター化テストを書く(個別のテストを書きます)
- 変更していないコードにコメントや docstring を追加する
カバレッジ分析(単独)
--generate を使わずに --coverage のみを有効にした場合:
- 行カバレッジの指標
- 分岐カバレッジの指標
- 未カバーのコードの特定
- カバレッジ傾向の比較
ツールの連携
- Bash - テストランナーの実行
- Glob - テストファイルの検索
- Grep - 結果の解析、失敗の分析
- Read - ソースファイルとテストファイルの確認
- Write - 新しいテストファイル、カバレッジレポートの作成
- Edit - 既存のテストファイルの拡張
- AskUserQuestion - 優先順位の確認、反復するかどうかの判断