简体   繁体   English

从TestCaseSource(NUnit)中的TestFixture访问值

[英]Accessing value from TestFixture in TestCaseSource (NUnit)

Let's have this setup: 让我们进行以下设置:

[TestFixture(10)]
[TestFixture(20)]
public class TestClass
{
    int I;

    public TestClass(int i)
    {
        I = i;
    }

    [TestCaseSource(typeof(TestSource))]
    public void Test(string name)
    {
        TestContext.WriteLine(name);
    }

    class TestSource : IEnumerable<TestCaseData>
    {
        public IEnumerator<TestCaseData> GetEnumerator()
        {
            yield return new TestCaseData("AAA") { TestName = $"Test" };                
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}

Is there a way to somehow get the current TestFixture value ( 10 or 20 in this case) when generating tests in TestCaseSource (either using class or method, doesn't matter for me)? TestCaseSource生成测试时(使用类或方法,对我来说无关紧要),是否有办法以某种方式获取当前的TestFixture值(在这种情况下为1020 )? I know I can workaround that by ie deriving classes or duplicating the methods, but I hope for clean solution (before queuing plan B). 我知道我可以通过派生类或复制方法来解决此问题,但是我希望有一个干净的解决方案(在计划B排队之前)。

Sorry to say that this can't work. 抱歉地说这行不通。 :-( :-(

First of all, let's be clear that your nested testcasesource class has no special standing with NUnit due to it's being nested. 首先,让我们清楚一点,由于嵌套,嵌套的testcasesource类在NUnit中没有特殊的地位。 It is instantiated independently of the test fixture class and works exactly as it would work if it were not nested. 它独立于测试夹具类进行实例化,并且与未嵌套时的工作原理完全相同。

Here is the sequence of things at test discovery time: 这是测试发现时的顺序:

  1. NUnit identifies your test fixture and takes note of the fact that it is will (later) be instantiated twice. NUnit标识您的测试治具,并注意将其(以后)实例化两次的事实。 It notes the arguments for naming purposes. 它记录了用于命名目的的参数。 This gives us two fixtures, each of which needs to have its tests discovered. 这给了我们两个夹具,每个夹具都需要进行测试。

  2. NUnit looks at all the methods in each fixture to find tests. NUnit会查看每个灯具中的所有方法以查找测试。 When it comes to the TestCaseSourceAttribute, it instantiates the source class and uses it's IEnumerable interface to acquire test cases. 当涉及到TestCaseSourceAttribute时,它将实例化源类并使用其IEnumerable接口来获取测试用例。

Later (seconds, minutes, years?) NUnit executes your tests. 稍后(几秒钟,几分钟,几年?),NUnit执行您的测试。 When it reaches the fixture in question, it instantiates it twice, once using 10, and once with 20. The test cases which were previously identified are run. 当它到达所讨论的灯具时,将其实例化两次,一次使用10,一次使用20。运行先前确定的测试用例。

As you can see, the test fixture is not even instantiated at the time the tests are discovered. 如您所见,在发现测试时,甚至没有实例化测试夹具。 Of course, NUnit "knows about" the arguments and theoretically could provide some sort of substitution facility, but no such facility exists - and it would be very complicated to create since in general it could involve simulating arbitrary execution of the fixture's methods. 当然,NUnit“知道”这些参数,并且理论上可以提供某种替代工具,但是这种替代工具不存在-创建起来将非常复杂,因为通常它可能涉及模拟夹具方法的任意执行。

Storing the value of the argument in the constructor and accessing it from the test is the "standard" way of solving this problem. 将参数的值存储在构造函数中并从测试中访问它是解决此问题的“标准”方法。 If there is something you want to do that won't work using that technique, it would be best to spell it out more clearly so we can see if there is workaround. 如果您要执行的某项操作无法使用该技术,则最好将其拼写清楚,以便我们查看是否有解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM