Управляемые данными тесты с атрибутом [DeploymentItem] вызывают ошибку OracleDataClientDriver с NHibernate (vstest.console.exe, Visual Studio 2013)

У нас есть несколько интеграционных / модульных тестов для проверки наших сопоставлений NHibernate. Я представил некоторые управляемые данными тесты, которые используют [DeploymentItem] атрибут над тестовыми методами для импорта файла CSV. Простое существование этого атрибута в любом тесте в проекте модульных тестов приводит к сбою всех тестов отображения NHibernate с сообщением ниже:

Error Message:
   Initialization method UnitTests.SearchOrganizationTests.Setup threw exception. NHibernate.HibernateException: NHibernate.HibernateException: Could not create the driver from NHibernate.Driver.OracleDataClientDriver. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object..
Stack Trace:
    at NHibernate.Driver.OracleDataClientDriver..ctor()
 --- End of inner exception stack trace ---
    at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
   at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
   at System.Activator.CreateInstance(Type type, Boolean nonPublic)
   at System.Activator.CreateInstance(Type type)
   at NHibernate.Bytecode.ActivatorObjectsFactory.CreateInstance(Type type)
   at NHibernate.Connection.ConnectionProvider.ConfigureDriver(IDictionary`2 settings)
 --- End of inner exception stack trace ---
    at NHibernate.Connection.ConnectionProvider.ConfigureDriver(IDictionary`2 settings)
   at NHibernate.Connection.ConnectionProvider.Configure(IDictionary`2 settings)
   at NHibernate.Connection.ConnectionProviderFactory.NewConnectionProvider(IDictionary`2 settings)
   at NHibernate.Cfg.SettingsFactory.BuildSettings(IDictionary`2 properties)
   at NHibernate.Cfg.Configuration.BuildSettings()
   at NHibernate.Cfg.Configuration.BuildSessionFactory()
   at MyApplication.DataContext.get_SessionFactory()
   at MyApplication.DataContext.GetClassMetadata(Type type)
   at MyApplication.DataContext.GetClassMetadata[T]()
   at MyApplication.DataContext.GetTableName[T]()

Я получаю ту же ошибку, использую ли я mstest.exe или же vstest.console.exe из командной строки.

Запуск тестов из "Test Explorer" в Visual Studio 2013 работает просто отлично. Сбой запуска тестов из командной строки, что является проблемой для нашего сервера непрерывной интеграции.

Итак, дополнительная информация:

  • Это тестовый модуль в Visual Studio
  • Oracle.DataAccess.dll Файл находится в выходном каталоге сборки (а для параметра "Копировать локальный" задано значение "Истина"), только когда я не запускаю тесты, украшенные [DeploymentItem] атрибут
  • При выполнении хотя бы 1 теста, украшенного [DeploymentItem] атрибут, Oracle.DataAccess.dll файл не копируется в выходной каталог
  • Для свойства "Копировать в вывод" для всех файлов CSV установлено значение "Всегда"
  • Visual Studio 2013
  • NHibernate версия 4.0.4.4000
  • .NET 4.5.1
  • FluentNHibernate версия 2.0.3.0
  • Клиент Oracle 12c установлен на моей машине (12.1.0)

Обновление № 1: я посмотрел в TestResults/<Test run name>/Out каталог, и я не вижу файл Oracle.DataAccess.dll


Обновление № 2: у нас есть тест, который открывает соединение с базой данных Oracle напрямую с помощью клиентской библиотеки Oracle. Над этим тестом я добавил атрибут [DeploymentItem] со ссылкой на файл Oracle.DataAccess.dll. Сейчас тесты отображения NHibernate проходят, но тесты, управляемые данными, не загружают файлы CSV.

[TestClass]
public class OracleConnectionTests
{
    [TestMethod]
    [TestProperty("Data Mappings", "Connection Test")]
    [DeploymentItem(@"..\Dependencies\Oracle.DataAccess.dll")]
    public void CanOpenCloseConnection()
    {
        OracleConnection oraConn = new OracleConnection("connection string here");
        oraConn.Open();
        Assert.IsTrue(oraConn.State == ConnectionState.Open);
        oraConn.Close();
        Assert.IsFalse(oraConn.State == ConnectionState.Open);
    }
}

Образец теста на основе данных:

[TestClass]
public class FixedPrologueTests
{
    private const string DATA_PROVIDER = "Microsoft.VisualStudio.TestTools.DataSource.CSV";
    private const string DATA_FILE_PATH = @".\UnitTests\ViewModelTests\FixedPrologueTestData.csv";
    private const string DATA_OUTPUT_PATH = @"UnitTests\ViewModelTests";
    private const string DATA_TABLE_NAME = "FixedPrologueTestData.csv";

    public TestContext TestContext { get; set; }

    private PaginationPrologueTestData data;
    private PaginationPrologue prologue;
    private System.Collections.Generic.IEnumerable<int> epilogue;

    [TestInitialize]
    public void Setup()
    {
        data = new PaginationPrologueTestData(TestContext.DataRow);
        prologue = new PaginationPrologue(data.Padding, data.CurrentPage, data.TotalPages);
        epilogue = prologue.CreateEpilogue();
    }

    [TestMethod]
    [TestProperty("PaginationPrologue", "Prologue remains fixed when nearing end of result set")]
    [DataSource(DATA_PROVIDER, DATA_FILE_PATH, DATA_TABLE_NAME, DataAccessMethod.Sequential)]
    [DeploymentItem(DATA_FILE_PATH, DATA_OUTPUT_PATH)]
    public void WhenNearingEndOfResultSet_EpilogueIsNotIncluded()
    {
        Assert.AreEqual(data.EpilogueLength, epilogue.Count());
    }

Как я могу включить атрибут [DeploymentItem], чтобы позволить управляемым данными тестам загружать файлы CSV, и позволить NHibernate загружать драйвер Oracle при запуске тестов из командной строки?

1 ответ

В итоге я "исправил" это с помощью флага компилятора:

          [TestMethod]
    [TestProperty("PaginationPrologue", "Prologue remains fixed when nearing end of result set")]
    [DataSource(DATA_PROVIDER, DATA_FILE_PATH, DATA_TABLE_NAME, DataAccessMethod.Sequential)]
#IF DEPLOY_TEST_DATA
    [DeploymentItem(DATA_FILE_PATH, DATA_OUTPUT_PATH)]
#ENDIF
    public void WhenNearingEndOfResultSet_EpilogueIsNotIncluded()
    {
        Assert.AreEqual(data.EpilogueLength, epilogue.Count());
    }

Поскольку эта ошибка возникала только при запуске автоматических тестов на нашем сервере сборки, это было достаточно хорошим решением. Честно говоря, я до сих пор не уверен, почему это работает, я просто знаю, что это работает. Прошло более 3 лет, и все было довольно стабильно.

Другие вопросы по тегам