【问题标题】:xUnit - Display test names for theory memberdata (TestCase)xUnit - 显示理论成员数据的测试名称(TestCase)
【发布时间】:2017-10-14 20:43:13
【问题描述】:

我一直在使用 NUnit 进行测试,我非常喜欢测试用例。在 NUnit 中,您可以使用 TestCaseData 类中的 SetName 函数轻松设置测试用例中的每个测试名称。

xUnit 有类似的功能吗?

目前我只能在测试资源管理器中看到一个测试,即使我在测试用例中有 6 个测试。

xUnit 测试

public class LogHandler : TestBase
{
    private ILogger _logger;

    public LogHandler()
    {
        //Arrange
        LogAppSettings logAppSettings = GetAppSettings<LogAppSettings>("Log");

        IOptions<LogAppSettings> options = Options.Create(logAppSettings);

        LogService logService = new LogService(new Mock<IIdentityService>().Object, options);

        LogProvider logProvider = new LogProvider(logService);

        _logger = logProvider.CreateLogger(null);
    }

    public static IEnumerable<object[]> TestCases => new[]
    {
        new object[] { LogLevel.Critical,
            new EventId(),
            new Exception(),
            1 },
        new object[] { LogLevel.Error,
            new EventId(),
            new Exception(),
            1 },
        new object[] { LogLevel.Warning,
            new EventId(),
            new Exception(),
            0 },
        new object[] { LogLevel.Information,
            new EventId(),
            new Exception(),
            0 },
        new object[] { LogLevel.Debug,
            new EventId(),
            new Exception(),
            0 },
        new object[] { LogLevel.Trace,
            new EventId(),
            new Exception(),
            0 },
        new object[] { LogLevel.None,
            new EventId(),
            new Exception(),
            0 }
    };

    [Theory, MemberData(nameof(TestCases))]
    public void Test(LogLevel logLevel, EventId eventId, Exception exception, int count)
    {
        //Act
        _logger.Log<object>(logLevel, eventId, null, exception, null);

        //Assert
        int exceptionCount = Database.Exception.Count();

        Assert.Equal(exceptionCount, count);
    }
}

xUnit 测试窗口

这里应该是 6 个测试而不是 1 个! (忽略 GetOrganisationStatuses)。

NUnit 测试用例

public static IEnumerable TestDatabaseCases
{
    get
    {
        yield return new TestCaseData(LogLevel.Critical,
            new EventId(1),
            new Exception("Exception"),
            0,
            1).SetName("InsertException_Should_Insert_When_LogLevel_Critical");

        yield return new TestCaseData(LogLevel.Error,
            new EventId(1),
            new Exception("Exception"),
            0,
            1).SetName("InsertException_Should_Insert_When_LogLevel_Error");

        yield return new TestCaseData(LogLevel.Warning,
            new EventId(1),
            new Exception("Exception"),
            0,
            0).SetName("InsertException_Should_Not_Insert_When_LogLevel_Warning");

        yield return new TestCaseData(LogLevel.Information,
            new EventId(1),
            new Exception("Exception"),
            0,
            0).SetName("InsertException_Should_Not_Insert_When_LogLevel_Information");

        yield return new TestCaseData(LogLevel.Debug,
            new EventId(1),
            new Exception("Exception"),
            0,
            0).SetName("InsertException_Should_Not_Insert_When_LogLevel_Debug");
    }
}

NUnit 测试窗口

这就是我想要的 xUnit!

如何在 xUnit 中为测试用例中的每个测试设置名称?

【问题讨论】:

  • 我之前也遇到过同样的问题。您的类将需要从 IXunitSerializable 继承。实现起来比较麻烦。。不知道有没有更好的方法。
  • 有一个现成的实现,它绕过了更改被测代码和测试代码的需要。只需包含新的自定义 xUnit TheoryAttribute、XunitDiscoverer 类和两个测试类 - 有关详细信息和 MIT 许可的工作代码,请参见第二个答案。

标签: c# asp.net .net asp.net-core xunit


【解决方案1】:

目前我只能在测试资源管理器中看到一个测试,即使我在测试用例中有 6 个测试。

这是因为您的测试数据不被 xUnit.net 视为可序列化的。看到这个问题:https://github.com/xunit/xunit/issues/1473

突出的细节是:

简短的回答

如果你的一些理论数据不能被 xUnit.net “序列化”,那么 它不能被封装到一个测试用例的序列化中 我们需要为 Visual Studio 测试运行程序做。

长答案

在 Visual Studio 测试运行器中,测试用例在一个中发现 进程,并在另一个进程中执行。因此,测试用例必须能够 变成一个不合格的字符串表示(又名, “序列化”)以便运行。我们也可以在测试时序列化 方法级别,因为这仅涉及了解类型和方法 名称(两个字符串)。当您开始将数据放入混合中时,我们需要 确保我们知道如何序列化该数据;如果我们不能序列化 所有数据用于一个理论,然后我们必须回退到一个单一的方法(我们知道我们可以序列化)。

完整答案包含更多细节。

在 NUnit 中,您可以使用 TestCaseData 类中的 SetName 函数轻松设置测试用例中的每个测试名称。

xUnit 有类似的功能吗?

暂时没有。

【讨论】:

  • 太遗憾了.. 就目前而言,我将继续使用 NUnit。希望他们能解决这个问题。
  • @Reft Common 这不是一个耻辱,而是一个小的限制,可以通过一小段代码轻松弥补 - 请参阅下面的答案。无论如何,xUnit 是 DotNet 世界中大量最重要的存储库的首选测试框架。
  • @JacekBlaszczynski 你能评论一下这些原因可能是什么吗?
【解决方案2】:

这对我有用:

public class TestScenario
{
...
    public override string ToString()
    {
        return $"Role: {Role}...";
    }
}
    [Theory]
    [ClassData(typeof(MyProvider))]
    public void TestScenarios(TestScenario scenaro)
    {
        TestScenarioInternal(scenaro);

    }

【讨论】:

  • 这正是我想要的,谢谢!
【解决方案3】:

实际上,有一个可行的解决方案需要一些管道代码,这些代码应该适用于未更改的测试。它需要实现自定义 TheoryAttribute、自定义 TheoryDiscoverer 和自定义 TestCase 类。整个解决方案在这个 repo DjvuNet/DjvuNet.Shared.Tests 的 MIT 许可下可用。

具有实现的必需文件是: DjvuTheoryAttributeDjvuTheoryDiscovererDjvuNamedDataRowTestCaseDjvuDataRowTestCase

用法很简单:将上述文件编译为直接包含在测试程序集中或作为单独的程序集,并在代码中以follows 的形式使用它们:

    [DjvuTheory]
    [ClassData(typeof(DjvuJsonDataSource))]
    public void DirmChunk_Theory(DjvuJsonDocument doc, int index)
    {
        int pageCount = 0;
        using (DjvuDocument document = DjvuNet.Tests.Util.GetTestDocument(index, out pageCount))
        {
            DjvuNet.Tests.Util.VerifyDjvuDocument(pageCount, document);
            DjvuNet.Tests.Util.VerifyDjvuDocumentCtor(pageCount, document);

            // DirmChunk is present only in multi page documents
            // in which root form is of DjvmChunk type
            if (document.RootForm.ChunkType == ChunkType.Djvm)
            {
                DirmChunk dirm = ((DjvmChunk)document.RootForm).Dirm;

                Assert.NotNull(dirm);

                Assert.True(dirm.IsBundled ? doc.Data.Dirm.DocumentType == "bundled" : doc.Data.Dirm.DocumentType == "indirect");

                var components = dirm.Components;
                Assert.Equal<int>(components.Count, doc.Data.Dirm.FileCount);
            }
        }
    }

其中一个理论函数参数在 xUnit 中不可序列化,但尽管理论测试将单独显示并编号。如果理论函数的第一个参数是字符串类型,除了作为函数调用的参数外,它还将用作测试的名称。

这个想法归功于其他开发人员 - 我必须找到指向他的代码的链接 - 但它是为 DjvuNet 项目从头开始重新实现的。

【讨论】:

    猜你喜欢
    • 2017-01-26
    • 2017-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2015-03-11
    • 1970-01-01
    相关资源
    最近更新 更多