views:

297

answers:

5

If you were testing a count function like the one below, is it considered to be 'right' or 'wrong' to test multiple things for the function in one function vs having a test function for each of the tests?

    function testGetKeywordCount()
    {
        $tester = $this->getDatabaseTester($this->CompleteDataFile);

        $tester->onSetUp();

        $KeywordID = 0;

        $this->setExpectedException('InvalidArgumentException');
        $this->keyword->getKeywordCount($KeywordID,'Active');

        $KeywordID = 1;

        $this->setExpectedException('InvalidArgumentException');
        $this->keyword->getKeywordCount($KeywordID,'InvalidStatus');

        $this->assertEquals(1, $this->keyword->getKeywordCount($KeywordID,'Active'));

        $tester->onTearDown();
    }

G-Man

+3  A: 

You should have multiple test functions, where each tests its own condition. That way it is easier to spot a failure without debugging.

__grover
+3  A: 

Having one test case for each scenario is ideal. However, in some cases it is more convenient (efficient from implementation effort point of view) to test more than one scenario in one test case. If you use a framework that doesn't stop on first failure, but tries to execute as much as possible in a test case, that framework is appropriate for multiple scenarios per test case.

I prefer to spend as less time as possible on unit testing, and still get as most coverage as possible in that time.

In the end, it matters less how you implement the unit test, but more the correctness of those tests.

Cătălin Pitiș
If I understand correctly, you're saying that it is easier, although less "correct" to have more scenarios in one test case.If that means you're putting multiple scenarios in one test case because making multiple test cases is too much work, I'd say: abstract it, make it easier and more DRY to make another scenario.Testing is also programming imho and should be done with more or less the same principles, like DRY.
Niels Bom
Also, another principle of programming is KIS (Keep It Simple). I like it more.
Cătălin Pitiș
+1  A: 

Testing frameworks don't always make it worth your effort to follow the one assertion per test rule.

One that does is RSpec for Ruby, which allows you to set up nested example groups. For example:

  • A User
    • without a password
      • is invalid
      • throws exception
    • with a password
      • that has been used before
        • is invalid
        • throws exception
        • trips security warning
      • that hasn't been used before
        • is valid
        • redirects to account page

By progressively building up scenarios and testing each step along the way, its easier to stick to the one assertion per test approach. It also makes it easier to spot untested scenarios.

Rich Apodaca
A: 

I would not talk about Unit tests in your example code above.
Your example is more an automated functional test, that tests a flow of functions.

BUT In this case it is fine to have multiple assertions.

Just make sure that 2 assertions are not one behind the other.

Bad example

public void ValidateRulesEntry_Valid_ValidConditionsFromFile()
{
    string condition = "Target.HasValue";
    string returnMessage;

    bool successFul = CodeParserTryParseCondition(condition, out returnMessage);


    Assert.IsTrue(successFul);
    Assert.IsFalse(string.IsNullOrEmpty(returnMessage));
    Assert.IsTrue(returnMessage == "OK");

}

The 2 last assertions are dependent of the 1st assertion IsTrue(successFul).

Think about: If that test fails --> Tell me why (without looking into Debug output)

Peter Gfader
A: 

One argument for splitting the assertions into two separate tests is that, if one of the assertions fails, you'll get one failure; if both assertions fail, you'll get two failures.

Also, by making the name of each test as suggestive as possible, you'll get extra clues when something breaks.

jared