tags:

views:

756

answers:

12

Do you write one case per function/method, with multiple checks in the test case, or a test case for each check?

+2  A: 

A test case for each check. It's more granular. It makes it much easier to see what specific test case failed.

TraumaPony
+4  A: 

BDD (Behavior Driven Development)

Though I'm still learning, it's basically TDD organized/focused around how your software will actually be used... NOT how it will be developed/built.

Wikipedia General Info

BTW as far as whether to do multiple asserts per test method I would recommend trying it both ways. Sometimes you'll see where one strategy left you in a bind and it'll start making sense why you normally just use one assert per method.

Justin Bozonier
A: 

I would suggest a test case for every check. The more you keep atomic, the better your results are!

Keeping multiple checks in a single tests will help you generate report for how much functionality needs to be corrected.

Keeping atomic test case will show you the overall quality !

Prakash
A: 

A testcase per check. If you name the method appropriately, it can provide valuable hint towards the problem when one of these tests cause a regression failure.

binil
+2  A: 

I have a test per capability the function is offering. Each test may have several assertions, however. The name of the testcase indicates the capability being tested.

Generally, for one function, I have several "sunny day" tests and one or a few "rainy day" scenario, depending of its complexity.

philippe
+2  A: 

I write at least one test per method, and somtimes more if the method requires some different setUp to test the good cases and the bad cases.

But you should NEVER test more than one method in one unit test. It reduce the amount of work and error in fixing your test in case your API changes.

gizmo
+7  A: 

One test case per check and super descriptive names, per instance:

@Test
public void userCannotVoteDownWhenScoreIsLessThanOneHundred() {
 ...
}

Both only one assertion and good names gives me a better report when a test fails. They scream to me: "You broke THAT rule!".

Kind Regards

marcospereira
thats basically BDD in a nutshell - although BDD puts the focus on writing those rules as descriptive assertions.
Michael Neale
A: 

I try to separate out Database tests and Business Logic Tests (using BDD as others here recommend), running the Database ones first ensures your Database is in a good state before asking your application to play with it.

There's a good podcast show with Andy Leonard on what it involves and how to do it, and if you'd like a bit more information, I've written a blog post on the subject (shameless plug ;o)

Andrew
A: 

In general one testcase per check. When tests are grouped around a particular function it makes refactoring (eg removing or splitting) that function more difficult because the tests also need a lot of changes. It is much better to write the tests for each type of behaviour that you want from the class. Sometimes when testing a particular behaviour it makes sense to have multiple checks per test case. However, as the tests become more complicated it makes them harder to change when something in the class changes.

David Dibben
A: 

In Java/Eclipse/JUnit I use two source directories (src and test) with the same tree. If I have a src/com/mycompany/whatever/TestMePlease with methods worth testing (e.g. deleteAll(List<?> stuff) throws MyException) I create a test/com/mycompany/whatever/TestMePleaseTest with methods to test differente use case/scenarios:

@Test
public void deleteAllWithNullInput() { ... }

@Test(expect="MyException.class") // not sure about actual syntax here :-P
public void deleteAllWithEmptyInput() { ... }

@Test
public void deleteAllWithSingleLineInput() { ... }

@Test
public void deleteAllWithMultipleLinesInput() { ... }

Having different checks is simpler to handle for me.

Nonetheless, since every test should be consistent, if I want my initial data set to stay unaltered I sometimes have, for example, to create stuff and delete it in the same check to insure every other test find the data set pristine:

@Test
public void insertAndDelete() { 
    assertTrue(/*stuff does not exist yet*/);
    createStuff();
    assertTrue(/*stuff does exist now*/);
    deleteStuff();
    assertTrue(/*stuff does not exist anymore*/);
}

Don't know if there are smarter ways to do that, to tell you the truth...

Manrico Corazzi
A: 

I like to have a test per check in a method and have a meaningfull name for the test-method. For instance:

testAddUser_shouldThrowIllegalArgumentExceptionWhenUserIsNull

Christophe Herreman
+1  A: 

I think that the rule of single assertion is a little too strict. In my unit tests, I try to follow the rule of single group of assertions -- you can use more than one assertion in one test method, as long as you do the checks one after another (you don't change the state of tested class between the assertions).

So, in Python, I believe a test like this is correct:

def testGetCountReturnsCountAndEnd(self):
    count, endReached = self.handler.getCount()
    self.assertEqual(count, 0)
    self.assertTrue(endReached)

but this one should be split into two test methods:

def testGetCountReturnsOneAfterPut(self):
    self.assertEqual(self.handler.getCount(), 0)
    self.handler.put('foo')
    self.assertEqual(self.handler.getCount(), 1)

Of course, in case of long and frequently used groups of assertions, I like to create custom assertion methods -- these are especially useful for comparing complex objects.

DzinX