We all know that Unit tests are vital for our software projects.
It’s thanks to them that we are able to say with certainty (ok, with a high degree of certainty) that our codebase does what it is supposed to do. Moreover their presence allow us to confidently change existing code knowing that if we mess up something, they will let us know by failing
I strongly agree with the following quote
legacy code is code without tests
– Michael Feathers
In fact no matter how well written our code is, without tests we cannot change its behaviour neither quickly nor verifiably.
To be useful, unit tests should cover all possible scenarios for the unit they are testing, which means they should not only go through the happy flow, but they should also test for exceptions (in case there are any), nullability and different range of values.
For this last specific case today I wanted to talk about Parameterization, which is a fancy word to say Running the same test using a series of different input
To better understand this very useful concept let’s imagine we wrote the following Kotlin function (same concept applies to Java as well)
Now, this example, although silly, provides room to see how the approach can differ between parameterized and non parameterized tests
Let’s begin unit testing this function the traditional way:
This could be a possible test, tackling all possible scenarios that the function could address.
This though has two drawbacks, first is a bit fragmented, and although in this case (for post brevity’s sake) it dos not show, imagine having to prepare every test with some mocks and other repetitive operations. Second, these tests do not account for many other scenarios, like what happens for numbers lower than -15? or between -9 and -1? etc.
Of course we could have written a line for each of these cases and have this class explode… OR, we could try our parameterized tests
So how do we go about them? First of all we need to run the test with the Parameterized class, which is placed before the class
Then in the constructor of this class we need to put as parameters the values we expect our test to use. Just to have it simple we can say that our tests will need an input and a result to be checked for equality.
Lastly, we want to define the set of values that those parameters are gonna have. Let’s just say we want to run the test providing as input the numbers from 1 to 4, and checking their result. So we will write
In the end you will have a class like this
And if run this will lead to the same test running 4 times, each of which with a different couple input/result
Of course this can be expanded to cover also the other cases with negative numbers and with the 0 and the exception it throws (which can be added as one parameter for the test)
Can you come up with a way to do it? If not you can always take inspiration from here
Leave a Comment