A fixture is the set of input values used to exercise the component under test. As you may have noticed, fixtures are the stars of the test method, as they derive naturally from the test cases we engineer using any of the techniques we have discussed.
When testing more complex components, you may need to build several different fixtures: one for each partition you want to exercise. These fixtures can then become complex. And to make the situation worse, while tests are different from each other, their fixtures may intersect. Given this possible intersection among the different fixtures, as well as the difficulty with building complex entities and fixtures, you may decide to declare a large fixture that works for many different tests. Each test would then use a small part of this large fixture.
While this approach may work, and the tests may correctly implement the test cases, they quickly become hard to maintain. Once a test fails, you will find yourself with a large fixture that may not be completely relevant for that particular failing test. You then must manually filter out parts of the fixture that are not exercised by the failing test. That is an unnecessary cost.
Making sure the fixture of a test is as specific and cohesive as possible helps you comprehend the essence of a test (which is, again, highly relevant when the test starts to fail). Build patterns (focusing on building test data) can help you avoid generic fixtures. More specifically, the Test Data Builder pattern we discussed is often used in the test code of enterprise applications. Such applications often deal with creating complex sets of interrelated business entities, which can easily lead developers to write general fixtures.
Leave a Reply