Skip to main content

Data driven test cases in NUnit

When you want to create thousands of test cases you don't use the [TestCase] attribute in NUnit. :) But did you know that there is a "TestCaseSource" attribute that specifies a method that will generate test case data? Look at this.

[TestCaseSource("MassiveAmountOfUsers")]
public void ShouldLogin(string username, string password, bool expected)
{
    /* Setup */
    var repository = new UserRepository();

/* Test */
var result = repository.Authenticate(username, password);

/* Assert */
Assert.That(result, Is.EqualTo(expected));

}

It is an integration test that will try to login a massive amount of users. This is the kind of test where you take a huge diversity of data and try to find out if there is anything that will make it break. But where does the data come from? The magic string "MassiveAmountOfUsers" holds the answer.

private IEnumerable MassiveAmountOfUsers
{
    get { return GetMassiveAmountOfUsers(); }
}
private IEnumerable GetMassiveAmountOfUsers()
{
    var doc = XDocument.Load("users.xml");
    return
        from user in doc.Descendants("user")
        let username = user.Attribute("username").Value
        let password = user.Attribute("password").Value
        let expected = user.Attribute("success").Value
            .Equals("true", StringComparison.InvariantCultureIgnoreCase)

    select new object[] { username, password, expected };

}

Test cases will be generated by the framework calling the property MassiveAmountOfUsers. This should return an IEnumerable of an array of arguments. We create that array of arguments by reading an XML file. To enable using different types, string and bools, as arguments we create an untyped array of objects. As long as we put strongly typed members into the array, we can use strong types in the test function. What the xml looks like, is unimportant, but in my test case like this.

<?xml version="1.0" encoding="utf-8" ?>
<users>
  <user username="fsse" password="dj7sihfs" success="true" />
  <user username="hgtd" password="sd122?=s" success="true" />
  <user username="asde" password="!!sf3mff" success="true" />
  <user username="bsfd" password="--sdfj+?" success="true" />
  <user username="aefb" password="!#ยค%/(sd" success="true" />
  ...
</users>

You could get the test data from anywhere, the database if you want to. Testing your code with an massive amount of real data, really gives you confidence with your code. Running this in the NUnit test runner looks pretty much like any [TestCase] suite, but the test cases are generated when the test assembly is loaded.

nunit gui

comments powered by Disqus