I'm having a hard time understanding why there is only one test per function in most professional TDD code that I have seen. When I approached TDD initially I tended to group 4-5 tests per function if they were related but I see that doesn't seem to be the standard. I know that it is more descriptive to have just one test per function because you can more easily narrow down what the problem is, but I find myself struggling to come up with function names to differentiate the different tests since many are so similar.
So my question is: Is it truly a bad practice to put multiple tests in one function and if so why? Is there a consensus out there? Thanks
Edit: Wow tons of great answers. I'm convinced. You need to really separate them all out. I went through some recent tests I had written and separated them all and lo and behold it was way more easier to read and helped my understand MUCH better what I was testing. Also by giving the tests their own long verbose names it gave me ideas like "Oh wait I didn't test this other thing", so all around I think it's the way to go.
Great Answers. Gonna be hard to pick a winner
Consider this straw man (in C#)
While "one assertion per test function" is good TDD advice, it's incomplete. Applying it alone would give:
It's missing two things: Once-and-only-once (aka DRY), and "one test class per scenario". The latter is the less-known one: instead of one test class / test fixture that holds all test methods, have nested classes for non-trivial scenarios. Like this:
Now you don't have duplication, and each test method asserts exactly one thing about the code under test.
If it wasn't so verbose, I would consider writing all my tests this way, such that test methods are always trivial single-line methods with only an assertion. However, it seems too clumsy when a test doesn't share "setup" code with another test.
(I have avoided details that are specific to unit test technology, e.g. NUnit or MSTest. You will have to adjust to fit whatever you are using, but the principles are sound.)
It seems like a single failure in a multi-test function would have to result in a failure for all, right? Generally test framework tests just pass fail, which with a multi-test method would mean you'd have to manually figure out which of the multiple tests would be failing, since if you're running a huge list of tests the first executed failure would result in an overall failure for the function and further tests wouldn't get to fail.
Granularity in tests is good. If you're going to write 5 tests, having them each in their own function seems no more difficult than having them all in the same location, apart from the minor overhead of creating new boilerplate function each time. With the right IDE, even that may be simpler than copying & pasting.