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
- 🔴 Red: Write a failing test
- 🟢 Green: Write minimal code to make it pass
- 🔵 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! ✅