我一直在使用NUnit进行测试,而且我非常喜欢测试用例。在NUnit中,您可以使用TestCaseData类中的SetName函数轻松地在测试用例中设置每个测试名称。
xUnit是否具有类似的功能?
目前我只能在测试资源管理器中看到一个测试,即使我在测试用例中有6个测试。
xUnit test
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次测试,而不是一次! (忽略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中为测试用例中的每个测试设置一个名称?
答案 0 :(得分:6)
目前我只能在测试资源管理器中看到一个测试,即使我在测试用例中有6个测试。
这是因为xUnit.net不会将您的测试数据视为可序列化的。请参阅此问题:https://github.com/xunit/xunit/issues/1473
显着的细节是:
简短回答
如果你的某些理论数据不能被xUnit.net“序列化”,那么 它不能封装到测试用例的序列化中 我们需要为Visual Studio测试运行器做。
答案很长
在Visual Studio测试运行器中,可以在一个测试用例中发现测试用例 过程,并在另一个执行。因此,测试用例必须能够 变成一个不合格的字符串表示(又名, “序列化”)以便运行。我们也可以在测试中序列化 方法级别,因为这只涉及知道类型和方法 名称(两个字符串)。当你开始将数据放入混合中时,我们需要 确保我们知道如何序列化这些数据;如果我们不能序列化 理论数据的 所有 ,然后我们必须回归到一个方法(我们知道我们可以序列化)。
完整的答案包含更多细节。
在NUnit中,您可以使用TestCaseData类中的SetName函数轻松地在测试用例中设置每个测试名称。
xUnit是否具有类似的功能?
目前还没有。
答案 1 :(得分:1)
实际上有一个工作解决方案需要一些管道代码,这些代码可以在未更改的测试中使用。它需要实现自定义TheoryAttribute,自定义TheoryDiscoverer和自定义TestCase类。整个解决方案在此回购DjvuNet/DjvuNet.Shared.Tests的MIT许可下可用。
具有实现的必需文件是: DjvuTheoryAttribute,DjvuTheoryDiscoverer,DjvuNamedDataRowTestCase,DjvuDataRowTestCase
用法很简单:编译上面的文件,将它们直接包含在测试程序集中或作为单独的程序集,并在代码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项目重新实现的。
答案 2 :(得分:-1)
这对我有用:
public class TestScenario
{
...
public override string ToString()
{
return $"Role: {Role}...";
}
}
[Theory]
[ClassData(typeof(MyProvider))]
public void TestScenarios(TestScenario scenaro)
{
TestScenarioInternal(scenaro);
}