DevOps Zone is brought to you in partnership with:

Senior Java developer, one of the top stackoverflow users, fluent with Java and Java technology stacks - Spring, JPA, JavaEE. Founder and creator of http://computoser.com and http://welshare.com . Worked on Ericsson projects, Bulgarian e-government projects and large scale recruitment platforms. Member of the jury of the International Olympiad in Linguistics and the Program committee of the North American Computational Linguistics Olympiad. Bozhidar is a DZone MVB and is not an employee of DZone and has posted 81 posts at DZone. You can read more from them at their website. View Full User Profile

Make Tests Fail

06.15.2014
| 7623 views |
  • submit to reddit

This is about a simple testing technique that is probably obvious, but I’ll share it anyway.

In case you are not following TDD, when writing tests, make them fail, in order to be sure you are testing the right thing. You can make them fail either by changing some preconditions (the “given” or “when” parts, if you like), or by changing something small in the code. After you make them fail, you revert the failing change and don’t commit it.

Let me try to give an examples why this matters.

Suppose you want to test that a service triggers some calculation only in case a set of rules are in place.
(using Mockito to mock dependencies and verify if they are invoked)

@Test
public void testTriggeringFoo() {
Foo foo = mock(Foo.class);
StubConfiguration config  new StubConfiguration();
config.enableFoo();
Service service = new Service(foo, config);
service.processOptionallyTriggeringFoo();
verify(foo).calculate(); //verify the foo calculation is invoked
}

That test passes, and you are happy. But it must fail if you do not call enableFoo(). Comment that out and run it again – if it passes again, there’s something wrong and you should investigate.

The obvious question here is – shouldn’t you have a negative test case instead (i.e. test that’s testing the opposite behaviour – i.e. that if you don’t enable foo, calculate() is not called)? Sometimes, yes. But sometimes it’s not worth having the negative test case. And sometimes it’s not about the functionality that you are testing.

Even if you code is working, your mocks and stubs might not be implemented correctly, and you may think you are testing something that you aren’t actually testing. That’s why making a test fail while writing it is not about the code you are testing, it’s about your test code. In the above example, if StubConfiguration is ignoring enableFoo(), but has it set to true by default, then the test won’t fail. But in this case the test is not useful at all – it always passes. And when you refactor your code later, and the condition is no longer met, your test won’t indicate that.

So, make sure your test and test infrastructure is actually testing the code the way you intend it to, by making the test fail.

Published at DZone with permission of Bozhidar Bozhanov, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Robert Brown replied on Wed, 2014/06/18 - 8:59am

I would say you need two tests here one with and one without the enableFoo().  

If it's worth testing once it's worth leaving the test in place.  IMHO.  


Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.