TotT: The Stroop Effect
How quickly can you...
- ...read all 25 words out loud: RED, GREEN, BLUE, ... (Try it now!)
- ...say all 25 colors out loud: GREEN, YELLOW, WHITE... (Try it now!)
Did the second task require more time and effort? If so, you're experiencing the Stroop Effect, which roughly says that when a label (in this case, the word) is in the same domain as its content (the color) with a conflicting meaning, the label interferes with your ability to comprehend the content.
What does this have to do with testing? Consider the following code:
public void testProtanopiaColorMatcherIsDistinguishable() {
ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA);
assertFalse(“BLUE and VIOLET are indistinguishable”,
colorMatcher.isDistinguishable(Color.BLUE, Color.VIOLET));
}
ColorMatcher colorMatcher = new ColorMatcher(PROTANOPIA);
assertFalse(“BLUE and VIOLET are indistinguishable”,
colorMatcher.isDistinguishable(Color.BLUE, Color.VIOLET));
}
When this test fails, it produces a message like this:
Failure: testProtanopiaColorMatcherIsDistinguishable:
Message: BLUE and VIOLET are indistinguishable
Message: BLUE and VIOLET are indistinguishable
Quick: what caused this error? Were BLUE and VIOLET indistinguishable, or not? If you're hesitating, that's the Stroop Effect at work! The label (the message) expresses a truth condition, but the content (in assertFalse) expresses a false condition. Is the ColorMatcher doing the wrong thing, or is the test condition bogus? This message is wasting your valuable time! Now consider this slight alteration to the test name and test message:
Failure: testProtanopiaColorMatcherCannotDistinguishBetweenCertainPairsOfColors
Message: BLUE and VIOLET should be indistinguishable
Message: BLUE and VIOLET should be indistinguishable
Do you find this clearer? Protanopia (reduced sensitivity to the red spectrum) causes certain pairs of colors to be indistinguishable. BLUE and VIOLET should have been indistinguishable, but weren't.
Here are some things to keep in mind when writing your tests:
- When someone breaks your test – will your test name and message be useful to them?
- Opinionated test names like testMethodDoesSomething can be more helpful than testMethod.
- Great test messages not only identify the actual behavior,but also the expected behavior.
- Should is a handy word to use in messages – it clarifies what expected behavior didn't actually happen.
Remember to download this episode of Testing on the Toilet and post it in your office. Permalink | Links to this post |
TotT: Refactoring Tests in the Red
Thursday, April 26, 2007 3:28 AM
With a good set of tests in place, refactoring code is much easier, as you can quickly gain a lot of confidence by running the tests again and making sure the code still passes.As suites of tests grow, it's common to see duplication emerge. Like any code, tests should ideally be kept in a state that's easy to understand and maintain. So, you'll want to refactor your tests, too.
However, refactoring tests can be hard because you don't have tests for the tests.
How do you know that your refactoring of the tests was safe and you didn't accidentally remove one of the assertions?
If you intentionally break the code under test, the failing test can show you that your assertions are still working. For example, if you were refactoring methods in
CombineHarvesterTest
, you would alter CombineHarvester
, making it return the wrong results.Check that the reason the tests are failing is because the assertions are failing as you'd expect them to. You can then (carefully) refactor the failing tests. If at any step they start passing, it immediately lets you know that the test is broken – undo! When you're done, remember to fix the code under test and make sure the tests pass again.
(
revert
is your friend, but don't revert the tests!)Let's repeat that important point:
When you're done...remember to fix the code under test!
Summary
- Refactor production code with the tests passing. This helps you determine that the production code still does what it is meant to.
- Refactor test code with the tests failing. This helps you determine that the test code still does what it is meant to.
No comments:
Post a Comment