You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Xunit Fact属性后如何集成SkippableFact实现警告结果

Automatically Switch Between Skippable and Regular Xunit Tests Based on Traits

Hey there! Let's tackle this problem step by step. I understand you want your custom Xunit Fact/Theory attributes to automatically use skippable behavior (for warning states) when a specific trait (like TestScope.Skippable) is present, while falling back to regular pass/fail behavior otherwise. Here's how to make this work:

1. Create Custom Wrapper Attributes

First, define custom versions of your Fact and Theory attributes that point to a custom test case discoverer. These will replace your existing custom attributes:

using Xunit;
using Xunit.Sdk;

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("YourProjectNamespace.CustomSkippableFactDiscoverer", "YourProjectAssemblyName")]
public class CustomFactAttribute : FactAttribute
{
    // Keep any existing properties/logic from your original custom Fact attribute here
}

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
[XunitTestCaseDiscoverer("YourProjectNamespace.CustomSkippableTheoryDiscoverer", "YourProjectAssemblyName")]
public class CustomTheoryAttribute : TheoryAttribute
{
    // Keep any existing properties/logic from your original custom Theory attribute here
}

Replace YourProjectNamespace and YourProjectAssemblyName with your actual project details.

2. Implement Custom Test Case Discoverers

These discoverers will check for the Skippable trait and decide whether to use skippable test logic or regular Xunit logic.

For Fact Tests

using System.Collections.Generic;
using Xunit.Abstractions;
using Xunit.Sdk;
using SkippableFactDiscoverer = Xunit.SkippableFact.SkippableFactDiscoverer;

public class CustomSkippableFactDiscoverer : SkippableFactDiscoverer
{
    public CustomSkippableFactDiscoverer(IMessageSink messageSink) : base(messageSink) { }

    public override IEnumerable<IXunitTestCase> CreateTestCases(
        ITestFrameworkDiscoveryOptions discoveryOptions,
        ITestMethod testMethod,
        IAttributeInfo factAttribute)
    {
        // Check if the test has the Skippable trait in its Tags
        var hasSkippableTrait = testMethod.Traits.TryGetValue("Tags", out var traitValues) &&
                               traitValues.Contains(TestScope.Skippable.ToString());

        if (hasSkippableTrait)
        {
            // Use SkippableFact logic to enable warning/skip behavior
            return base.CreateTestCases(discoveryOptions, testMethod, factAttribute);
        }
        else
        {
            // Fall back to regular Fact behavior
            var defaultFactDiscoverer = new FactDiscoverer(MessageSink);
            return defaultFactDiscoverer.CreateTestCases(discoveryOptions, testMethod, factAttribute);
        }
    }
}

For Theory Tests

using System.Collections.Generic;
using Xunit.Abstractions;
using Xunit.Sdk;
using SkippableTheoryDiscoverer = Xunit.SkippableFact.SkippableTheoryDiscoverer;

public class CustomSkippableTheoryDiscoverer : SkippableTheoryDiscoverer
{
    public CustomSkippableTheoryDiscoverer(IMessageSink messageSink) : base(messageSink) { }

    public override IEnumerable<IXunitTestCase> CreateTestCases(
        ITestFrameworkDiscoveryOptions discoveryOptions,
        ITestMethod testMethod,
        IAttributeInfo theoryAttribute)
    {
        var hasSkippableTrait = testMethod.Traits.TryGetValue("Tags", out var traitValues) &&
                               traitValues.Contains(TestScope.Skippable.ToString());

        if (hasSkippableTrait)
        {
            // Use SkippableTheory logic for warning/skip behavior
            return base.CreateTestCases(discoveryOptions, testMethod, theoryAttribute);
        }
        else
        {
            // Fall back to regular Theory behavior
            var defaultTheoryDiscoverer = new TheoryDiscoverer(MessageSink);
            return defaultTheoryDiscoverer.CreateTestCases(discoveryOptions, testMethod, theoryAttribute);
        }
    }
}

3. Update Your Tests

Replace your existing custom Fact/Theory attributes with the new [CustomFact]/[CustomTheory] attributes. The discoverer will handle the rest automatically:

[UI, Scenario("Example"), Tags(TestScope.Smoke, TestScope.Skippable, Priority.One)]
[Evaluate("Example")]
[CustomFact] // Use the new custom attribute
public async Task ExampleTest() {
    Skip.If(Data == 0, "No Data to run smoke test"); // Now shows a warning instead of failing!
}

Key Notes

  • Make sure you have the xunit.SkippableFact NuGet package installed in your project.
  • Verify that TestScope.Skippable.ToString() matches the exact value stored in the Tags trait (enums default to their name, so this should work if you're using an enum).
  • This setup preserves your existing custom attribute logic while adding conditional skippable behavior based on traits.

内容的提问来源于stack exchange,提问作者rowdog_14

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:15:03