Single Assertions Do Not (Necessarily) Check Single Expectations

According to him, we should only test one expectation at a time; so, we can only have one assertion per test.

Now, I completely agree with the “test only one expectation at at time” philosophy. However, I completely deny that that implies we should only have one assertion per test.

Unfortunately, I’ve noticed that a large portion of developers buy into this mantra; and under some circumstances, it actually has very good results. However, it also has the potential to block developers from writing clear and meaningful tests.

Confusing Strategy for Tactics

Suppose that I wanted to remove duplicate items in a javascript array. The following function could provide that functionality.

In order to test the “uniq” function, I could use the following jasmine code

Superficially, this test seems to follow the “one expectation; one assertion” rule. However, consider what it means for the test to fail.

What postconditions could make this a failing unit test? From the top of my head, I can think of the following scenarios

The result is not an array

The array has more or less than 4 elements in the list

Index zero of the array is not 0

Index one of the array is not 1

Index two of the array is not 2

Index three of the array is not 3

This implies that the following unit test is at least as powerful.

Tasting the Forbidden Fruit

Even though the first unit test had only one assertion, it actually checked at least 6 different postconditions.

This proves that the “one expectation; one assertion” rule does not work (in general); so, feel free to use as many assertions that you want and need.

Personally, I find that aiming for “one expectation; one assertion” makes me write cleaner tests. However, I’ve also found situations where it makes me write complex or cumbersome tests. My milage using “one expectation; one assertion” varies depending on the type of test.

I would recommend everyone at least try to aim for the ideal of “one expectation; one assertion”, but only as far as it helps you write good tests. At that point, you should throw it away.