What to Expect of a Test Case
- It prepares some scenario
- It executes the system under test
- It makes some concrete assertions of an answer that was predicted at the time the test was constructed
What if you see…
Here’s a test. It’s in Java, but it might be in any language.
What’s wrong with the above?
It’s only doing one of the three things of prepare, act and assert. It’s just asserting. There’s something else going somewhere else on to make this a meaningful test. It’s more of a fragment of a test case, than a full test case.
Is this Wrong?
I’m sure I’ve written things like the above test and been happy with them… but before we assume it’s likely to be ok, let’s look at what it might be a sign of. If these things can be avoided, then the tests will be better and clearer turned back into the 1-2-3 of prepare, act and assert, or given, when and then.
Why is my Setup Absent?
- Maybe we have to set up the system consistently for all tests, and we want to assert the initial state for any test – this is ok, but may need commenting.
- Maybe we over-cooked the setup so that it stole some of the code from a test case, leaving only the assert to write – this is like the previous example, except there are no other tests that need this common set up
- Maybe our tests set up a global state and then do a series of separate assertions on that state – this is a confusing pattern as it’s one test case, divided into several – perhaps better expressed using something like Cucumber, rather than a unit testing framework like JUnit, TestNG, mocha, Jasmine, etc.
- Maybe each of our tests is in a causal chain – this can be useful if the cost of running tests is high, so we need to be careful of wasting resource re-executing things, but it makes things harder to understand.
A test that’s self contained is easy to understand. If it needs a shared setup, that’s also quite conventional. If it’s part of a structure where the execution of the test is in multiple locations, then although the assertion-only test looks simpler, the test as a whole is much more complex and should be simplified if possible.
Opinions expressed by Java Code Geeks contributors are their own.