[英]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还演示了一种可能的方法,用于将不同的事件类型分派给各个处理程序。
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.