Section 5 of 5

Test-Driven Development (TDD)

🎯 What You'll Learn

  • What is TDD
  • Red-Green-Refactor cycle
  • Benefits of TDD
  • TDD workflow
  • Practical TDD example

What is TDD?

Test-Driven Development (TDD) is a development approach where you write tests before writing the implementation code.

Red-Green-Refactor Cycle

The TDD Cycle
  1. 🔴 Red: Write a failing test
  2. 🟢 Green: Write minimal code to make it pass
  3. 🔵 Refactor: Improve code while keeping tests green

Benefits of TDD

  • Better design: Forces you to think about API before implementation
  • Fewer bugs: Catches issues early
  • Confidence: Refactor without fear
  • Documentation: Tests show how code should be used
  • Testable code: Naturally leads to better architecture

TDD Workflow Example

Step 1: 🔴 Red - Write Failing Test

DiscountCalculatorTests.cs C#
public class DiscountCalculatorTests
{
    [Fact]
    public void CalculateDiscount_TenPercent_ReturnsDiscountedPrice()
    {
        // Arrange
        var calculator = new DiscountCalculator();

        // Act
        var result = calculator.CalculateDiscount(100, 0.1m);

        // Assert
        Assert.Equal(90, result);
    }
}

// This test FAILS - DiscountCalculator doesn't exist yet!

Step 2: 🟢 Green - Make Test Pass

DiscountCalculator.cs C#
public class DiscountCalculator
{
    public decimal CalculateDiscount(decimal price, decimal discountPercent)
    {
        return price - (price * discountPercent);
    }
}

// Test now PASSES! ✅

Step 3: 🔵 Refactor - Improve Code

Add More Tests C#
[Theory]
[InlineData(100, 0.1, 90)]
[InlineData(50, 0.2, 40)]
[InlineData(200, 0.5, 100)]
public void CalculateDiscount_VariousInputs_ReturnsCorrectPrice(
    decimal price, decimal discount, decimal expected)
{
    var calculator = new DiscountCalculator();
    
    var result = calculator.CalculateDiscount(price, discount);
    
    Assert.Equal(expected, result);
}

InvenTrack TDD Example

Let's build a stock validator using TDD.

🔴 Red: Write Test

StockValidatorTests.cs C#
[Fact]
public void IsInStock_QuantityGreaterThanZero_ReturnsTrue()
{
    var validator = new StockValidator();
    var product = new Product { Quantity = 10 };

    var result = validator.IsInStock(product);

    Assert.True(result);
}

🟢 Green: Implement

StockValidator.cs C#
public class StockValidator
{
    public bool IsInStock(Product product)
    {
        return product.Quantity > 0;
    }
}

🔴 Red: Add Edge Case

Test Zero Quantity C#
[Fact]
public void IsInStock_QuantityZero_ReturnsFalse()
{
    var validator = new StockValidator();
    var product = new Product { Quantity = 0 };

    var result = validator.IsInStock(product);

    Assert.False(result);
}

// Test PASSES - implementation already handles this! ✅

TDD Best Practices

  • Start simple: Begin with simplest test case
  • One test at a time: Focus on one behavior
  • Minimal code: Write just enough to pass
  • Refactor often: Keep code clean
  • Fast tests: Tests should run quickly
  • Descriptive names: Test names explain behavior

Key Takeaways

  • TDD: Write tests before code
  • Red-Green-Refactor: The TDD cycle
  • 🔴 Red: Write failing test
  • 🟢 Green: Make it pass
  • 🔵 Refactor: Improve code
  • Benefits: Better design, fewer bugs, confidence
🎉 Part XVI Complete!

Congratulations! You've completed Part XVI: Testing. You now understand:

  • ✅ Unit testing with xUnit ([Fact]/[Theory], assertions)
  • ✅ Mocking with Moq (Mock<T>, Setup, Verify)
  • ✅ Integration testing (in-memory database)
  • ✅ WebApplicationFactory (testing HTTP endpoints)
  • ✅ Test-Driven Development (Red-Green-Refactor)

You can now write comprehensive tests for your ASP.NET Core applications! ✅