Testing data generated in ClassInitialize: no longer works in Visual Studio 2012

I upgraded Visual Studio 2010 to Visual Studio 2012.

In my unit test project, I have a [ClassInitialize] method that generates a CSV file, which I then pass to the data driven [TestMethod] using [DataSource] connected to the CSV.

This works great in Visual Studio 2010.

I cannot get this to work in Visual Studio 2012.

It seems that in VS2012, the MS test runner requires that a file connected to [DataSource] already exist, otherwise none of the tests will run. If I create a CSV myself, data-driven tests run, but they don’t collect the data created in [ClassInitialize]: it seems that the list of tests from [DataSource] is evaluated before running [ClassInitialize].

Is there any workaround?


This is a minimal project that reproduces the problem. For me, this succeeds in VS2010, but does not work in VS2012.

TestProject.cs

using System.Diagnostics; using System.IO; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace TestProject { [TestClass] public class DataDrivenUnitTest { private static bool _classInitializeCalled; private static int _testCount; public TestContext TestContext { get; set; } [ClassInitialize] public static void ClassInitialize(TestContext testContext) { // Generate the csv list of tests //TestContext = testContext; _classInitializeCalled = true; string testDirectory; testDirectory = testContext.DeploymentDirectory; using (var f = new StreamWriter(testDirectory + @"\" + "TestList.csv")) { f.WriteLine("TestName"); f.WriteLine("TestA"); f.WriteLine("TestB"); } } [TestMethod] [DataSource("CsvTestData32")] public void TestMethod1() { _testCount++; var testName = TestContext.DataRow["TestName"]; Debug.Print("Test {0}: {1}", _testCount, testName); } [ClassCleanup] public static void ClassCleanup() { Assert.IsTrue(_classInitializeCalled); Assert.AreEqual(_testCount, 2); Debug.Print("Tests completed: Tests run {0}", _testCount); } } } 

In my case, "run test as 32-bit" is the default setting; it can be changed under -

  • in VS2012: TEST> TestSettings> Default processor architecture
  • in VS2010 Right-click Solution explorer "Solution Elements"> Add> New Item> Test Settings, then
  • VS2010 Main Menu> Tests> Change Test Settings> Hosts> Run tests in a 32-bit or 64-bit process.

If you are using a 64-bit version, use [DataSource ("CsvTestData64")], and you may need to install the MS Access 64-bit ODBC driver . The easiest way is to stick with the 32-bit version.

App.config

 <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="microsoft.visualstudio.testtools" type="Microsoft.VisualStudio.TestTools.UnitTesting.TestConfigurationSection, Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" /> </configSections> <microsoft.visualstudio.testtools> <dataSources> <add name="CsvTestData32" connectionString="CsvConn32" dataTableName="`TestList.csv`" dataAccessMethod="Sequential" /> <add name="CsvTestData64" connectionString="CsvConn64" dataTableName="`TestTest.csv`" dataAccessMethod="Sequential" /> </dataSources> </microsoft.visualstudio.testtools> <connectionStrings> <add name="CsvConn32" connectionString="Driver={Microsoft Text Driver (*.txt; *.csv)};.\;Extensions=csv;" providerName="System.Data.Odbc" /> <add name="CsvConn64" connectionString="Driver={Microsoft Access Text Driver (*.txt, *.csv)};Dbq=.\;Extensions=csv" providerName="System.Data.Odbc" /> </connectionStrings> </configuration> 
+5
c # unit-testing visual-studio-2012 mstest data-driven-tests
source share
1 answer

MSTestHacks can help.

It allows you to use IEnumberable in your test class as a DataSource for your TestMethod .

From the website:

Runtime Data Source

You SHOULD inherit your test class from TestBase

 [TestClass] public class UnitTest1 : TestBase { } 

Create a property, field, or method that returns IEnumerable

 [TestClass] public class UnitTest1 : TestBase { private IEnumerable<int> Stuff { get { //This could do anything, fetch a dynamic list from anywhere.... return new List<int> { 1, 2, 3 }; } } } 

Add the DataSource attribute to your test method, pointing back to the IEnumerable name you created earlier. This is necessary for a full qualification.

 [TestMethod] [DataSource("Namespace.UnitTest1.Stuff")] public void TestMethod1() { var number = this.TestContext.GetRuntimeDataSourceObject<int>(); Assert.IsNotNull(number); } 
+4
source share

All Articles