2

How to parametrize a C# unit test so that instead of a series of similar assert statements the test would iterate through a list of parameters (incl. expected values) and compare result with the expected values?

Use case:

  • this particular unit test needs to check an XML document and go through a list of XML element names, verifying that the document contains these elements and their values match what is expected

Assert part of the test method consists of series of assertions like this:

var width = output.Element(namespace + "width");
Assert.IsNotNull(width);
Assert.AreEqual(width.Value, "600");

I would like to avoid redundant code and iterate through the same code with different values instead. How do I define a data structure to iterate through in the assertion checking?

The data structure needed is a list of tuples (containing elements of types (XName, string) in this case). How to express that in C#? Are there some standard unit-testing tools that can help here?

More information:

  • using the Visual Studio unit-testing framework (Microsoft.VisualStudio.TestTools.UnitTesting) and .Net 3.5
  • I do not need to run the use case itself with various parameter values, just the assert part of it (the code quoted above)
CaptSolo
  • 1,771
  • 1
  • 16
  • 17
  • What Unit-testing library do you use? – Sasha Mar 11 '13 at 16:49
  • 1
    Added info re unit-testing framework to the question. It's the Visual Studio testing framework. – CaptSolo Mar 11 '13 at 16:54
  • 1
    Updated the question: added a use case description; added info re .Net 3.5. -- seems like in .Net 4.0 the answer would be to use a list of tuples and iterate through it. – CaptSolo Mar 11 '13 at 17:35

3 Answers3

2

Nunit has something called TestCases which you access via an attribute. This sounds like something you are asking for:

http://nunit.org/?p=testCase&r=2.5

UPDATE:

This answer was provided prior to the question update specifying the framework being used

UPDATE

This question also looks like it has relevancy: MS Test Equivalent (or lack of)

Does MSTest have an equivalent to NUnit's TestCase?

Community
  • 1
  • 1
REA_ANDREW
  • 10,666
  • 8
  • 48
  • 71
  • There seems to be some support for data driven tests in MSTest, I've metioned a couple of resources that demonstrate this. – Srikanth Venugopalan Mar 11 '13 at 16:59
  • 1
    I need to iterate just through a fragment of the assertion checking code, after the method to be tested is called. TestCase attributes would be helpful if the whole test case needed to be re-run, but not in this case. – CaptSolo Mar 11 '13 at 16:59
  • 1
    thanks for the answer. I added a clarification to the original question explaining that only the assert part needs to be iterated through -- if you have suggestions on how to further clarify the question, please let me know – CaptSolo Mar 11 '13 at 17:27
1

It seems like you just need to extract a method to meet your literal requested need:

public void AssertElementExistsWithValue(XmlElement parent, string nameSpace, string childName, string value)
{
    var child = parent.Element(namespace + childName);
    Assert.IsNotNull(child);
    Assert.AreEqual(child.Value, "600");    
}

I usually use the Linq Xml classes, so I apologize if I have a compile error. You'll get the gist, I'm sure.

When I test xml formatting, I usually write two tests. The first is a round trip test: write the entity to xml, read it back, assert that they are the same. This is a nice value oriented test that doesn't break if you change the name of an element.

The second test I write is one that pins the format of XML exactly. I get the xml from a correctly formatted object, and use it as a constant in a test, and assert the correct object is created. This test fails for implementation detail reasons, but that's ok. It is there to force me to notice if I break backwards compatibility with data formats.

tallseth
  • 3,635
  • 1
  • 23
  • 24
  • 1
    Thanks - extracting assertion code to another function made the solution more clear. -- But it does not solve the main question which is how to define a list of element names and expected values to iterate through. Solved this by defining a Dictionary and modifying the AssertElements* function to iterate through this dictionary. – CaptSolo Mar 17 '13 at 08:02
0

Since you say that you are using mstest, here are couple of resources from MSDN and independent blog that illustrate Data Driven Testing using Microsoft's unit testing framework.

In summary, you need to specify a DataSource attribute in your TestMethod and point it to the source of data. It can be a CSV or SQL Server CE.

Srikanth Venugopalan
  • 9,011
  • 3
  • 36
  • 76