April 5, 2017
How to Use TDD with C#: Step-by-Step Scenarios
Continuing from our Introduction of Using Test Driven Development with C#:
Let’s follow TDD
From the SUT we have, let’s focus on a piece of production code.
The IsAccountActive() function is supposed to return the account status of a provided account #. We will be writing tests to verify the behavior and then fixing the production code to make the Tests Pass and repeat the same with more scenarios and possibilities (use case, business rules/validations and so on.)
Scenario #1: To test this production code we add [TestMethod] TestAccountStatus_Active_Success() to our TDD Suite (Unit Test Project).
The test failed, because we have not yet implemented the production code.
Let’s implement the IsAccountActive() in the code to make the test pass. New code additions are:
Repeat it with more validation and business rules
What would be the response from the caller of the API if null is passed as an account number? Let’s say the API must throw an ArgumentException.
Scenario #2: To verify this behavior add a Test First and we will use the Microsoft Test provided attribute [ExpectedException(typeof(ArgumentException))] to verify the exception the caller will be expecting in a real situation.
Since our production or development code is not yet ready to handle this scenario, this test is supposed to fail and the reason is shown on the right-side panel (I underlined in Green).
Refactor-Test and Test Further More
Let’s refactor our production or development code to make the TestAccountStatus_ArgumentException_Success() test case pass. The new code additions are highlighted in Green.
Now let’s re-run the test TestAccountStatus_ArgumentException_Success() and observe the results.
Scenario #3: Now let’s verify the behavior if we pass White Space ” ” as an account number and expect an ArgumentException is thrown. We will use the [ExpectedException(typeof(ArgumentException))] attribute.
Run the test and you will see the result as shown in the image below:
Let’s refactor the code and it will look such as shown below. The new code additions are:
Let’s re-run the test and observe the results:
The test still fails, though we added the right condition to verify WhiteSpace.
Let’s Debug the Test
Add a breakpoint to the failing test at the line where you are invoking the production code as in the following:
Right-click in the code-editor and select Debug Tests as shown in the image below.
This will start Test Execution in Debug mode and you will see a screen as shown below:
Press F11 and you will be taken to the Production code to debug it further.
Press F10 to Step-Over and keep pressing F10 until the Debug session ends and you will observe the flow as shown below:
So what we discovered is that the first condition accNumber!= null is true even if WhiteSpace has been passed as the account number. Hence, it’s another opportunity to refactor the production code and re-run the Test(s). The new code additions are:
After each Test addition or refactoring session, re-run the tests in the Test Explorer to ensure that previously passing tests haven’t begun failing, in other words there is no Collateral Damage.