49

是否可以跳过特定类中的所有测试,例如 NUnit

[TestFixture]
[Ignore("Reason")]
public class TestClass {
}
4

10 回答 10

48

没有-目前没有这样的设施

在 xUnit 中实现该效果的一种快速方法是注释掉public- 私有类不被反映(但显然它不会以这种方式出现在跳过列表中)。

如果您觉得对此的需求足够普遍,请考虑将其作为问题记录在 CodePlex 上(我个人无法想象赞成它,因为我根本不会遇到需要跳过整个测试类的测试的情况)。

更新:另一种方法是TraitAttribute在类上放置一个,然后(假设您正在使用xunit.console跑步者)通过运行过滤掉它/-trait traitName。(例如,您可以通过ExplicitAttribute这种方式实现待定测试的 BDD 框架技术的某些方面和类似的语义 - 当然,最大的问题是在使用任何这些过滤技术时它们不会出现在任何报告中)

更新2:你可以做

const string skip = "Class X disabled";

[Fact(Skip=skip)]
void Test() {}

然后您可以更改为const string skip = null以撤消跳过。这样做的(缺点)优点是测试仍然在测试列表中显示为已跳过的测试,通常在测试运行报告中包含一个原因(而不是private让它可能被遗忘)

于 2013-02-13T03:02:53.807 回答
4

这是我避免错误 xUnit1000 的技巧:测试类必须是公共的(检查单个事实,我认为理论也可以通过这种方式被破解)。

// Uncomment to enable tests
//public class FactSwitch : FactAttribute { } // public! ahh, a bug!

// Uncomment to disable tests
internal class FactSwitch : Attribute { }

public class MyTests
{
    [FactSwitch]
    public void MyTest1()
    {
        "it".ShouldBe("it");
    }
}

(3年后)

在寻找相同的解决方案时,我发现有更好的方法可以做到这一点。让我们按照 Ruben Bartelink 建议的方式重写上面的示例(继续他的想法)。

public class MyTests
{
    //const string SkipOrNot = null; // Run all tests
    const string SkipOrNot = "reason"; // Skip all tests

    [Fact(Skip = SkipOrNot)]
    public void MyTest1()
    {
        "it".ShouldBe("it");
    }
}

Nathan Cooper 对我的想法提出了一个很好的改进:

public class MyTests
{
    // Uncomment to disable tests
    //private class FactAttribute : Attribute { }

    [Fact]
    public void MyTest1()
    {
        "it".ShouldBe("it");
    }
}

所以我喜欢鲁本和内森的两个想法。使用 Skip="something" (Ruben) 和根本不使用 Skip 之间存在细微差别。使用“Skip”会将所有测试置于“Skipped tests”警告区,而“FactAttribute : Attribute”将隐藏它们。

于 2018-01-16T13:08:04.950 回答
2

这是另一个需要对代码进行最少更改的 hack

using FactAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;
using TheoryAttribute = System.Runtime.CompilerServices.CompilerGeneratedAttribute;

任何兼容的属性都可以用于替换。

如果您还使用了,InlineDataAttribute那么您需要定义一个替换,因为我认为没有现有的 compatible 属性。

using InlineDataAttribute = DummyDataAttribute;

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
internal class DummyDataAttribute : Attribute
{
    public DummyDataAttribute(params object[] data)
    {
    }
}
于 2018-11-26T08:07:18.990 回答
2

我发现了另一种在没有编译器警告的情况下临时禁用整个类的方法。

禁用:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
/*
public /**/class DatabaseTests
{
}

启用向上移动/*一行(即使用 alt+up):

/*
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]//*/
public /**/class DatabaseTests
{
}

请注意,使用 SupressMessage 的完整命名空间路径不会弄乱您的使用。

于 2020-03-30T18:42:38.307 回答
2

您可以创建LocalOnlyFactAttribute

    public class LocalOnlyFactAttribute : FactAttribute
    {
        //uncomment to run on local
        //const string skip = null; 

        //keep this to avoid slow running tests on other env
        const string skip = "Disabled slow running tests."; 

        public override string Skip { get => skip; set => base.Skip = value; }
    }   
于 2020-05-14T01:42:24.943 回答
2

据我所知,在运行时动态跳过整个 xUnit 测试类的最简单方法是在TestFrameworkAttribute程序集级别使用方法返回另一个实现接口的类(或从 继承,这更简单),您最终可以在其中覆盖该方法,以决定是否应该跳过一个类。ITestFrameworkXunitTestFrameworkCreateDiscoverer()ITestFrameworkDiscovererXunitTestFrameworkDiscovererIsValidTestClass()

这是一些示例代码:

[assembly: TestFramework("MyNamespace.Xunit.MyTestFramework", "MyAssembly")]

namespace MyNamespace.Xunit
{
    public class MyTestFramework : XunitTestFramework
    {
        public MyTestFramework(IMessageSink messageSink)
            : base(messageSink)
        {
        }

        protected override ITestFrameworkDiscoverer CreateDiscoverer(
            IAssemblyInfo assemblyInfo)
            => new MyTestFrameworkDiscoverer(
                assemblyInfo,
                SourceInformationProvider,
                DiagnosticMessageSink);
    }

    public class MyTestFrameworkDiscoverer : XunitTestFrameworkDiscoverer
    {
        public MyTestFrameworkDiscoverer(
            IAssemblyInfo assemblyInfo,
            ISourceInformationProvider sourceProvider,
            IMessageSink diagnosticMessageSink,
            IXunitTestCollectionFactory collectionFactory = null)
            : base(
                assemblyInfo,
                sourceProvider,
                diagnosticMessageSink,
                collectionFactory)
        {
        }

        protected override bool IsValidTestClass(ITypeInfo type)
            => base.IsValidTestClass(type) &&
               FilterType(type);

        protected virtual bool FilterType(ITypeInfo type)
        {
            // Insert your custom filter conditions here.
            return true;
        }
    }
}

用 xUnit 测试2.4.1

我们在 Pomelo.EntityFrameworkCore.MySql 中使用它(参见AssemblyInfo.csMySqlXunitTestFrameworkDiscoverer.cs)(比这里的示例代码复杂一点)。

于 2021-04-24T14:26:10.187 回答
1

在最初的问题之后几乎一年后添加了一个原因。我有一组调用真实服务器 api 的测试,我想按需运行。使用 nUnit,它具有 Ignore 属性:使用该设置,测试运行器将跳过这些测试,但我仍然可以手动运行它。

xUnit 没有这样的功能。最接近的是设置这样的类级别属性,并在我想运行它时将其注释掉。

于 2014-02-06T00:44:30.773 回答
1

您可以通过自定义 ITestClassCommand 实现此目的。

http://mariangemarcano.blogspot.be/2010/12/xunitnet-running-tests-testcategory.html

于 2014-08-15T12:52:34.063 回答
1

您需要将您的班级访问级别设置为内部和隐藏消息,就像@Miq 所做的那样:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "xUnit1000:Test classes must be public", Justification = "Disabled")]
internal class MyClassThatIsNotATestClass
{ ... }
于 2020-06-15T01:37:53.520 回答
0

考虑创建LocalOnlyFactAttribute,它可以在多个测试文件中重复使用。


    public class LocalOnlyFactAttribute : FactAttribute
    {
        //uncomment to run on local
        //const string skip = null; 

        //keep this to avoid slow running tests on other env
        const string skip = "Disabled slow running tests."; 

        public override string Skip { get => skip; set => this.Skip = value; }
    }   
于 2020-05-14T01:49:34.170 回答