views:

47

answers:

3

Especially for C# Unit Testing, how to make a test run for various inputs or an input matrix?

I very often have the case of unit tests making a matrix of inputs, but usually it can be reasonably solved by checking a list of inputs.

The simplest case is testing the addition:

  • 0 + 0 = 0
  • 1 + 0 = 1
  • 0 + -1 = -1
  • 1 + -1 = 0

The same tests would be done for each of those inputs (in this example there are 4 inputs, each associated to some expected output.

The simple solution is:

object[] inputs = ...
foreach (var input in inputs)
   // Put Assert here

The problem with that is that when you run your test it doesn't tell for which input it failed unless you include enough details in the message log manually.

Another solution is to unroll the loop (like below). The stack trace then give which input failed and this allows to run the test for a single input again.

TestAddition(0, 0, 0);
TestAddition(1, 0, 1);
TestAddition(0, -1, -1);
TestAddition(1, -1, 0);

Last but not least, are solutions like FitNess which seem to help such cases but also add a lot of complexity and don't seem to fit well for standard C# development.

All those solution don't work well with fixtures, because the [TestInitialize] is called once for all inputs.

What is your solution?

Is there some feature I don't know of that helps those cases?

+4  A: 

If you're using NUnit, you should have a look at the TestCase attribute.

[TestCase(0,0,0)]
[TestCase(1,0,1)]
[TestCase(0,-1,-1)]
[TestCase(1,-1, 0)]
public void AdditionTest(int x, int y, int z)
{
  Assert.AreEqual( z, x+y );
}
Martin Clarke
Actually I'm using Visual Studio Unit Testing Framework (the built-in unit testing). Never had any issue or reason to change so far.
Wernight
http://codeclimber.net.nz/archive/2008/01/18/How-to-simulate-RowTest-with-MS-Test.aspx found here http://stackoverflow.com/questions/347535/how-to-rowtest-with-mstest suggests an approach. Seems a bit heavy to me though.
Martin Clarke
+1  A: 

Take a look at Pex. You can try it online before deciding it's worth downloading.

Stephen Cleary
I think this is a bit too advanced for what the OP is asking; Pex if I'm not mistaken is a 'scan and generate unit tests' tool
Gishu
It is more advanced. With Pex, the op won't even have to write the data for his test cases.
Stephen Cleary
+2  A: 

Its possible. The term you are missing is "Data Driven Tests" / Parameterized tests. Try with a search engine and you should find quite a few answers for your specific testing framework.

Most of the xUnit testing frameworks have mechanisms to enable this. As Martin has posted, NUnit uses a RowTest/TestCase attribute to pass in parameters to a test.

Gishu
See if this helps - tagged: 'shameless blog plug' :) http://madcoderspeak.blogspot.com/2009/01/nunit-rowtest-extension-running-same.html
Gishu
Thanks for those keyworks. With it I found http://www.c-sharpcorner.com/UploadFile/sanks/1770/Default.aspx which seem close to what I'm looking (just a bit complex it seems). Searching...
Wernight