Wednesday, August 19, 2009

Parameterized tests in NUnit

In an earlier post I showed how to pass parameters to test methods using an NUnit RowTest extension. As of version 2.5, the extensions are no longer packaged with the NUnit installer. The good news is that the addition of parameterized tests replaces the RowTest and adds a number of new features as well.

For reference, my previous RowTest looked like this:

[RowTest]
[Row(2, 3)]
[Row(-1, -4)]
public void AddTwoNumbers(int x, int y)
{
    Assert.AreEqual(x + y, Add(x, y),
        "Add returned incorrect result");
}

A basic switch to a parameterized test is a matter of dropping the RowTest attribute and replacing each Row attribute with a similarly-formatted TestCase attribute. The new code, which creates two distinct tests as before, looks like this:

[TestCase(2, 3)]
[TestCase(-1, -4)]
public void AddTwoNumbers(int x, int y)
{
    Assert.AreEqual(x + y, Add(x, y),
        "Add returned incorrect result");
}

In addition to single parameters you can now specify ranges. If I want to test values of X from 1 to 5, with a Y value of 1, I can do so using the Range and Values attributes, like so:

[Test]
public void AddTwoNumbers(
                    [Range(1, 5)]int x,
                    [Values(1)]int y)
{
    Assert.AreEqual(x + y, Add(x, y),
        "Add returned incorrect result");
}        

In the test runner, this shows up as five distinct unit tests


If I specify the range 1-5 for both X and Y, NUnit defaults to creating 25 unique tests. This is the default Combinatorial attribute.


If I wish to use a value from each range only once, I instead mark the test as Sequential

[Test, Sequential]
public void AddTwoNumbers(
                    [Range(1, 5)]int x,
                    [Range(1, 5)]int y)
{
    Assert.AreEqual(x + y, Add(x, y),
        "Add returned incorrect result");
}        

which produces the desired effect

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.