Having spent a fair amount of time using unit test frameworks, you inevitable come up with a few tricks to make things more efficient. This post simply describes some of those tricks that I’ve picked up while testing code. The examples will be done with NUnit versions 2.6, but I’ve applied these same techniques to MBunit, XUnit, and am currently using them with the NUnit beta 3.0.
Test Ids to Increase Readability
Often, some units under test have a wide variation of input parameters and require many test cases to effectively beat on the code. Take the following example. Though it is contrived, it demonstrates situations I’ve had to handle in almost every project I’ve been involved with. The class below has a single method to verify some input string based on a defined rule set.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
Effective unit tests for the code above would need to test for cases returning true, false, and error cases, (I would normally generate the tests before the method, but for simplicity I will dispense with preaching TDD). For the true cases, here are several approaches using NUnit, (for brevity’s sake, I have not included all possible variations of input parameters to test for true).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
Both test methods in the fixture above perform the same tests, but each handles the multiple test inputs using different features of NUnit. You will notice a unique id associated with each test input, this is one of those ‘tricks’ I picked up. By assigning a unique id for test methods with multiple inputs, you can quickly find a specific test case. For example, here is an image of the NUnit runner output with ids and it is easy to identify in the code the specific test cases which fail.
When should you use unique ids with your parameterized test cases? This is completely up to your style of test kung-fu. If it helps your more efficiently beat on your code then by all means do it.
Overriding ToString() in Complex Parameters
While NUnit recognizes the individual test parameters and consequently each individual test cast, it does not effectively present this information to the user. For example, lets say there is an additional Verify() method that takes in a custom object called UserItem as a parameter. UserItem is a stand in for any POCO that you may need to validate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
In order to set up multiple test cases for this new method, we are unable to use the TestCaseAttribute out of the box since we cannot embed a UserItem constructor in an attribute. But, we can still use the TestCaseSourceAttribute like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
When you look at the output you will notice that although NUnit identifies the individual test cases, it displays each UserItem by the default ToString() implementation:
To improve the readability of each test, you can override the ToString() method:
1 2 3 4 5 6 7 8 9 10
NUnit uses the parameters to differentiate individual test cases. If you do override ToString(), to preclude NUnit from skipping test cases it considers duplicates then you need to ensure the override of ToString() returns unique values for each object, or use the separate id parameter technique mentioned earlier. Using the id will guarantee each input results in an individual test even if the ToString() override does not provide unique strings for each object.
Just a few tricks that may help you in your code writing endeavors. Test early & test often: the more you beat on your code the stronger is the force in you.