如何在C#中使用Engine扩展构建自定义NUnit 3.x测试运行器

时间:2017-12-17 07:27:09

标签: c# nunit nunit-3.0 nunit-console

我需要运行N次测试,其中N是通过外部文件提供的。所以N不是编译时间常数。我怎样才能做到这一点?我尝试过如下实现ITestAction和IFrameworkDriver。在调试模式下运行测试时,在测试运行之前执行BeforeTest方法,在执行测试之后执行AfterTest。我假设Run方法只是为了运行测试而执行,但它没有。感谢您的帮助。

[Extension]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class CustomRunner : Attribute, ITestAction, IFrameworkDriver
{

    private NUnit3FrameworkDriver frameworkDriver = new NUnit3FrameworkDriver(AppDomain.CurrentDomain);


    #region ITestAction
    public ActionTargets Targets => ActionTargets.Test;

    public bool IsTestRunning => throw new NotImplementedException();

    public void AfterTest(ITest test)
    {
        Console.WriteLine("After test is executed");
    }

    public void BeforeTest(ITest test)
    {
        Console.WriteLine("Before test is executed");
    }

    #endregion


    public string Load(string testAssemblyPath, IDictionary<string, object> settings)
    {
        Console.WriteLine("Testting");
        return frameworkDriver.Load(testAssemblyPath, settings);
    }

    public int CountTestCases(string filter)
    {
        Console.WriteLine("Testting");
        return frameworkDriver.CountTestCases(filter);
    }

    public string Run(ITestEventListener listener, string filter)
    {
        Console.WriteLine("Testting");
        return frameworkDriver.Run(listener, filter);
    }

    public string Explore(string filter)
    {
        Console.WriteLine("Testting");
        return frameworkDriver.Explore(filter);
    }

    public void StopRun(bool force)
    {
        Console.WriteLine("Testting");
        frameworkDriver.StopRun(force);
    }

    public string ID { get { return frameworkDriver.ID; } set { frameworkDriver.ID = value; } }
}

test.cs中

[TestFixture]
public class Test 
{
    [CustomRunner]
    [Test]
    public void JustATest()
    {
        Assert.True("a".Equals("a"));
    }
}

1 个答案:

答案 0 :(得分:0)

NUnit 3基于分层架构:runners-engine-framework。与任何此类体系结构一样,这些层仅通过定义的API相互通信,并且它们的类永远不会混合。

引擎扩展是引擎层的一部分,它能够使用驱动程序所在的任何框架加载和运行测试。具体来说,编写框架驱动程序扩展以将引擎连接到它本身不理解的框架。驱动程序是引擎的扩展,不是它们支持的框架的一部分。所以你使用IFrameworkDriver接口的目的是错误的(你没有新的框架可以连接,而且已经有NUnit 3框架驱动程序)并且在它的实现中(有一个属性引用引擎并提供驱动程序没有效果,因为没有什么可以称之为。)

ITestAction界面 是框架的一部分,如果使用正确,您的操作将在每次测试运行之前和之后调用。但是,它对 测试的运行没有影响。

由于您需要一个与现有RetryAttribute类似的属性但从文件中获取计数的属性,我们可能会考虑从RetryAttribute派生新类。不幸的是,虽然没有密封,但是类使用私有成员并且没有要覆盖的虚拟方法。它不是设计用作基类。

OTOH,RetryAttribute是一个非常小的类。我的最终建议是你只需复制和修改它。仔细研究它的实现将澄清很多关于自定义属性如何为您工作的事情。