Convert string to C# code
in the current NUnit version, I can parameterized TestFixture and instantiated it multiple times. E.g.:
[TestFixture("var1")]
[TestFixture("var2")]
[TestFixture("var3")]
public class MyTestFixture
{
private string var;
public MyTestFixture(string var)
{
this.var = var;
}
...
}
This will instantiate the MyTestFixture开发者_JAVA百科 3 times with the argument parameter. My problem is the current NUnit doesn't have datasource feature for TextFixture attribute (only TestCaseSource). I need to instantiate the TestFixture based on the data input, and each TestFixture has a different sets of test case data input. No problem with the Test case data driven, thanks to the TestCaseSource. But how can I do this for the TestFixture attribute?
My idea is to generate the TestFixture attribute on the fly then change it to code string and insert into the test code, e.g.: something like this:
ConvertToCode(GenerateTestFixture());
public class MyTestFixture
{
...
}
How can I do this? Or are there a better way?
Thank you very much for your help.
Best regards,
EdwardCreating attributes for your method on the fly is possible but hard. You're better off finding another approach.
Attributes (e.g. [TestFixture]
) of the kind you have are read by the compiler when your code is compiled and inserted in to your code automatically.
To generate your own attributes for classes you'll need to use something like Reflection.Emit to modify generated assemblies as a post-build step for the project. This is like writing assembly language directly (you'd be creating MSIL) which might be fun but is not easy and would make your code very hard to maintain!
An alternative approach might be to have an enum control the test cases, and have a method that checks the enum and returns the appropriate data:
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);
}
...
}
The method GetDataForTest()
would then have some kind of switch statement to generate the data.
An alternative approach might be to use a type rather than an enum, then instantiate the type in the GetDataForTest()
method and call a factory method - but I think that might be a bit overcomplicated.
Take a look there:
http://www.dotnetspider.com/resources/26499-Making-NUnit-test-cases-data-driven.aspx
[TestCaseSource] and TestCaseData are the classes you're looking for
This is now possible in NUnit 3.x using the TestFixtureSource attribute. Create a class that implements IEnumerable with your values then use it like so:
[TestFixtureSource(typeof(Foo), Category = "Quux")]
public class BarTest
{
public BarTest(object baz)
{
_baz = baz;
{
}
One thing that has changed with TestCaseSource and applies to TestFixtureSource is that you have to either give it a type that implements IEnumerable or give it a static method. If you were relying on properties or methods that generate data from the constructor, then you need to either refactor in a static way or just have the class implement IEnumerable itself and pass itself in as the source type.
精彩评论