test-driven-development skill
契約ベースのテストとアーキテクチャ境界の管理を通じて、テスト駆動開発の原則に基づいたソフトウェア設計を実現します。
- GitHubスター
- 9
- ファイル
- 1
- 最終コミット
- 2026年10月13日
- ライセンス
- EPL-2.0
- 許可されたツール
- —
test-driven-development skillは何をしますか
test-driven-developmentはAgent Skillsです。 契約ベースのテストとアーキテクチャ境界の管理を通じて、テスト駆動開発の原則に基づいたソフトウェア設計を実現します。.
skillのSKILL.mdから生成された要約。
test-driven-development skill について
このSKILLは、開発者やAIエージェントがテスト駆動開発の原則をソフトウェア設計に適用することを可能にします。テストを単なる事後的な作業としてではなく、ビジネス要件と期待される動作を定義する正式な契約として扱います。エージェントがこのSKILLをロードすると、まず失敗するテストを書くこと、アーキテクチャ境界を管理すること、そしてスタブ、モック、フェイク、スパイといった適切なテストダブルを使用することについてのガイダンスを提供します。
ユーザーはこのSKILLを活用することで、壊れたコードに合わせてテストを変更するのではなく、実装の修正に集中し、高いコード品質を維持できます。また、内部のプライベートメソッドをモックしようとする衝動などの設計上の問題(デザイン・スメル)を特定し、リファクタリングを提案します。このSKILLは、レイヤー、モジュール、プロセス、外部システム境界を含む幅広いアーキテクチャ境界をカバーしています。JUnit、pytest、clojure.testなどの特定のフレームワークを使用している場合に特に有用であり、ユニットテストがコンポーネントのロジックを検証し、統合テストが境界を越えた実際のシステム動作を検証できるようにします。
エージェントができること
- 1失敗したテストのデバッグテストの失敗を、テストの断言(assertion)を修正するためのものではなく、実装をデバッグするためのシグナルとして活用します。
skill の SKILL.md から作成されています。すべてのユースケースは、その引用と照合されています。
test-driven-development skillのインストール方法
各コマンドはskillフォルダをクライアントのskillsディレクトリにコピーします。読み込むには、クライアントを再起動するか新しいセッションを開始してください。プラグインにtest-driven-development skillをインストールする
/plugin marketplace add Pyroxin/opinionated-claude-skills /plugin install opinionated-software-engineering@opinionated-claude-skills
Claude Codeにtest-driven-development skillをインストールする
~/.claude/skills/test-driven-development/SKILL.md
$ npx degit Pyroxin/opinionated-claude-skills/opinionated-software-engineering/skills/test-driven-development ~/.claude/skills/test-driven-developmentClaude Code (project)にtest-driven-development skillをインストールする
.claude/skills/test-driven-development/SKILL.md
$ npx degit Pyroxin/opinionated-claude-skills/opinionated-software-engineering/skills/test-driven-development .claude/skills/test-driven-developmentCodexにtest-driven-development skillをインストールする
~/.agents/skills/test-driven-development/SKILL.md
$ npx degit Pyroxin/opinionated-claude-skills/opinionated-software-engineering/skills/test-driven-development ~/.agents/skills/test-driven-developmentGemini CLIにtest-driven-development skillをインストールする
~/.gemini/skills/test-driven-development/SKILL.md
$ npx degit Pyroxin/opinionated-claude-skills/opinionated-software-engineering/skills/test-driven-development ~/.gemini/skills/test-driven-developmentClaude.aiにtest-driven-development skillをインストールする
npx degit Pyroxin/opinionated-claude-skills/opinionated-software-engineering/skills/test-driven-development test-driven-development && zip -r test-driven-development.zip test-driven-development # claude.ai → Customize → Skills → + → Create skill → Upload a skill → test-driven-development.zip
SKILL.md
GitHubで表示Test-Driven Development
For system-level design principles and architectural boundaries, see the software-engineer skill.
Core Philosophy
<core_philosophy>
Foundation: TDD is an application of contract-based design. Tests define the contract an implementation must fulfill—they are specifications, not afterthoughts. This connects directly to the abstraction principles in the software-engineer skill.
Tests = Contracts: Tests represent business requirements and expected behavior. They are contracts the implementation must fulfill. Never compromise test integrity to achieve green tests.
Tests are source of truth: When tests fail, fix the implementation. Only change tests when requirements change or test has a verified bug. </core_philosophy>
Testing Approach
Architectural Boundaries and Mocking Strategy
<architectural_boundaries> Identify architectural boundaries in your system:
- Layer boundaries (e.g., data layer, service layer, presentation layer)
- Module boundaries (e.g., namespaces, packages, crates)
- Process boundaries (e.g., Erlang processes, Elixir GenServers)
- External system boundaries (e.g., APIs, databases, third-party services) </architectural_boundaries>
<unit_definition> What constitutes a "unit":
A "unit" is a cohesive component at an architectural boundary:
- Classes (e.g., Java, Python, Swift)
- Namespaces with related functions (e.g., Clojure, Haskell)
- Modules with related predicates (e.g., Prolog)
- Processes/GenServers (e.g., Erlang, Elixir)
- Modules with traits/protocols (e.g., Rust, Swift) </unit_definition>
<mocking_rules> When to mock:
- Mock dependencies across architectural boundaries
- External dependencies injected/passed into system under test get mocked
When NOT to mock:
- Don't mock the system under test itself
- Don't mock within a cohesive unit (e.g., private methods, internal helpers)
- If tempted to mock internals, that's a design smell — refactor instead </mocking_rules>
<test_balance> Balance unit and integration tests:
- Unit tests: Test each component in isolation with mocked dependencies across boundaries
- Integration tests: Test behavior across boundaries with real implementations
- Both are necessary — unit tests verify component logic, integration tests verify system behavior
- Over-mocked tests validate mocks, not real behavior </test_balance>
┌───────────────────────────────────────────────────────┐
│ Application Core │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Domain │ │ Service │ │ Use Case │ │
│ │ Models │ │ Layer │ │ Layer │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
├───────────────────────BOUNDARY────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Database │ │ External │ │ HTTP │ │
│ │ Adapter │ │ API │ │ Client │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└───────────────────────────────────────────────────────┘
- Unit tests: Test domain models and service layer with mocked adapters
- Integration tests: Test adapters with real external systems (DB, APIs)
- Contract tests: Verify adapters fulfill the port interface
- External database gets mocked at adapter boundary, not inside services
Test Doubles Taxonomy
<test_doubles> Understanding test double types aids in communicating test intent. This taxonomy was formalized by Gerard Meszaros in xUnit Test Patterns (2007):1
| Type | Purpose | When to Use |
|---|---|---|
| Stub | Returns predetermined values | When behavior doesn't affect test outcome |
| Mock | Verifies interactions occurred | When the interaction IS the behavior being tested |
| Fake | Working implementation (simplified) | When real implementation too slow/complex |
| Spy | Records calls for later verification | When need to verify after execution |
Key insight: Overuse of mocks often indicates testing implementation rather than behavior. Prefer stubs when possible; use mocks when interactions are the contract.
Test Design Process
<design_steps> When designing tests:
- Identify architectural boundaries in the system
- Determine what constitutes a "unit" (component, layer, module)
- Plan unit tests for each unit with dependencies mocked at boundaries
- Plan integration tests crossing boundaries with real implementations
- Ensure tests verify usage/requirements, not implementation details </design_steps>
<failure_response> When test fails:
- Read test to understand expected behavior
- Debug implementation to find why it doesn't meet expectations
- Fix implementation, never "fix" test to pass </failure_response>
<quality_criteria> Test quality requirements:
- Descriptive names explaining the requirement being checked
- Readable as documentation of system behavior
- Plan test cases based on usage, not implementation details
- Include comprehensive documentation (e.g., Javadoc for JUnit, Sphinx for Python) explaining what test ensures and special considerations
- Tests can have bugs or enforce wrong behaviors—always assess correctness </quality_criteria>
Test-Driven Development Workflow
<tdd_cycle>
- Write failing tests FIRST based on requirements (including desired usage patterns)
- Thoroughly document planned tests to guide implementation
- Stub planned tests with exceptions:
throw new IllegalStateException("Not implemented yet!")
- Implementation makes existing tests pass without test modification
- Tests are source of truth — never change tests to match broken code
- When debugging:
- Understand why test is failing
- Fix implementation to match test expectations
- Only modify tests if requirements changed or test has VERIFIED bug
- Treat test failures as implementation bugs, not test bugs
- Test bugs exist, but assume only after verifying implementation is correct </tdd_cycle>
<debugging_tip> Debug and trace logging: Effective way to probe program function during test execution. </debugging_tip>
Critical Anti-Patterns
<anti_patterns> Never:
- Mock the system under test itself (the component being tested)
- Mock within a cohesive unit (e.g., private methods, internal helpers of the unit under test)
- Change test assertions to match current behavior
- Write tests that mirror implementation rather than requirements
- Over-mock to the point tests don't validate real behavior
- Write tests that don't exercise code in module being tested (e.g., calculating result in test instead of using module-under-test)
- Mock to make tests pass — fix implementation instead </anti_patterns>
<design_smell> If tempted to mock internals of the unit under test: That's a design smell — refactor the code instead. </design_smell>
Framework-Specific Guidance
See language-specific skills for testing framework details:
- java-programmer: JUnit, Mockito, assertion patterns
- python-programmer: pytest, unittest, mocking strategies
- clojure-programmer: clojure.test, test.check
- racket-programmer: RackUnit, testing patterns
General principles across frameworks:
- Use framework's assertion methods instead of custom comparison logic
- Include descriptive assertion messages explaining business/technical reasons
- Organize tests into logical categories/suites
- Maintain consistent assertion styles within codebase
Planning and Scaffolding
<scaffolding_steps> Before implementing:
- Create interfaces, type signatures, abstract classes, and other definitional structures
- Create empty functions with step-by-step comments: "1. Setup data.", "2. Process data.", etc.
- Write tests after defining but NOT implementing code structures to create example API uses
- Examine example code for potential usage problems requiring scaffold refactoring </scaffolding_steps>
<maintainability_principles> Maintainability:
- Assume code maintained by junior engineers and other LLMs
- Prefer strongly defined structures based on idiomatic patterns for the language
- If uncertain, ask — user is senior engineer with answers or resources </maintainability_principles>
Common Mistakes
<common_mistakes>
Mechanical Mistakes
- Planning tests based on implementation instead of usage/requirements
- Creating tests that over-fit to specific implementation
- Removing existing documentation or comments (rephrase for consistency instead)
- Not documenting tests (every test needs comprehensive documentation)
- Using inconsistent assertion/verification styles across tests
- Not explaining business/technical reasons in assertion messages
Judgment Mistakes (Staff-Level Insights)
- Confusing "tests first" with "tests drive design": TDD is about using tests to discover design, not just writing tests before code
- Treating coverage metrics as quality proxies: 100% coverage with bad tests is worse than 70% coverage with good tests
- Not recognizing test difficulty as design feedback: If a unit is hard to test, the design is likely wrong—don't fight to mock, refactor instead
- Writing tests that specify implementation sequence: Tests should specify WHAT behavior occurs, not HOW or in what order
- Testing internal state rather than observable behavior: Tests should verify outputs and side effects, not implementation details
- Over-mocking to achieve isolation: If everything is mocked, the test validates mocks, not system behavior </common_mistakes>
Resources
Key Principles:
- Test Pyramid concept (Mike Cohn, 2009): more unit tests, fewer integration tests, even fewer E2E
- Arrange-Act-Assert pattern (Bill Wake, 2001) for test structure
- Given-When-Then (Dan North and Chris Matts, ~2006) for behavior specification
See also: Language-specific skills for framework-specific testing patterns (JUnit, pytest, clojure.test, RackUnit, PlUnit).
Footnotes
-
Gerard Meszaros. 2007. xUnit Test Patterns: Refactoring Test Code. Addison-Wesley. </test_doubles> ↩
このスキルのファイル
1test-driven-development skillに関する質問
Claude Codeにtest-driven-development skillをインストールするには
npx degit Pyroxin/opinionated-claude-skills/opinionated-software-engineering/skills/test-driven-development ~/.claude/skills/test-driven-developmentを実行してください。Claude Codeは~/.claude/skills(すべてのプロジェクト)または.claude/skills(単一プロジェクト)からskillsを読み込み、説明がタスクに一致する場合にskillを使用します。
test-driven-development skillはどのクライアントで使用できますか
Agent Skills形式を読み込むすべてのクライアントで使用できます: Claude Code、Codex、Gemini CLI、claude.ai(ZIPとしてアップロード)。skill内のスクリプトは、クライアントがコード実行を許可した場合にのみ実行されます。
テストが失敗した場合はどうすればよいですか?
テストを読み込んで期待される動作を理解し、実装をデバッグして失敗の原因を特定した上で、実装を修正してください。テストをパスさせるためにテストコードを変更しないでください。
ユニットのテストが困難な場合はどう対応すべきですか?
テストの困難さは設計の不備を示すサインです。無理にモックを適用しようとするのではなく、コードをリファクタリングすべきです。