One assert per test, really.

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
  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 ?

8 Responses to “One assert per test, really.”

  1. Anonymous says:

    This comment was originally posted onTwitter

  2. Anonymous says:

    This comment was originally posted onTwitter

  3. Anonymous says:

    This comment was originally posted onTwitter

  4. Anonymous says:

    This comment was originally posted onTwitter

  5. owehrens says:

    new blog post: http://bit.ly/lVR2YU

    This comment was originally posted onTwitter

  6. +1: One Assert Per Test (OAPT) — must-have or bull**** for the test-obsessed? RT @owehrens: new blog post: http://bit.ly/lVR2YU

    This comment was originally posted onTwitter

  7. owehrens says:

    New Blog Post: http://bit.ly/lVR2YU Do one assert per test only.

    This comment was originally posted onTwitter

  8. Good way for the majority of small test. And for orchestrating services with multiple interactions on delegate objects I prefer another test-pattern. Test the “workflow” in one well named test method and state all assertions encapsulated methods.
    @Test
    void an_uploaded_document_will_be_saved_and_the_id_assigned_to_the_logged_in_user() {
    // given

    // when

    // then
    assertDocumentSaved(document);
    assertDocumentAssignedToUser(document, “joe”);
    }

Leave a Reply

Additional comments powered byBackType