Lesson 1
Lesson: Introduction to TDD with C#: What, Why, and How
Introduction to TDD

Welcome to the first lesson of our course on Test Driven Development (TDD) in C# using xUnit. TDD is an iterative software development process where tests are written prior to developing the actual functionality. This approach helps developers focus on the requirements first, leading to more reliable and maintainable code.

In this lesson, we'll introduce you to the essential elements of TDD, including the Red-Green-Refactor cycle, which serves as the core structure of this methodology. We'll be utilizing tools specially suited for C#: xUnit, a popular testing framework that is robust and integrates well with C#. These tools are excellent for defining and running tests in C#. Let's start by investigating TDD’s core components with a hands-on example.

Writing the First Test (Red)

The TDD process begins with writing a test that fails, marking the "Red" phase. This step allows you to crystallize what the code should achieve before writing the actual implementation. Let's write a test for a Sum method that should eventually add two numbers.

Create a file named MathTest.cs in the Tests directory:

C#
1using Xunit; 2 3public class MathTest 4{ 5 [Fact] 6 public void Sum_AddsTwoNumbers_Correctly() 7 { 8 var math = new Math(); 9 Assert.Equal(5, math.Sum(2, 3)); 10 } 11}

This test script:

  • Uses [Fact] to denote a single test case.
  • Instantiates a Math class.
  • Calls the Sum method and checks if the result equals 5.

Attempt to run this test although the Math class and Sum method are not yet implemented. It will result in a compilation error, reflecting the "Red" stage, signaling the requirement for implementation.

Expected output:

1MathTests.cs(8,20): error CS0712: Cannot create an instance of the static class 'Math'

This is a normal failure, illustrating that our test is effectively identifying unimplemented features.

Making the Test Pass (Green)

Our next objective is to write the simplest code possible to make the test pass — the "Green" step. In TDD, it means implementing minimal functionality to satisfy the test conditions. Let’s define the Sum method in a new file Math.cs under the Src directory:

C#
1public class Math 2{ 3 public int Sum(int a, int b) 4 { 5 return 5; 6 } 7}

This version seems superficial since it doesn't actually add two numbers, but it highlights the TDD focus on passing the test with minimal implementation. By doing so, we've met the test condition.

Re-running the test will produce the following result:

1Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: < 1 ms

Seeing the test pass confirms our code meets the given test scenario. Future test cases will guide us to refine the implementation.

Refactoring and Code Improvement (Refactor)

The last step, "Refactor," involves refining the code while ensuring existing behavior remains unchanged. In this instance, our Sum function is quite efficient, but we can improve our test readability by separating the execution from the assertion. This involves extracting the output of the Sum function into a variable:

C#
1using Xunit; 2 3public class MathTest 4{ 5 [Fact] 6 public void Sum_AddsTwoNumbers_Correctly() 7 { 8 var math = new Math(); 9 var result = math.Sum(2, 3) 10 Assert.Equal(5, result); 11 } 12}

This small refactoring illustrates how minor adjustments can enhance clarity, as it isolates the act (execution) from the assert (verification). When dealing with more complex functions, refactoring might involve breaking down a function, renaming variables for clarity, or improving test readability. Our Red-Green-Refactor cycle for this example is now complete.

Review and Next Steps

In this lesson, we've explored the basic principles of TDD using the Red-Green-Refactor workflow with C#, and xUnit. Let's recap:

  • Red: Start by writing a test that initially fails.
  • Green: Add minimal code to pass the test.
  • Refactor: Improve the code, ensuring all tests still pass.

As you practice TDD in upcoming exercises, you’ll reinforce your understanding and gain the ability to craft robust, maintainable C# code. Remember to apply these concepts in your coding routine to boost code quality and reliability.

With this foundation, you’re prepared to tackle more complex scenarios in future lessons. Continue honing your skills to excel in TDD practices using C#.

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.