C# FluentAssertions 在断言失败后继续

Posted

技术标签:

【中文标题】C# FluentAssertions 在断言失败后继续【英文标题】:C# FluentAssertions continue after Failed Assertion 【发布时间】:2020-04-08 16:29:32 【问题描述】:

在 FluentAssertions 中断言失败后是否可以继续? 我有一些断言不是显示停止器,应该只报告但不会失败测试运行。

[TestClass]
public class UnitTest1

    [TestMethod]
    public void TestMethod1()
    
        using (var scope = new AssertionScope())
        
            "This Should not Failed with an AssertException".Should().Be("Should Failed");
            "And this also not".Should().Be("Should Failed");
            "All should only be printed to the console".Should().NotBeEmpty();
        
        "But the Test should continue".Should().Be("And Failed here with an AssertException");
    

【问题讨论】:

一个小的代码示例在这里肯定会有所帮助。总的来说,不要断言不重要的事情。您可以输出一些东西,只需 google 为您的单元测试框架(例如 here 是 NUnit 方式)。 我正在做 Selenium 测试,如果文本不符合预期,没有理由停止测试只是为了打印一条消息。 【参考方案1】:

对于输出端,使用 XUnit 中的 ITestOutputHelper — 这是在 XUnit 2.0+ 中获取测试日志输出的唯一方法。如果您必须将检查编写为断言,您可以提供自己的IAssertionStrategy 实现作为AssertionScope 的构造函数参数,并让它将断言失败消息发送到XUnit 的测试输出而不是抛出。

注意:您至少需要 v5.9.0 的 FluentAssertions 才能完成此操作。

public class XUnitTestOutputAssertionStrategy : IAssertionStrategy

    private readonly ITestOutputHelper output;
    private readonly List<string> failures = new List<string>();

    public XUnitTestOutputAssertionStrategy(ITestOutputHelper output)
    
        this.output = output;
    

    public void HandleFailure(string message)
    
        failures.Add(message);
    

    public IEnumerable<string> DiscardFailures()
    
        var snapshot = failures.ToArray();
        failures.Clear();
        return snapshot;
    

    public void ThrowIfAny(IDictionary<string, object> context)
    
        if (!failures.Any()) return;

        var sb = new StringBuilder();
        sb.AppendLine(string.Join(Environment.NewLine, failures));
        foreach ((string key, object value) in context)
            sb.AppendFormat("\nWith 0:\n1", key, value);

        output.WriteLine(sb.ToString());
    

    public IEnumerable<string> FailureMessages => failures;


public class ContrivedTests

    private readonly ITestOutputHelper output;

    public ContrivedTests(ITestOutputHelper output)
    
        this.output = output;
    

    [Fact]
    public void WhenRunningTest_WithContrivedExample_ShouldOutputThenAssert()
    
        using (new AssertionScope(new XUnitTestOutputAssertionStrategy(output)))
        
            "Failures will log".Should().Contain("nope", "because we want to log this");
            "Success won't log".Should().StartWith("Success", "because we want to log this too, but it succeeded");
        

        "This line will fail the test".Should().StartWith("Bottom Text", "because I pulled a sneaky on ya");
    

【讨论】:

【参考方案2】:

您可以将断言包装在AssertionScope 中,以在单个异常中捕获所有失败。另见https://fluentassertions.com/introduction#assertion-scopes

【讨论】:

您有AssertionScope 的实际用例示例吗?什么时候有用?对我来说,例如“预期值为 10,但找到 5”。知道就足够了,我不在乎是否有更多的断言失败,因为无论如何我都必须修复第一个失败的断言。 是的,但是如果我将断言包装在 AssertionScope 中并在最后执行 scope.Discard() ,它们就没有消息。如何让失败的断言输出但仍继续? 我不认为你可以,断言明确检查这一点,否则失败。如果您只想记录,也许您所要做的就是创建类似的东西,只写到控制台? scope.Discard() 将失败消息返回给您,因此您可以将它们转储到命令行或使用 XUnit 的 ITestOutputHelper

以上是关于C# FluentAssertions 在断言失败后继续的主要内容,如果未能解决你的问题,请参考以下文章

C# fluent 断言检查结果为 bool

使用 Fluent Assertions 库的多个断言

如何在 FluentAssertions 的集合断言中重用自定义对象断言

C# 单元测试 - JSON 上的断言

当类型是 C# 9 记录时,FluentAssertions Should().BeEquivalentTo() 在微不足道的情况下失败,似乎将对象视为字符串

如何使用 FluentAssertions 4.x 版断言异常?