Преобразовать строку в код C # - PullRequest
0 голосов
/ 07 января 2010

в текущей версии NUnit, я могу параметризовать TestFixture и создать его несколько раз. Например:

[TestFixture("var1")]  
[TestFixture("var2")]  
[TestFixture("var3")]  
public class MyTestFixture  
{  
    private string var;  

    public MyTestFixture(string var)  
    {  
        this.var = var;  
    }  

    ...  

}  

Это создаст экземпляр MyTestFixture 3 раза с параметром аргумента. Моя проблема в том, что в текущем NUnit нет функции источника данных для атрибута TextFixture (только TestCaseSource). Мне нужно создать экземпляр TestFixture на основе ввода данных, и каждый TestFixture имеет различные наборы ввода данных теста. Нет проблем с управляемыми данными тестового примера, благодаря TestCaseSource. Но как я могу сделать это для атрибута TestFixture?

Моя идея состоит в том, чтобы сгенерировать атрибут TestFixture на лету, затем изменить его на строку кода и вставить в код теста, например: что-то вроде этого:

ConvertToCode(GenerateTestFixture());  
public class MyTestFixture  
{  
   ...  
}  

Как я могу это сделать? Или есть лучший способ?

Большое спасибо за вашу помощь.

С уважением,
Эдвард

Ответы [ 3 ]

3 голосов
/ 07 января 2010

Создание атрибутов для вашего метода на лету возможно, но сложно. Вам лучше найти другой подход.

Атрибуты (например, [TestFixture]) того типа, который у вас есть, читаются компилятором, когда ваш код компилируется и автоматически вставляется в ваш код.

Чтобы сгенерировать свои собственные атрибуты для классов, вам нужно использовать что-то вроде Reflection.Emit, чтобы модифицировать сгенерированные сборки как шаг после сборки для проекта. Это похоже на непосредственное написание ассемблера (вы создаете MSIL), что может быть весело, но не просто и затруднит поддержку вашего кода!

Альтернативный подход может заключаться в том, чтобы перечисление управляло контрольными случаями и имело метод, который проверяет перечисление и возвращает соответствующие данные:

public enum TestController
{
    Value1,
    Value2,
    Value3
}

[TestFixture(TestController.Value1)]   
[TestFixture(TestController.Value2)]   
[TestFixture(TestController.Value3)]   
public class MyTestFixture   
{   
    public MyTestFixture(TestController testController)   
    {   
        var dataForTest = GetDataForTest(testController);
    }   

    ...   

}   

Метод GetDataForTest() будет тогда иметь своего рода оператор переключения для генерации данных.

Альтернативным подходом может быть использование типа, а не перечисления, затем создание экземпляра типа в методе GetDataForTest() и вызов метода фабрики - но я думаю, что это может быть немного слишком сложно.

0 голосов
/ 08 марта 2016

Теперь это возможно в NUnit 3.x с использованием атрибута TestFixtureSource. Создайте класс, который реализует IEnumerable с вашими значениями, а затем используйте его так:

[TestFixtureSource(typeof(Foo), Category = "Quux")]
public class BarTest
{    
     public BarTest(object baz)
     {
         _baz = baz;
     {
}

Одна вещь, которая изменилась с TestCaseSource и применяется к TestFixtureSource, заключается в том, что вы должны либо дать ему тип, который реализует IEnumerable, либо предоставить ему статический метод. Если вы полагались на свойства или методы, которые генерируют данные из конструктора, то вам нужно либо выполнить рефакторинг статическим способом, либо просто заставить класс реализовать сам IEnumerable и передать себя как тип источника.

0 голосов
/ 26 сентября 2011

Взгляните туда:

http://www.dotnetspider.com/resources/26499-Making-NUnit-test-cases-data-driven.aspx

[TestCaseSource] и TestCaseData - это классы, которые вы ищете

...