agentsclimarketplace

Tdd discipline

Skill Inteligentsensingsolutions/tdd-dev-workflow/skills/tdd-discipline

This skill should be used when the user asks about "TDD", "test-driven development", "red green refactor", "write tests first", "failing test", "test first", "TDD cycle", "test coverage", "how to start implementing", "implement a feature", "add tests for", or needs guidance on test-driven development methodology. Enforces the red-green-refactor discipline.From its SKILL.md

Install
npx -y skills add Inteligentsensingsolutions/tdd-dev-workflow --skill tdd-discipline

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.8 KB, as published. Nobody here has run it

TDD Discipline: Red-Green-Refactor

The Iron Law

NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST.

No exceptions. No "just this once." No "it's too simple to test." No "I'll add tests later." Every line of production code must exist because a test demanded it.

This is not a guideline. This is a discipline.


The TDD Cycle

The cycle has exactly three phases. Execute them in strict order, every time.

RED  --->  GREEN  --->  REFACTOR  --->  RED  --->  ...

Phase 1: RED -- Write a Failing Test

Goal: Define the expected behavior before writing any implementation.

Steps

  1. Identify the next smallest piece of behavior to implement.
  2. Write a single test that asserts that behavior.
  3. Run the test. It MUST fail.
  4. Verify the failure message. The test must fail for the right reason.

What "Failing for the Right Reason" Means

  • A test that fails because the function does not exist yet: correct.
  • A test that fails because the assertion does not match the return value: correct.
  • A test that fails because of a syntax error in the test: incorrect. Fix the test.
  • A test that fails because of a missing import: incorrect. Fix the test.

The failure message must describe the behavioral gap, not an infrastructure problem.

Rules

  • One logical assertion per test. Test one behavior at a time.
  • Name the test to describe the behavior, not the implementation.
  • Do not write multiple failing tests at once. One RED, one GREEN, then repeat.
  • If unsure what to test next, revisit the acceptance criteria.

Example

describe('TemperatureConverter', () => {
  it('converts 0 Celsius to 32 Fahrenheit', () => {
    expect(convertCelsiusToFahrenheit(0)).toBe(32);
  });
});

Run it. See it fail: convertCelsiusToFahrenheit is not defined. This is the right reason.


Phase 2: GREEN -- Make the Test Pass

Goal: Write the minimum code necessary to make the failing test pass.

Steps

  1. Write the simplest implementation that makes the test pass.
  2. Run the test. It MUST pass.
  3. Run all existing tests. They must ALL still pass.
  4. Stop.

What "Minimum Code" Means

  • If a hardcoded return value makes the test pass, that is valid. The next test will force generalization.
  • Do not add error handling that no test requires.
  • Do not add features that no test requires.
  • Do not optimize code that no test requires to be optimized.
  • Do not refactor yet. That is the next phase.

The Temptation Rule

If tempted to write more code than the test demands, STOP. Write another test first. Let the tests drive the design.

Example

function convertCelsiusToFahrenheit(celsius: number): number {
  return celsius * 9/5 + 32;
}

Run the test. Green. All existing tests still green. Stop.


Phase 3: REFACTOR -- Improve the Code

Goal: Improve code structure and quality while all tests remain green.

Steps

  1. Look for duplication, poor naming, complex conditionals, long functions.
  2. Improve the code in small increments.
  3. Run all tests after each change. They MUST stay green.
  4. If tests break during refactoring, undo the last change immediately.

What to Refactor

  • Remove duplication: Extract repeated logic into shared functions or constants.
  • Improve naming: Rename variables, functions, and classes to express intent.
  • Extract patterns: Pull out helper functions, modules, or classes.
  • Simplify conditionals: Replace nested if/else with early returns or polymorphism.
  • Reduce coupling: Move toward cleaner interfaces and better separation of concerns.

What NOT to Do During Refactoring

  • Do not add new functionality. That requires a new RED phase.
  • Do not change the external behavior of the code. Tests must stay green.
  • Do not skip running tests between refactoring steps.

Test Structure: Arrange-Act-Assert

Structure every test with three clear sections:

it('calculates total price with tax', () => {
  // Arrange: set up preconditions and inputs
  const cart = new ShoppingCart();
  cart.addItem({ name: 'Widget', price: 10.00 });
  const taxRate = 0.08;

  // Act: execute the behavior under test
  const total = cart.calculateTotal(taxRate);

  // Assert: verify the expected outcome
  expect(total).toBe(10.80);
});

Rules

  • Keep each section small and focused.
  • One Act per test. If multiple actions are needed, consider splitting into multiple tests.
  • Use descriptive test names that document the behavior being verified.
  • Group related tests with describe blocks to provide context.

Naming Convention

Name tests to describe behavior from the user's perspective:

// Good: describes behavior
'returns empty array when no items match filter'
'throws validation error when email format is invalid'
'sends notification after successful payment'

// Bad: describes implementation
'calls filterItems method'
'checks regex pattern'
'triggers sendEmail function'

What to Test

Coverage Strategy

For each acceptance criterion in an issue, write at least one test. Then extend coverage:

CategoryDescriptionExample
Happy pathNormal expected usageValid input produces correct output
Edge casesBoundary and unusual inputsEmpty string, zero, max value
Error conditionsInvalid inputs and failure modesNull input, network timeout
Boundary valuesValues at the edges of valid rangesFirst item, last item, off-by-one

Test Ordering

Start with the simplest happy path test. Build complexity incrementally:

  1. Simplest possible input and output.
  2. Another variation of the happy path.
  3. Edge case: empty or minimal input.
  4. Edge case: boundary values.
  5. Error condition: invalid input.
  6. Error condition: external failure.

Each test adds one new dimension of behavior. The implementation grows organically to handle each new case.


Anti-Patterns to Avoid

Testing Implementation Details

Do NOT test how something is done internally. Test what it does.

// Bad: tests implementation detail
expect(service.internalCache.size).toBe(3);

// Good: tests observable behavior
expect(service.getItems()).toHaveLength(3);

If the internal implementation changes but behavior stays the same, tests should not break.

Writing Tests After Code

Writing tests after code turns them into a rubber stamp. The tests confirm what was already written rather than driving the design. Always write the test first.

Skipping the RED Phase

Running a test that passes immediately provides no information. If the test passes without new production code, either the test is wrong (it does not test what it should) or the behavior already exists (no new code needed).

Writing Too Many Tests at Once

Write one test, make it pass, refactor. Then write the next test. Batching tests leads to large jumps in implementation and missed design feedback.

Testing Trivial Code

The iron law applies to code containing decisions, transformations, or side effects. Simple getters, setters, or constructor assignments with no logic are not production behavior that requires a failing test -- they are structural wiring. Focus testing effort on code that makes decisions, transforms data, or produces side effects.


When to Apply TDD

Features

Apply the full Red-Green-Refactor cycle. Start from the acceptance criteria and work through each criterion as a test.

Bug Fixes

  1. Write a failing test that reproduces the bug. This test captures the exact broken behavior.
  2. Verify it fails for the right reason (the bug).
  3. Fix the code.
  4. Verify the test passes.
  5. This test now prevents the bug from recurring.

Refactoring

  1. Ensure comprehensive tests exist before changing any code.
  2. If tests are missing, add them first (characterization tests).
  3. Refactor in small steps, running tests after each change.
  4. Never refactor and add features simultaneously.

TDD Decision Checklist

Before writing any production code, confirm:

  • A failing test exists that demands this code.
  • The test fails for the right reason.
  • The test name describes a behavior, not an implementation.
  • Only the minimum code to pass the test is being written.
  • All existing tests still pass.
  • Refactoring is complete before writing the next test.

Quick Reference

PhaseActionValidation
REDWrite one failing testTest fails for the right reason
GREENWrite minimum code to passAll tests green
REFACTORImprove structure, no new behaviorAll tests stay green

Dependencies

None -- this is a foundation workflow skill.


Used By

ComponentReason
issue-workflowStep 4 mandates TDD for all implementation work
systematic-debuggingPhase 4 uses TDD to implement the fix
e2e-testingE2E tests run after the TDD unit/integration cycle
Agent: tdd-redExecutes the RED phase
Agent: tdd-greenExecutes the GREEN phase
Agent: tdd-refactorExecutes the REFACTOR phase

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.