Help us improve
Share bugs, ideas, or general feedback.
From disciplined-process
Test-driven development methodology with four test types - unit, integration, property, and e2e. Use when writing tests, planning test strategy, implementing features test-first, or verifying test coverage. Triggers when tests are mentioned, test files are being created, or test-first approach is needed.
npx claudepluginhub rand/disciplined-process-plugin --plugin disciplined-processHow this skill is triggered — by the user, by Claude, or both
Slash command
/disciplined-process:tdd-methodologyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Tests verify specifications are met. Write tests BEFORE implementation. Tests reference spec paragraph IDs for traceability.
Enforces test-driven development for features, bug fixes, and refactoring. Requires failing tests before any production code, with guidance on test types and spec-to-test mapping.
Orchestrates TDD workflows enforcing red-green-refactor cycles, coordinates multi-agent testing agents, and applies modern practices like Chicago/London school, ATDD, and BDD.
Guides TDD cycles (red-green-refactor), outside-in double-loop architecture, test isolation, and naming. Useful when writing test plans or reviewing test quality.
Share bugs, ideas, or general feedback.
Tests verify specifications are met. Write tests BEFORE implementation. Tests reference spec paragraph IDs for traceability.
┌──────────────────┐
│ 1. RED │ Write a failing test for spec requirement
├──────────────────┤
│ 2. GREEN │ Write minimal code to pass
├──────────────────┤
│ 3. REFACTOR │ Improve code, keep tests green
└──────────────────┘
Purpose: Test individual functions/methods in isolation
Location: tests/unit/
Characteristics:
Pattern:
test_<function>_<scenario>_<expected>
Example (Rust):
#[test]
// @trace SPEC-03.07
fn test_validate_length_exceeds_max_returns_error() {
let input = "x".repeat(1025);
assert!(validate_length(&input).is_err());
}
Example (TypeScript):
describe('validateLength', () => {
// @trace SPEC-03.07
it('returns error when input exceeds max length', () => {
const input = 'x'.repeat(1025);
expect(() => validateLength(input)).toThrow();
});
});
Example (Python):
def test_validate_length_exceeds_max_returns_error():
"""@trace SPEC-03.07"""
input_str = 'x' * 1025
with pytest.raises(ValidationError):
validate_length(input_str)
Purpose: Test component interactions, real dependencies
Location: tests/integration/
Characteristics:
Pattern:
test_<component>_<integration>_<scenario>
Example (Rust):
#[tokio::test]
// @trace SPEC-05.12
async fn test_auth_service_validates_against_database() {
let db = TestDb::new().await;
let auth = AuthService::new(db.pool());
let result = auth.authenticate(valid_credentials()).await;
assert!(result.is_ok());
}
Purpose: Test invariants hold across generated inputs
Location: tests/property/
Characteristics:
Properties to test:
decode(encode(x)) == xf(f(x)) == f(x)len(result) <= MAX_SIZEf(a, b) == f(b, a)Example (Rust with proptest):
proptest! {
#[test]
// @trace SPEC-02.01 - Encoding roundtrip
fn test_encode_decode_roundtrip(input: String) {
let encoded = encode(&input);
let decoded = decode(&encoded)?;
prop_assert_eq!(decoded, input);
}
}
Example (Python with Hypothesis):
from hypothesis import given, strategies as st
@given(st.text())
def test_encode_decode_roundtrip(input_str):
"""@trace SPEC-02.01"""
encoded = encode(input_str)
decoded = decode(encoded)
assert decoded == input_str
Example (TypeScript with fast-check):
import fc from 'fast-check';
// @trace SPEC-02.01
test('encode/decode roundtrip', () => {
fc.assert(fc.property(fc.string(), (input) => {
const encoded = encode(input);
const decoded = decode(encoded);
return decoded === input;
}));
});
Purpose: Test complete user workflows
Location: tests/e2e/
Characteristics:
Pattern:
test_<user_journey>_<expected_outcome>
Example:
// @trace SPEC-01.01 - Complete user registration flow
test('user can register and receive confirmation email', async () => {
await page.goto('/register');
await page.fill('#email', 'test@example.com');
await page.fill('#password', 'SecurePass123!');
await page.click('button[type="submit"]');
await expect(page).toHaveURL('/welcome');
await expect(emailServer).toHaveReceivedEmail({
to: 'test@example.com',
subject: /Welcome/
});
});
╱╲
╱ ╲ E2E (few)
╱────╲ Critical user journeys
╱ ╲
╱────────╲ Property (some)
╱ ╲ Invariants, edge cases
╱────────────╲ Integration (more)
╱ ╲ Component boundaries
╱────────────────╲ Unit (many)
Individual functions
tests/
├── unit/
│ ├── test_<module>.{ext}
│ └── ...
├── integration/
│ ├── test_<component>_<integration>.{ext}
│ └── ...
├── property/
│ ├── test_<invariant>.{ext}
│ └── ...
├── e2e/
│ ├── test_<journey>.{ext}
│ └── ...
├── fixtures/ # Shared test data
│ ├── valid_inputs.json
│ └── ...
└── conftest.{ext} # Shared setup (pytest) or similar
| Language | Unit | Property | Integration | E2E |
|---|---|---|---|---|
| Rust | #[test], cargo test | proptest, quickcheck | tokio::test | - |
| TypeScript | Jest, Vitest | fast-check | Supertest | Playwright |
| Python | pytest | Hypothesis | pytest + fixtures | Playwright |
| Go | testing | gopter | testcontainers | - |
| Zig | std.testing | - | - | - |
| Level | Minimum Coverage | Measured By |
|---|---|---|
| Spec | 100% normative paragraphs | Trace marker presence |
| Unit | 80% line coverage | Coverage tools |
| Integration | Critical paths | Manual review |
| E2E | Happy paths | Journey checklist |
@trace SPEC-XX.YYtest_<what>_<scenario>_<expected>