maxheapsize.com test it. code it. ship it.

One Assert Per Test, Really.

Posted on in Test | Comments

Recently I was debugging my code and I could not see why my test was failing. It took me about 20 minutes to see that I violated one rule I try to follow. One assert per test.

After tweeting it I got some reaction ranging from ‘this is a very silly guideline’ to ‘Tests should test one thing. Often one assertion, but not always.’. I, of course, tend to agree the latter one.

So what’s in for you when you use one assert per test? What are the problems?

One the plus side:

  1. If a tests fails, you know what is wrong.
  2. You know how to name your test method, since you are just testing one thing.
  3. It plays very nicely along with Test Driven Development, test and implement one feature at a time and make it work.
  4. If you change one thing in your code, at best only one unit test will fail (ok, this one is hard but possible).
  5. With multiple asserts you fix one assert which is broken and only then you see that the next one is broken too.

The other side:

  1. You need to think more about the test setup, it should be possible to really just test one thing and mock the rest. Think, design for testability.
  2. More (test) code.
  3. It looks like it is easier to have multiple asserts.

I try to do one assert per test. Once in a while my code reviewer catches one of the multiple asserts per test. Some times this is ok, some times I fix it.

My rule is to have one assert per test almost every time. But try it at least.

And while on it, use a better assert lib. Both JUnit and TestNG Assert confuse the heck out of me. Ansgar introduced FEST Fluent Assertions Module to our team. Now my tests look something like:

Test.java
1
2
3
4
5
6
7
  @Test
  public void testAddSubscriber() {
    TestEventSubscriber eventSubscriber = new TestEventSubscriber();
    eventPublisher.registerSubscriber(eventSubscriber);
    assertThat(eventPublisher.getEventSubscribers()).
       containsOnly(eventSubscriber);
  }

If you don’t know it, try it. I do like it.

Which thoughts do you have ?

Comments