xunit 以编程方式添加新测试/“[事实]"? [英] xunit programmatically add new tests/"[Facts]"?

查看:51
本文介绍了xunit 以编程方式添加新测试/“[事实]"?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个文件夹,里面装满了需要设置为单个 URI 的 JSON 文本文件.目前这一切都是用一个 xUnit "[Fact]" 完成的,如下所示

We have a folder full of JSON text files that need to be set to a single URI. Currently it's all done with a single xUnit "[Fact]" as below

[Fact]
public void TestAllCases()
{
    PileOfTests pot = new PileOfTests();
    pot.RunAll();
}

pot.RunAll() 然后解析文件夹,加载 JSON 文件(比如 50 个文件).然后每个都针对 URI 进行锤击,以查看每个都返回 HTTP 200(ok").如果有任何失败,我们目前正在使用

pot.RunAll() then parses the folder, loads the JSON files (say 50 files). Each is then hammered against the URI to see is each returns HTTP 200 ("ok"). If any fail, we're currently printing it as a fail by using

System.Console.WriteLine("\n >> FAILED ! << " + testname + "\n");

这确实确保了失败引起了我们的注意,但 xUnit 认为所有测试都失败了(可以理解).最重要的是,我们不能指定 xunit在这里,只运行这个特定的测试".它目前的构建方式要么全有要么全无.

This does ensure that failures catch our eye but xUnit thinks all tests failed (understandably). Most importantly, we can't specify to xunit "here, run only this specific test". It's all or nothing the way it's currently built.

如何以编程方式添加测试用例?当我阅读 *.json 文件的数量和名称时,我想添加它们.

How can I programmatically add test cases? I'd like to add them when I read the number and names of the *.json files.

推荐答案

简单的答案是:,不是直接的.但是存在一种变通方法,尽管有点笨拙,如下所示.

The simple answer is: No, not directly. But there exists an, albeit a bit hacky, workaround, which is presented below.

通过在类上指定 [RunWith(typeof(CustomRunner))],可以指示 xUnit 使用 CustomRunner 类 - 该类必须实现 Xunit.Sdk.ITestClassCommand - 枚举使用此属性修饰的测试类上可用的测试.

By specifiying the [RunWith(typeof(CustomRunner))] on a class, one can instruct xUnit to use the CustomRunner class - which must implement Xunit.Sdk.ITestClassCommand - to enumerate the tests available on the test class decorated with this attribute.

但不幸的是,虽然测试方法的调用已经从 System.Reflection + 实际方法中解耦了,通过测试运行到测试运行器的方式还没有.

But unfortunately, while the invocation of test methods has been decoupled from System.Reflection + the actual methods, the way of passing the tests to run to the test runner haven't.

在用于调用特定测试方法的 xUnit 框架代码中的某处,有一个对 typeof(YourTestClass).GetMethod(testName) 的调用.

Somewhere down in the xUnit framework code for invoking a specific test method, there is a call to typeof(YourTestClass).GetMethod(testName).

这意味着,如果实现测试发现的类返回的测试名称不引用测试类上的真实方法,则该测试将显示在 xUnit GUI 中 - 但任何运行/调用它的尝试都会结束带有 TargetInvocationException.

This means that if the class implementing the test discovery returns a test name that doesn't refer to a real method on the test class, the test is shown in the xUnit GUI - but any attempts to run / invoke it end up with a TargetInvocationException.

仔细想想,解决方法本身相对简单.可以在此处找到它的有效实现.

If one thinks about it, the workaround itself is relatively straightforward. A working implementation of it can be found here.

所提供的解决方案首先读取文件的名称,这些文件应在 xUnit GUI 中显示为不同的测试.然后它使用 System.Reflection.Emit 动态生成带有测试类的程序集,其中包含针对每个输入文件的专用测试方法.

The presented solution first reads in the names of the files which should appear as different tests in the xUnit GUI. It then uses System.Reflection.Emit to dynamically generate an assembly with a test class containing a dedicated test method for each of the input files.

每个生成的方法所做的唯一一件事就是在指定了 [EnumerateFilesFixture(...)]RunTest(string fileName) 方法> 属性.有关进一步说明,请参阅链接的要点.

The only thing that each of the generated methods does is to invoke the RunTest(string fileName) method on the class that specified the [EnumerateFilesFixture(...)] attribute. See linked gist for further explanation.

希望这有帮助;如果您愿意,可以随意使用示例实现.

Hope this helps; feel free to use the example implementation if you like.

这篇关于xunit 以编程方式添加新测试/“[事实]"?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆