Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to name different tests for the same method?

How do I name tests for a method that has many different flows?

For example, let's say I have a method, process(), which behaves differently based on an object's fields:

public void process () {

    if (this.someField1 == null) {
        doSomethingOne();
    else
        doSomethingTwo();

    if (this.someField2 == null) {
        doSomethingThree();
    else
        doSomethingFour();
}

There are four different potential outcomes from this method. I assume I should write four different test cases for 100% code coverage. Is there a standard practice/pattern for how I should name those test cases? Or do people normally make one giant test case?

like image 225
Azianese Avatar asked May 29 '26 07:05

Azianese


1 Answers

There are some goals that shall be achieved when naming tests. Keep in mind that when you run a number of tests, in case of regressions due to changes you may see a number of failing tests. Then, the ideal situation is, that from the pattern of failing and passing tests you can immediately (without even going into the code or starting a debugger) deduce what the problem is.

Therefore, from the diagnostic output (which includes the name of the failing tests) you would like to know

  • which class / method was under test for each test that failed.
  • what was the scenario for which the test was failing.
  • what was the expected result

To some extent this is already provided by the default output of the test frameworks. For example, you get the file names and class names for each failing test. But, even if you know it is class FooTest in file FooTest.java, then it is still not too enlightening to know that test15 and test21 are failing. Moreover, the test framework assertions - when failing - also indicate expected and actual values. For some tests it may be clear enough to learn that 19 was expected but 20 was the actual results. It may, however, be more helpful to know that the expected output is 19, being the eigth prime number.

A common pattern for test names that addresses the above point is:

<method under test>_<scenario being tested>_<expected outcome>

for example

process_noFieldsInitialized_shallDoOneAndThree

but there are some more naming conventions, which basically address the same topics but in slightly different ways.

It may be worth mentioning that there is also a line of thought in the direction: Instead of thinking about great explanatory test names, make your test code better readable such that all information can be seen in the test code immediately. For me, this is not a contradition: The code should be easy to read, for sure. But, the code is on the implementation level and uses concrete values, whereas the test name can be on semantic/user domain level and can describe the abstract scenario: Imagine that when testing some function foo you want to test the scenario that foo is called with some number above 42. In your test implementation you have to choose a number, maybe 43, but maybe 50. But, in your test name you can still make it clear what the test is about: foo_withArgumentAbove42_shallProvideTheAnswer.

Now, coming to your second question: Should you put all four scenarios into one test case, or, more generally, should all tests for one method go into one test case. Let me repeat the goal from above: From the pattern of failing and succeeding test cases you should ideally be able to deduce immediately what the problem is. This leads to the conclusion that you should have different tests for different aspects/scenarios. In your case, there would be four test cases. If one scenario fails, you will know immediately which one it was. If you put all scenarios in one test case, you will afterwards have to figure out what the problem actually was.

Update: Having four tests instead of one can mean some code duplication. Obviously this is undesired. Therefore, when following the concept to have separate tests for separate scenarios / aspects, make yourself familiar with concepts like "parameterized tests", or, test helper methods.

like image 94
Dirk Herrmann Avatar answered Jun 02 '26 01:06

Dirk Herrmann