问题
I'm interested in being able to instantiate multiple testfixtures with constructor arguments passed to it at runtime by a static method or property returning an IEnumerable.
In Nunit 2.5 they introduced parameterised tests and test fixtures. These allow you to write a single test and run it with several inputs provided using the TestCase attribute, and write a single test class and instantiate multiple instances of it with different constructor arguments respectively.
In addition to this, it is possible to create several test cases based on the output of a property or method, using the TestCaseSource attribute. This will use the output of a method/property that implements IEnumerable to create a set of testcases, one per object in the list. This is what I'd like to be able to do, but at the fixture level not the Test level.
Some background on my use case:
I'm testing simulation software, and a 'simulation environment' that must be loaded (from a serialized object) before any simulations can be run. There are about 5 different types of sim, so my test class has 5 test methods (one for each type of sim). I'm using inheritance currently (instead of parameterised fixtures) to run the test cases under several (a half dozen or so) simulation environments, which have been taken from production data.
My trouble springs from the fact that in a recent attempt to increase code coverage, we automatically generated all possible combinations of simulation components, resulting in 100+ sim environments. I don't want to create inherited classes for each of these so instead I'm using TestCaseSource with a property that returns all the workspaces in a folder, and modifying the tests so they (re)load the sim environment within the test itself for each testcase.
Ideally I'd like to have one fixture per simulation environment, and determine how many/what these are at runtime. I know I can do the former via hardcoding the sim environment paths into 100+ TestFixture attributes, can I do the latter?
回答1:
I emailed the Nunit-Discuss list about this and got the below response from Charlie Poole. In brief, this isn't possible yet, but is being looked at for future versions of Nunit.
Hi,
Simply stated, what you want is coming, but it's not here yet. Parameterized fixtures are (as you have discovered) limited by the fact that you can only use arguments that are permitted in attributes. We'd like to have a way that allows use of properties and methods as for test cases but fixtures are a bit more complicated, since the type may be generic.
Have you considered using a generic fixture as a workaround? You could pass in the environment as a Type (or Types) and any constructor arguments as non-type arguments. I don't know your app, so take this with a grain of salt, but how about something like...
[TestFixture(typeof(Environment1), 42, "string")] public class TestClass<T> { IEnvironment env; public TestClass(int n, string s) { env = new T( n, s); } ... }
Note that this is "maillistcode" so may not work. :-)
Charlie
来源:https://stackoverflow.com/questions/3605567/nunit-parameterised-testfixtures-with-parameters-set-at-runtime