test-namer について
テスト名で実装の詳細ではなく観察可能な振る舞いを平易な英語で表すための開発者向けスキルです。言語ごとの命名指針を示し、振る舞いを中心としたテストを重視します。
主な機能
- 01平易な英語で振る舞いを記述
- 02固定的な命名テンプレートを回避
- 03言語ごとの命名規則に対応
- 04観察可能な振る舞いを優先
- 05適切なテストスタイルを選択
活用シーン
- 01ドメイン動作テストの命名
- 02Go や Python のテスト作成
- 03JavaScript テストケースの命名
- 04実装に結び付いたテストの見直し
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mryll/ skills --skill test-namerインストール後、Claude Code で/test-namerを入力して読み込まれたか確認します。
同梱ファイルreferences/anti-patterns.mdreferences/testing-philosophy.md
詳細
テストの命名
実装の詳細ではなく、平易な英語で振る舞いを説明するテストを書きましょう。Vladimir Khorikov のテスト原則に基づいています。
命名ガイドライン
ルール
- 厳格な命名規則を設けない —
[MethodUnderTest]_[Scenario]_[ExpectedResult]のようなテンプレートは使わないでください - 問題領域に詳しいプログラマーではない人にも振る舞いが伝わるように説明する — ドメインの専門家がテスト名を理解できるようにします
- 関数名/メソッド名では単語をアンダースコアで区切る(JS/TS のような文字列ベースのテスト名では不要です)
- テスト名に SUT のメソッド名を含めない — メソッドではなく、振る舞いをテストします
- 希望ではなく、事実を書く —
should_be_invalidではなくis_invalidと書きます - 基本的な英文法を使う — 冠詞(
a、the)を使うと読みやすくなります - 具体的に書く —
Delivery_with_a_past_date_is_invalidはDelivery_with_invalid_date_is_invalidより適切です
命名の改善例
厳格な規則から始めて、段階的に改善します。
IsDeliveryValid_InvalidDate_ReturnsFalse -- rigid, cryptic
Delivery_with_invalid_date_should_be_invalid -- plain English (good start)
Delivery_with_past_date_should_be_invalid -- more specific
Delivery_with_past_date_is_invalid -- fact, not wish
Delivery_with_a_past_date_is_invalid -- natural grammar (final)
例外:ユーティリティコード
ビジネスロジックを含まないユーティリティ/ヘルパーコードでは、ビジネスに携わる人にとって振る舞いに意味がないため、メソッド名に言及しても問題ありません。
Sum_of_two_numbers
Trimmed_string_has_no_leading_whitespace
言語ごとの適用方法
Go
テスト関数は(言語上の要件により)Test で始める必要があります。その後に説明的な名前を付けます。
func TestDelivery_with_a_past_date_is_invalid(t *testing.T) { ... }
t.Run によるサブテストの名前には、完全な自由があります。
func TestDelivery(t *testing.T) {
t.Run("with a past date is invalid", func(t *testing.T) { ... })
t.Run("with a future date is valid", func(t *testing.T) { ... })
}
テーブル駆動テストでは、メソッドシグネチャではなく、説明的な name フィールドを使います。
tests := []struct {
name string
// ...
}{
{"delivery with a past date is invalid", ...},
{"delivery for tomorrow is valid", ...},
}
Python(pytest)
関数は test_ で始める必要があります。その後に snake_case で説明的な名前を付けます。
def test_delivery_with_a_past_date_is_invalid():
...
def test_new_customer_starts_in_pending_state():
...
Java / Kotlin(JUnit)
テストの検出には @Test アノテーションを使います。メソッド名は自由に記述できます。
@Test
void Delivery_with_a_past_date_is_invalid() { ... }
@Test
void New_customer_starts_in_pending_state() { ... }
Kotlin では、バッククォートで囲んだ名前を使って自然な言葉で記述できます。
@Test
fun `delivery with a past date is invalid`() { ... }
JavaScript / TypeScript(Jest、Vitest、Mocha)
文字列ベースの名前では、アンダースコアは使わず、自然な言葉をそのまま使います。
it("delivery with a past date is invalid", () => { ... });
test("new customer starts in pending state", () => { ... });
describe("delivery validation", () => {
it("rejects past dates", () => { ... });
it("accepts future dates", () => { ... });
});
C# / .NET
[Fact] または [Test] 属性を使います。アンダースコアを使った名前も自由に付けられます。
[Fact]
public void Delivery_with_a_past_date_is_invalid() { ... }
Rust
#[test] 属性を使います。標準的な snake_case の識別子を使います。
#[test]
fn delivery_with_a_past_date_is_invalid() { ... }
テストクラス/ファイルの命名
[ClassName]Tests または [feature]_test は、エントリーポイントとして使い、境界としては扱わないでください。ユニットテストにおけるユニットはクラスではなく、振る舞いの単位です。複数のクラスにまたがることもあります。
テスト対象 — 実装ではなく振る舞い
- 観察可能な振る舞いをテストする:出力、状態の変化、クライアントから見える副作用
- 実装の詳細は決してテストしない:内部の連携、プライベートメソッド、厳密な SQL クエリ、特定のメソッド呼び出し順序
- 内部メソッドの名前を変更しても、テストが失敗することがあってはなりません
- 正当なリファクタリング中にテストが失敗するなら、そのテストは実装に依存しています
テストのスタイル(優先度順)
- 出力ベース — 入力を与え、出力を検証します。誤検知への耐性が最も高い方法です。純粋関数やドメインロジックに使います。
- 状態ベース — 操作を実行し、公開 API を通じて結果の状態を検証します。出力の検証ができない場合に適しています。
- コミュニケーションベース(モック) — 依存関係とのやり取りを検証します。制御できない外部依存関係(SMTP、メッセージバス、サードパーティ API)にのみ使ってください。ドメインオブジェクトや安定した依存関係は決してモックにしないでください。
テストのスタイル、価値、実践的なテスト戦略について詳しくは、testing-philosophy.md を参照してください。
避けるべき一般的なアンチパターンについては、anti-patterns.md を参照してください。