Let\'s say I want to write a function that validates an email address with a regex. I write a little test to check my function and write the actual function. Make it pass.
I don't think that you should write separate test for each case since all the cases are related to the same thing which is testing that the string is the correct email address. If you are using MbUnit or NUnit for running your tests then you can use the RowTest and Row attribute to pass in different values to the test. Another way is to store all the different email formats in an array and loop over the array and perform the assert.
If the different incantations really boil down to the same thing it isn't a problem.
However, if one of the email addresses suddenly breaks the test, you are going to have to debug to find out which case went wrong. So that seems a good reason to break them up.
You would end up with millions of unit tests, which is right as they are after all tesing a unit of your application, but in practice multiple asserts will do providing that the way in which a failed assert breaks the test doesn't mess up the meaning of the failure.
Generally I create many different tests, and give each it's own name. For example let's say that there are 3 different regexes {A, B, & C} for matching an email address. The function checks the incoming email for a match and accepts the first match found.
I would have the following tests.
Generally I'd put one assert in each test.
Sometimes, however, I'll put more than one assert in a test if the asserts are all checking different parts of the same thing. For example, let's say I have a function that finds all the emails matching pattern A. My test feeds in a list of emails but only one matches pattern A. The function returns a list, and I expect that list to have only one element in it. So I would assert two things:
If you are testing the same functionality, I'd check them in the same test, with multiple assertions, provided that your tests remain simple enough.
Some people advocate that every test must have just a single assertion, because the test must be very, very, very simple.
If the test is not simple, say that you have loops and ifs, you would need a test for the test itself, to check that its logic is correct, and this is not good.
If your test has multiple assertions, but still remain simple (no loops, no ifs) and the multiple assertions are testing the same thing, then I'd not be so aggressive in advocating "single assert per test". The choice is yours.
Most testing frameworks now support some sort of data based testing to let you run the same test on multiple data sets.
See the ValuesAttribute in NUnit.
xUnit.net, MBUnit and others have similar methods.
BDD and/or Context/Specification frameworks like SubSpec which happens to have some salient examples manage this by treating each batch of related assertions as a separate Observation block that one gives a name or descriptive label to.
The key elements of a good test that this pushes one towards are:
Row Tests can be appropriate in some cases when you really are doing a simple table or matrix based suite of things.
Also xUnit.net's PropertyData can be powerful and appropriate in some cases as a way of doing some of the tricks in the other anwers.