简体   繁体   English

C#xUnit测试监听器

[英]C# xUnit Test listeners

I'm building a selenium test framework based on .Net Core and the team decided to go with xUnit. 我正在构建一个基于.Net Core的selenium测试框架,团队决定使用xUnit。 All's well and good everything has been going ok but for a while now, we've been trying to replicate the functionality of Java TestNG listeners without much luck. 一切都很好,一切都很顺利,但有一段时间了,我们一直试图复制Java TestNG听众的功能而没有太多运气。

I've been digging around the xunit git repo and found a few instances where some interfaces such ITestListener have been used. 我一直在挖掘xunit git repo,发现了一些使用ITestListener等接口的实例。 After digging deeper, I found that these listeners are from a package called TestDriven.Framework and I wanted to know exactly how would I use a test listener created using those interfaces? 在深入挖掘之后,我发现这些监听器来自一个名为TestDriven.Framework的包,我想知道我将如何使用这些接口创建的测试监听器?

So far this is my simple test listener that should write something when the test fails: 到目前为止,这是我的简单测试监听器,在测试失败时应该写一些东西:

public class Listener
{
    readonly int totalTests;

    public Listener(ITestListener listener, int totalTests)
    {
        this.totalTests = totalTests;
        TestListener = listener;
        TestRunState = TestRunState.NoTests;
    }

    public ITestListener TestListener { get; private set; }
    public TestRunState TestRunState { get; set; }

    public void onTestFail(ITestFailed args)
    {
        Console.WriteLine(args.Messages);
    }

}

Now, I know you can do this inside a tear down hook but remember, this is just a simple example and what I have in mind is something more complex. 现在,我知道你可以在一个撕裂的钩子里做到这一点,但请记住,这只是一个简单的例子,我想到的是更复杂的东西。 So to be precise, where/how exactly would I register the test to use this listener? 那么准确地说,我将在何处/如何注册测试以使用此侦听器? In Java TestNg I would have @Listeners but in C# I'm not too sure. 在Java TestNg中我会有@Listeners但在C#中我不太确定。

Edit 1 so the example worked and managed to add it to my own project structure but when I try to use this 编辑1以便示例工作并设法将其添加到我自己的项目结构中,但是当我尝试使用它时

    class TestPassed : TestResultMessage, ITestPassed
{
    /// <summary>
    /// Initializes a new instance of the <see cref="TestPassed"/> class.
    /// </summary>
    public TestPassed(ITest test, decimal executionTime, string output)
        : base(test, executionTime, output) {
        Console.WriteLine("Execution time was an awesome " + executionTime);
    }
}

I'm having trouble registering this one, or if i'm even registering it right. 我无法注册这个,或者我甚至正在注册它。 As far as the examples go, I have found the actual message sinks but also found the actual test status data which i'm not exactly sure how to use. 就示例而言,我已经找到了实际的消息接收器,但也找到了我不确定如何使用的实际测试状态数据。

I haven't worked with TestNG, but I did some quick reading and I think I see what you're after. 我没有和TestNG合作,但是我做了一些快速阅读,我我看到了你所追求的。

To demonstrate, I've implemented a very basic proof-of-concept xUnit IMessageSink . 为了演示,我实现了一个非常基本的概念验证xUnit IMessageSink

public class MyMessageSink : IMessageSink
{
    public bool OnMessage(IMessageSinkMessage message)
    {
        // Do what you want to in response to events here.
        // 
        // Each event has a corresponding implementation of IMessageSinkMessage.
        // See examples here: https://github.com/xunit/abstractions.xunit/tree/master/src/xunit.abstractions/Messages
        if (message is ITestPassed)
        {
            // Beware that this message won't actually appear in the Visual Studio Test Output console.
            // It's just here as an example. You can set a breakpoint to see that the line is hit.
            Console.WriteLine("Execution time was an awesome " + ((ITestPassed)message).ExecutionTime);
        }

        // Return `false` if you want to interrupt test execution.
        return true;
    }
}

The sink is then registered via an IRunnerReporter : 然后通过IRunnerReporter注册接收IRunnerReporter

public class MyRunnerReporter : IRunnerReporter
{
    public string Description => "My custom runner reporter";

    // Hard-coding `true` means this reporter will always be enabled.
    //
    // You can also implement logic to conditional enable/disable the reporter.
    // Most reporters based this decision on an environment variable.
    // Eg: https://github.com/xunit/xunit/blob/cbf28f6d911747fc2bcd64b6f57663aecac91a4c/src/xunit.runner.reporters/TeamCityReporter.cs#L11
    public bool IsEnvironmentallyEnabled => true;

    public string RunnerSwitch => "mycustomrunnerreporter";

    public IMessageSink CreateMessageHandler(IRunnerLogger logger)
    {
        return new MyMessageSink();
    }
}

To use my example code, just copy the classes into your test project (you'll also need to add a reference to the xunit.runner.utility NuGet package). 要使用我的示例代码,只需将类复制到测试项目中(您还需要添加对xunit.runner.utility NuGet包的引用)。 The xUnit framework will automagically discover the IRunnerReporter --no need to explicitly register anything. xUnit框架将自动发现IRunnerReporter无需显式注册任何内容。

If this seems like it's headed in the right direction, you can find a lot more info in the xUnit source code. 如果这似乎朝着正确的方向前进,您可以在xUnit源代码中找到更多信息。 All of the interfaces involved are well-documented. 所涉及的所有接口都有详细记录。 There are a few existing implementations in the xunit.runner.reporters namespace . xunit.runner.reporters命名空间中有一些现有的实现。 AssemblyRunner.cs also demonstrates one possible method for dispatching the different event types to individual handlers. AssemblyRunner.cs还演示了一种可能的方法,用于将不同的事件类型分派给各个处理程序。

Edit 1 编辑1

I've updated the implementation of MyMessageSink (above) to demonstrate how you might listen for an ITestPassed message. 我已经更新了MyMessageSink (上面)的实现,以演示如何监听ITestPassed消息。 I also updated the link embedded in that code snippet--the previous link was to implementations, but we should really use these abstractions. 我还更新了代码片段中嵌入的链接 - 前一个链接是实现,但我们应该真正使用这些抽象。

The if (message is IMessageType) pattern is pretty crude, and won't scale well if you want to listen for many different message types. if (message is IMessageType)模式非常粗糙,如果您想要侦听许多不同的消息类型,则无法很好地扩展。 Since I don't know your needs, I just went with the simplest thing that could possibly work--hopefully it's enough that you can improve/extend it to fit your needs. 由于我不了解您的需求,我只是选择了最简单的方法 - 希望您可以改进/扩展它以满足您的需求。

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

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