If you come across this post it may be because you’ve only started reading about unit tests and are thinking of implementing them (way to go!), or perhaps want a clearer definition of what it is and what it actually makes a good unit test, whatever your reason is I will hopefully be able to shed some light on it.
What is actually a unit test?
In plain English, a unit test can be defined as a short piece of code that we write in order to test another method/function by specifying a known input and obtaining an expected output.
Well, that may not have been the best definition but maybe an example would help.
Show me the code!
Let’s say we have a method that is meant to provide us with some sort of calculation (i.e. the total price after a 10% discount has been applied).
public static class Price
private const decimal _discount = 0.10M;
public static decimal CalculateTotalPrice(decimal totalPrice)
How do we know this code works as expected? (I know this is a really simple example but let’s image there are some complicated calculations involved). To test it we could for example have a web page that at the click of a button calls this function and displays the results, or have a console application that can call that function and display the results on the console (wow that sounds like a lot of effort, I think I’ll pass)
How about running a unit test? writing a unit test should not take long and we can get instant feedback, let’s give that a go
public class PriceTests
public void CalculateTotalPrice_PriceGiven_ShouldReturnCorrectTotalPrice()
const decimal expectedTotalPrice = 90.00M;
var actualTotalPrice = Price.CalculateTotalPrice(100.00M);
After running this unit test we can see that it fails !, but why? because in my CalculateTotalPrice method I’m returning the total discounted value, not the total price after the discount has been applied (yes silly mistake)
See what I mean by instant feedback? had I not run this unit test I would probably have received a call later on from my boss, and certainly not a happy one.
After fixing my method I re-run the unit test and I get a nice green mark, hooray!
So… What makes a good unit test?
You’ve probably guessed a couples of answers to this question by this point, let’s enumerate them:
- Unit tests should be easy to write
- Unit tests should be automated: (even though we didn’t cover automated unit tests in this blog they can run automatically as part of your build)
- Unit tests should be repeatable: kind of what we just said above, it just means that we can run it over and over again with each build
- Unit tests should add value to the product/project: Don’t just write unit tests for the sake of it, test the business logic of your application and not a function that adds up two numbers (that makes my example a bad unit test but you get the idea)
- Unit tests should be independent to all others: if a unit test depends on another, then is not a unit test
- Unit tests should test a unit of work (that is a single isolated method/function) and not more than that (otherwise it may be an integration test)
- Unit tests should be clearly named following a pre-define naming convention (here is an example of unit test naming conventions)
P.S. we didn’t talk about TDD (Test Driven Development) as this would extend the original scope to this blog post but I will publish a blog post about that soon.
In the meantime, do you have any other ideas of what makes a good unit test?