# Test Driven Development (TDD)

Test Driven Development (TDD) is a software development process where you write the test *before* you write the actual code. It relies on the repetition of a very short development cycle.

## 1. The Red-Green-Refactor Cycle

The core of TDD is a simple 3-step loop:

1.  **Red:** Write a failing test for a small piece of functionality. It fails because the feature doesn't exist yet.
2.  **Green:** Write just enough code to make the test pass. Do not worry about code quality or elegance here; just get it to pass.
3.  **Refactor:** Clean up the code while keeping the test passing. Remove duplication, improve names, and apply design patterns.

## 2. The Three Laws of TDD

Robert C. Martin (Uncle Bob) defines three rules:
1.  You are not allowed to write any production code unless it is to make a failing unit test pass.
2.  You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
3.  You are not allowed to write any more production code than is sufficient to pass the one failing unit test.

## 3. Example (JavaScript)

**Step 1: Red (The Test)**
```javascript
// math.test.js
const { add } = require('./math');

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});
// Fails: 'add' is not defined.
```

**Step 2: Green (The Code)**
```javascript
// math.js
function add(a, b) {
  return a + b;
}
module.exports = { add };
// Test passes!
```

**Step 3: Refactor**
(In this simple example, there isn't much to refactor, but if we had hardcoded `return 3`, we would now change it to `a + b`).

## 4. Benefits

*   **High Test Coverage:** Since you write tests for everything, you end up with near 100% coverage by default.
*   **Better Design:** Writing the test first forces you to think about the API design (how the code will be used) before implementation details.
*   **Confidence:** You can refactor aggressively because you have a safety net of tests.
*   **Documentation:** The tests serve as living documentation of how the system behaves.

## 5. Common Pitfalls

*   **Testing Implementation Details:** Tests should check *behavior*, not internal state. If you test internals, refactoring becomes impossible without breaking tests.
*   **Skipping Refactoring:** If you only do Red-Green, you accumulate technical debt.
*   **Slow Tests:** If tests are slow, developers won't run them frequently, defeating the purpose of the tight feedback loop.

## 6. Behavior Driven Development (BDD)

BDD is an evolution of TDD that focuses on the behavior of the application from the end-user's perspective. It uses a natural language syntax (Gherkin) to describe tests.

*   **Focus:** "What" the system should do, rather than "how" it is implemented.
*   **Language:** Uses `Given`, `When`, `Then` syntax.
*   **Tools:** Cucumber, SpecFlow.

### Example (Gherkin)
```gherkin
Feature: User Login

  Scenario: Successful Login
    Given the user is on the login page
    When the user enters valid credentials
    Then the user should be redirected to the dashboard
```

[[programming/software-testing-basics]]
[[programming/refactoring-techniques]]
[[programming/agile-methodology]]