
608
Chapter 24 Test Organization Patterns
How It Works
The solution, of course, is to factor out the common logic into a utility method.
When this logic includes all four parts of the entire Four-Phase Test (page 358)
life cycle—that is, fi xture setup, exercise SUT, result verifi cation, and fi xture
teardown—we call the resulting utility method a Parameterized Test. This kind
of test gives us the best coverage with the least code to maintain and makes it
very easy to add more tests as they are needed.
If the right utility method is available to us, we can reduce a test that would
otherwise require a series of complex steps to a single line of code. As we detect
similarities between our tests, we can factor out the commonalities into a Test
Utility Method (page 599) that takes only the information that differs from test to
test as its arguments. The Test Methods pass in as parameters any information
that the Parameterized Test requires to run and that varies from test to test.
When to Use It
We can use a Parameterized Test whenever Test Code Duplication (page 213)
results from several tests implementing the same test algorithm but with slightly
different data. The data that differs becomes the arguments passed to the Param-
eterized Test, and the logic is encapsulated by the utility method. A Parameterized
Test also helps us avoid Obscure Tests (page 186); by reducing the number of
times the same logic is repeated, it can make the Testcase Class (page 373) much
more compact. A Parameterized Test is also a good steppingstone to a Data-
Driven Test (page 288); the name of the Parameterized Test maps to the verb or
“action word” of the Data-Driven Test, and the parameters are the attributes.
If our extracted utility method doesn’t do any fi xture setup, it is called a
Verifi cation Method (see Custom Assertion on page 474). If it also doesn’t
exercise the SUT, it is called a Custom Assertion.
Implementation Notes
We need to ensure that the Parameterized Test has an Intent-Revealing Name
[SBPP] so that readers of the test will understand what it is doing. This name
should imply that the test encompasses the whole life cycle to avoid any con-
fusion. One convention is to start or end the name in “test”; the presence of
parameters conveys the fact that the test is parameterized. Most members of
the xUnit family that implement Test Discovery (page 393) will create only
Testcase Objects (page 382) for “no arg” methods that start with “test,” so this
restriction shouldn’t prevent us from starting our Parameterized Test names
with “test.” At least one member of the xUnit family—MbUnit—implements
Parame-
terized Test