To follow up with my last blog post, I am going to talk about how to get started writing unit tests. In my last blog post I talked about what a unit test is and why unit testing is important. If you’re ready to start writing unit tests, read on to learn how we do that.
When learning to write unit tests, a pattern that we typically follow is Arrange, Act, Assert. In the first step, Arrange, we setup everything needed for running the tested code. This includes any initialization of dependencies, mocks and data needed for the test to run. Next we Act by invoking the code under test. Finally we Assert by specifying the pass criteria for the test, which fails it if not met.
Here is an example of a simple unit test in C#:
public void ShouldAddTwoNumbers()
var calculator = new Calculator();
var sum = calculator.Add(0, 1);
In this example you can see we have our Arrange by creating a `new Calculator` class, we act by calling `calculator.Add()` and we Assert by using the NUnit `Assert.That(…), Is.EqualTo(1);`
Some common mistakes I see when developers first start writing unit tests are:
- Test passes but is not testing the actual feature
- Testing irrelevant things
- Testing multiple things in assertions
Let’s talk about these more in depth. The first one can be solved easily, but let’s figure out what it means. Say you write a test, and it passes, you move on to the next test because your test is green, but why did that test pass so quickly? Are you actually implementing that functionality in your code? If so, try to make the test fail. Change the implementation of the production code or change the Assert and see if your test still passes. If it does, ask yourself “what am I actually testing here?” and write a test for that. If your test never fails, how will it ever tell you anything about your code. Tests help us pinpoint things in our code that have gone wrong.
Tests help us pinpoint things in our code that have gone wrong.
If your test can’t do that, it may not be a good test.
The second one, testing irrelevant things happens when a developer tests something but it may not necessarily be the correct thing. I always recommend asking yourself: why am I testing this. If the test fails, what does that tell me as a developer? If you can’t think of a good answer, your test may be irrelevant.
The third is by far the most common. I see developers that want to input every single number between 0 and 4000 and make sure the output is correct. The problem with this kind of test as a unit test is that, first, we want our unit tests to be fast and second, you’re basically asking the same question 4000 times. If you are testing the number 1, why is it also important to test the number 2? You’re essentially testing the same thing. If you truly believe 1 and 2 are different test cases, make sure your test explains why those tests are important.
If you truly believe 1 and 2 are different test cases, make sure your test explains why those tests are important.
For example, you could say one tests odd numbers and one tests even numbers, but if you cannot think of a reason why they are different, then one test will probably suffice.
If you try to avoid these three common pitfalls for writing unit tests and follow the Arrange Act Assert pattern, you’ll be writing good unit tests in no time.