Тесты, управляемые данными, сгенерированные в ClassInitialize: больше не работают в Visual Studio 2012

Я обновился с Visual Studio 2010 до Visual Studio 2012.

В моем проекте модульного тестирования у меня есть метод [ClassInitialize], который генерирует CSV-файл, который я затем передаю в управляемый данными [TestMethod], используя [DataSource], подключенный к CSV.

Это прекрасно работает в Visual Studio 2010.

Я не могу заставить это работать в Visual Studio 2012.

Похоже, что в VS2012 средство запуска тестов MS требует, чтобы файл, подключенный к [DataSource], уже существовал, иначе ни один из тестов не будет запущен. Если я сам создам CSV, тесты, управляемые данными, запустятся, но они не получат данные, созданные в [ClassInitialize]: кажется, что список тестов из [DataSource] оценивается ДО запуска [ClassInitialize].

Есть ли обходной путь?


Это минимальный проект, который воспроизводит проблему. Для меня это удается в VS2010, но не в 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);
        }
    }
}

В моем случае «запустить тест как 32-разрядный» является настройкой по умолчанию; это может быть изменено в разделе -

  • в VS2012: TEST > TestSettings > Архитектура процессора по умолчанию
  • в VS2010 щелкните правой кнопкой мыши обозреватель решений «Элементы решения» > «Добавить» > «Новый элемент» > «Настройки теста», затем
  • Главное меню VS2010> Тесты> Изменить настройки теста> Хосты> Запустить тесты в 32-битном или 64-битном процессе.

Если вы используете 64-разрядную версию, используйте [DataSource("CsvTestData64")], и вам может потребоваться установить 64-разрядный драйвер ODBC для MS Access. Самый простой способ - придерживаться 32-битной версии.

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>

person Edward    schedule 13.11.2012    source источник
comment
Догадка. Отладьте тест, убедитесь, что testContext.DeploymentDirectory находится в том же месте, где вы загружаете файл вручную.   -  person Tony Hopkinson    schedule 13.11.2012
comment
Похоже, это проблема с адаптером MSTest в Visual Studio 2012. Вы можете отправить его по адресу connect.microsoft.com/ визуальная студия ?   -  person Oleg Sych    schedule 13.11.2012
comment
это уже исправлено?   -  person DevDave    schedule 02.04.2013
comment
Вы смотрели на это? social.msdn.microsoft .com/Forums/en-US/vsunittest/thread/   -  person Spock    schedule 18.06.2013
comment
Также эта ссылка может помочь вам -vs2010" title="почему модульный тест, управляемый данными, не работает в vs2012, когда он отлично работал в vs2010"> stackoverflow.com/questions/16025719/   -  person Spock    schedule 18.06.2013


Ответы (1)


MSTestHacks может помочь.

Это позволяет использовать IEnumberable в вашем тестовом классе как DataSource для вашего TestMethod.

С веб-сайта:

Источник данных среды выполнения

Вы ДОЛЖНЫ наследовать свой тестовый класс от TestBase.

[TestClass]
public class UnitTest1 : TestBase
{ }

Создайте свойство, поле или метод, который возвращает 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 };
        }
    }
}

Добавьте в метод тестирования атрибут DataSource, указывающий на имя IEnumerable, созданное ранее. Это должно быть полностью квалифицировано.

[TestMethod]
[DataSource("Namespace.UnitTest1.Stuff")]
public void TestMethod1()
{
    var number = this.TestContext.GetRuntimeDataSourceObject<int>();

    Assert.IsNotNull(number);
}
person Jon    schedule 18.12.2014
comment
единственная проблема с этим решением - это требование TestBase, было бы неплохо, если бы MSTestHacks авторы могли найти способ реализовать такое расширение без обязательных базовых классов для всех тестовых приспособлений. - person Shaun Wilson; 05.07.2016