Row Tests or Paramerterized Tests (MsTest) – CSV
In a previous post, I discussed Parameter Value Coverage (PVC). One of the easiest ways to add PVC to your test suite is to use Row Tests, sometimes called Parameterized Tests. Row test is the idea of writing a single unit test, but passing many different values in.
Different testing frameworks implement row tests differently.
MsTest uses an attribute called DataResourceAttribute. This supports anything from a csv, Excel file or xml, to a full-blown database.
For a single Unit Test, NUnit’s Row tests are far superior. However, for a larger test project, you will see that DataSourceAttribute with external data sources, scales nicely and compares to NUnits TestCaseSource. However, it is not as easy to get it right the first time. It needs a step by step tutorial.
Step 1 – Create a the Project
- In Visual Studio click File | New | Project.
- Select Unit Test Project for C#.
- Give it a name and a path and click OK.
Step 2 – Add a csv file
- Create a folder in your visual studio project called Data.
- Right-click on the data folder and choose Add | New Item.
- Create new text file named: Data.csv
- Add the following to the csv.
Value1, Value2, ExpectedMinValue, Message 1,10, 1, 1 is less th an 10. 192, 134, 134, 134 is less than 192. 101, 99, 99, 99 is less than 101. 77, 108, 77, 77 is less than 108. 45, 37, 37, 37 is less than 34. 12, 18, 12, 12 is less than 18.
Step 3 – Save the CSV file with the correct encoding
Note: The CSV file needs to be saved with an encoding that doesn’t add junk characters.
- Click File | Advanced Save Options.
- Choose this Encoding option: Unicode (UTF-8 without signature) – Codepage 65001
- Click OK and then click save.
Note: VS 2017 doesn’t have an Advance Save Options menu item.
- Click File | Save Data.csv as.
- Click the drop down on the Save button and choose Save with Encoding.
- Choose this Encoding option: Unicode (UTF-8 without signature) – Codepage 65001
- Click OK and then click save.
Step 4 – Set CSV File Properties
The CSV file needs to be copied on build.
- Right-click on the CSV file and choose Properties.
- Change the Copy to output directory to: Copy if newer
Step 5 – Add a Unit Test method
Note: We won’t have a real project to test. We will just test Math.Min() for an example.
- Add a reference to System.Data.
- Add the TestContext property. (See line 9 below)
- Add a DataSource attribute to the test method. (See line 12 below)
- Use TestContext.DataRow[0] to get the first column. (See line 16 below)
Note: You can also access the column by the column name we used: TestContext.DataRow[Value1] - Assign variables for the rest of the columns. (See lines 16-19 below)
- Add the test and the assert. (See lines 22 and 25)
using System; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MsTestRowTestExample { [TestClass] public class UnitTest1 { public TestContext TestContext { get; set; } [TestMethod] [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", @"Data\Data.csv", "Data#csv", DataAccessMethod.Sequential)] public void TestMethod1() { // Arrange int a = Convert.ToInt32(TestContext.DataRow[0]); int b = Convert.ToInt32(TestContext.DataRow[1]); int expected = Convert.ToInt32(TestContext.DataRow[2]); string message = TestContext.DataRow[3].ToString(); // Act var actual = Math.Min(a, b); // Assert Assert.AreEqual(expected, actual, message); } } }
You finished! Good job!.
Use Common Csv files for Parameter Value Coverage
While this method involved way more steps than anything with NUnit to set up, tt can actually be a bit quicker for subsequent tests and quite useful when testing larger projects. Once you have the csv files setup, you can reuse them for many methods. For example, for every method that takes a string, you could use the same DataSource to get Parameter Value Coverage (PVC).
null, A null string "", An empty string, String.Empty, or "" " ", One or more spaces " " " ", One or more tabs " " " ", A new line or Environment.NewLine "Hello, world!", A valid string. "&*^I#UYLdk1-KNnS1.,Dv0Hhfwelfnzsdase", An invalid or junk string গঘ, Double-byte Unicode characters
If you used a Base64 string in the csv, you could then use the below extension method. But as I said before, it means your test code needs tests. 🙂
http://stackoverflow.com/a/36592239/375727
Hello,
I really like your posts and it's helping start on unit tests!
But I have a small question. While maintaining one test per method and having to perform Parameterized Tests using a CSV file is it ok if I include an if inside the test?
Including the if on the test method performs the tests as it should but I want to make sure I am following a good procedure!
Best regards!
Marco,
Well, I would normally recommend that you add an 'Expected' column to your data set, but your expected type is byte[], which would be hard to do in CSV. You would have to convert the string to and from a byte array, which may add too much complexity for a test, causing your test to need its own code and unit tests to function. Not to mention the expected value is an encryption, which means you won't know the expected values before hand.
This is a perfectly acceptable work around that doesn't break any rules and won't hide failures. The additional complexity of the if statement is minor.