TDD – How Granular Should TDD Tests Be?

tddunit testing

During TDD training based on medical software case we are implementing the following story: "When user presses Save button, system should add patient, add device and add device data records".

The final implementation will look something like this:

if (_importDialog.Show() == ImportDialogResult.SaveButtonIsPressed)
{
   AddPatient();
   AddDevice();
   AddDeviceDataRecords();
}

We have two ways to implement it:

  1. Three tests where each verifies one method (AddPatient, AddDevice, AddDeviceDataRecords) was called
  2. One test which verifies all three methods were called

In the first case if something wrong is happend to if clause condition, all three tests will fail. But in the second case if test fails, we are not sure what is exactly wrong. What way would you prefer.

Best Answer

But in the second case if test fails, we are not sure what is exactly wrong.

I think that would largely depend on how good error messages the test produces. In general, there are different ways to verify that a method has been called; e.g. if you use a mock object, it will give you a precise error message describing which expected method was not called during the test. If you verify that the method was called via sensing the effects of the call, it is up to you to produce a descriptive error message.

In practice, the choice between options 1 and 2 also depends on the situation. If I see the code you show above in a legacy project, I choose the pragmatic approach of Case #2 just to verify that each of the 3 methods are called properly when the condition is fulfilled. If I am developing this piece of code right now, the 3 method calls would most likely be added one by one, at separate points in time (possibly days or months away from each other), so I would add a new, separate unit test to verify each call.

Note also, that either way, you should also have separate unit tests to verify that each of the individual methods do what it is supposed to do.

Related Topic