-
When/Then Unit Test Naming Pattern
No CommentsGiving meaningful names to unit tests is critically important to quality unit tests. Unit tests classes often contain a large set of test methods and it can be challenging to distinguish from between tests because of the small permutations of the condition, the action, or the result.
I was clued in to the When/Then naming pattern when working with Patterns & Practices at Microsoft. I’ve seen this naming pattern work well across both client and web projects containing several hundred unit tests for all kinds of classes. I’ve adopted for all my unit tests with success.
The pattern
When<ActionAndCondition>Then<ExpectedResult>.
For example, a unit test that verifies the PropertyChanged event is raised when the Name property is changed might read: “WhenNameSetToDifferentValueThenPropertyChangedRaised”.
Benefits
The When/Then naming pattern works well because it includes the action, condition, and result. By putting the key semantic information in the name of the unit test there is no longer a need for method or code comments explaining what is being tested.
The When/Then naming pattern has several other benefits.
• It naturally focuses each unit test on verifying one result. This encourages writing atomic tests an discourages integration tests posting as unit tests.
• It helps evaluate the purpose of each member of a class by thinking about the conditions and results. This also illuminates other unit test permutations.
• It helps describe the test independent of the code. This helps when the test code doesn’t make the condition or result as obvious as the reader would like. Most often this is due to mocking frameworks, verifying complex data, or other aspects of the test obfuscate the test’s purpose.Tips
Some tips to consider when applying the pattern:
• To keep the names a little shorter, you can remove passive verbs. “WhenNameIsSetToDifferentValueThenPropertyChangedIsRaised” becomes just WhenNameSetToDifferentValueThenPropertyChangedRaised. At one point I was tempted to remove the “When” and the “Then” and separate them with an underscore, but I found that it made the test name harder to read for comprehension.
• Use standard verbs in your test names. I use “Set” for properties, “Called” for methods, and “Raised” for events. I avoid synonyms like Updated, Recalculated, Invoked, or Fired.
• Often a set of tests are focused on single part of your class (such as the Name property). I use #region to group test cases that are related. This helps me avoid injecting excessive class structure into my test names and makes it easy to evaluate the set of tests when working toward 100% code coverage.Additional Examples
Here are some additional examples from my own code:
#region Name Tests
WhenNameSetThenValueSet
WhenNameSetToDifferentValueThenPropertyChangedRaised
WhenNameSetToSameValueThenPropertyChangedNotRaised
WhenNameSetToNullThenExceptionThrown
WhenNameSetToEmptyThenValueSet#endregion
#region UpdateStatistics Tests
WhenUpdateStatisticsCalledThenTotalPriceSet
WhenUpdateStatisticsCalledThenAveragePriceSet#endregion
-
Leave a comment
Your email address will not be published.