Do you write one test per function/method, with multiple checks in the test, or a test for each check?
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.
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...
One test per check and super descriptive names, per instance:
@Test
public void userCannotVoteDownWhenScoreIsLessThanOneHundred() {
...
}
Both only one assertion and using good names gives me a better report when a test fails. They scream to me: "You broke THAT rule!".
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.
I like to have a test per check in a method and have a meaningfull name for the test-method. For instance:
testAddUser_shouldThrowIllegalArgumentExceptionWhenUserIsNull
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.