在Visual Studio中如何查看XUnit测试的运行顺序?
查看XUnit串行测试执行顺序的简便方案
针对你遇到的偶现Heisenbug问题,不用修改所有测试代码,有以下几种简便方法查看测试执行顺序或目标测试的前置测试:
1. 直接用dotnet test诊断日志(最快捷)
在命令行运行测试时加上诊断日志参数,会输出每个测试的启动/结束时间和完整名称:
dotnet test -v diag
运行后,在输出的日志里搜索目标测试的名称,向前查找最近的Starting test method条目,就是它的上一个执行测试。日志会按时间顺序输出,完全不需要修改任何代码。
2. 自定义测试基类(少量代码修改)
创建一个所有测试类都继承的基类,在基类的构造函数中记录测试执行顺序,只需要修改基类一次,不用改动800个测试:
using System; using System.IO; using System.Reflection; public class TrackedTestBase : IDisposable { private static readonly object _logLock = new object(); private readonly string _currentTestName; public TrackedTestBase() { var method = MethodBase.GetCurrentMethod()?.DeclaringType?.GetMethod( MethodBase.GetCurrentMethod()?.Name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); _currentTestName = $"{method?.DeclaringType?.FullName}.{method?.Name}"; lock (_logLock) { File.AppendAllText("test_execution.log", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} - START: {_currentTestName}\n"); } } public void Dispose() { lock (_logLock) { File.AppendAllText("test_execution.log", $"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} - END: {_currentTestName}\n"); } } }
之后让所有测试类继承TrackedTestBase即可,运行测试后打开test_execution.log就能看到完整的执行顺序。
3. 自定义XUnit测试监听器(零测试代码修改)
实现XUnit的ITestExecutionListener接口,注册后自动监听测试启动事件,记录每个测试的前置测试:
步骤1:实现监听器类
using System; using System.IO; using Xunit.Abstractions; using Xunit.Sdk; namespace YourTestProjectNamespace { public class TestSequenceListener : ITestExecutionListener { private static readonly object _lock = new object(); private static string _lastExecutedTest; public void TestStarting(ITest test) { var currentTest = $"{test.TestCase.TestMethod.Method.TypeName}.{test.TestCase.TestMethod.Method.Name}"; lock (_lock) { var logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] Previous: {_lastExecutedTest ?? "None"} | Current: {currentTest}"; Console.WriteLine(logEntry); File.AppendAllText("test_sequence.log", logEntry + "\n"); _lastExecutedTest = currentTest; } } // 以下接口方法留空实现即可 public void TestFinished(ITest test, ITestResult result) { } public void TestFailed(ITest test, ITestResult result) { } public void TestSkipped(ITest test, string reason) { } } }
步骤2:配置监听器
修改项目中的xunit.runner.json(如果没有则新建),添加监听器配置:
{ "parallelizeTestCollections": false, "listeners": [ { "typeName": "YourTestProjectNamespace.TestSequenceListener, YourTestProjectAssemblyName" } ] }
替换YourTestProjectNamespace和YourTestProjectAssemblyName为实际的命名空间和程序集名称。运行测试后,test_sequence.log中会直接显示每个测试的上一个执行测试。
内容的提问来源于stack exchange,提问作者William Jockusch
相关产品推荐
相关产品推荐

