C#如何通过函数在控制台应用中触发执行所有xUnit单元测试
实现方案
可以直接在代码中托管xUnit官方的运行引擎,不需要依赖外部命令行工具,就能在控制台程序内执行所有xUnit测试并输出结果,具体实现步骤如下:
1. 安装依赖NuGet包
给你的控制台项目安装以下包:
xunit:xUnit核心框架xunit.runner.utility:xUnit官方提供的可编程执行接口,支持在自定义代码中调用测试运行逻辑
测试类既可以直接写在控制台项目中,也可以写在同解决方案的独立测试项目中,只要控制台项目能引用到测试类所在的程序集即可。
2. 编写自定义测试执行函数
添加以下命名空间引用:
using System.Reflection; using Xunit.Runners;
核心执行代码如下,会自动统计测试结果、打印用例执行状态和失败详情:
static void RunAllXunitTests() { // 加载包含测试用例的程序集,如果测试在独立项目,替换为对应程序集的加载逻辑即可 Assembly testAssembly = Assembly.GetExecutingAssembly(); string assemblyPath = testAssembly.Location; // 初始化xUnit程序集运行器 using AssemblyRunner runner = new AssemblyRunner( useAppDomain: false, // .NET Core/.NET 5+ 不支持AppDomain,必须设为false assemblyFileName: assemblyPath, configFileName: null, shadowCopy: false); int total = 0, passed = 0, failed = 0; List<string> failedDetails = new List<string>(); // 单个测试执行完成的回调 runner.OnTestCompleted = info => { total++; if (info.Success) { passed++; Console.WriteLine($"[通过] {info.TestDisplayName} 耗时: {info.ExecutionTime}ms"); } else { failed++; failedDetails.Add($"[失败] {info.TestDisplayName}\n错误信息: {info.ExceptionMessage}\n堆栈: {info.ExceptionStackTrace}"); } }; // 所有测试执行完成的汇总回调 runner.OnTestAssemblyCompleted = summary => { Console.WriteLine("\n================ 测试结果汇总 ================"); Console.WriteLine($"总用例数: {total} 通过: {passed} 失败: {failed} 总耗时: {summary.ExecutionTime}ms"); if (failed > 0) { Console.WriteLine("\n================ 失败用例详情 ================"); foreach (string item in failedDetails) { Console.WriteLine(item); Console.WriteLine("--------------------------------------------"); } } }; Console.WriteLine("开始执行所有单元测试...\n"); runner.Start(); runner.WaitForCompletion(Timeout.Infinite); }
3. 集成到现有菜单逻辑
直接在switch分支中调用上面的函数即可,参考代码:
while (true) { Console.WriteLine("\n===== 功能菜单 ====="); Console.WriteLine("1. 执行某项操作"); Console.WriteLine("2. 执行其他不同操作"); Console.WriteLine("3. 运行单元测试"); Console.WriteLine("0. 退出"); Console.Write("请输入选项:"); string choice = Console.ReadLine()?.Trim(); switch (choice) { case "1": // 原有业务逻辑1 DoFirstOperation(); break; case "2": // 原有业务逻辑2 DoSecondOperation(); break; case "3": RunAllXunitTests(); break; case "0": return; default: Console.WriteLine("无效输入,请重新选择"); break; } }
注意事项
- 如果测试用例存放在独立的测试项目,将
Assembly.GetExecutingAssembly()替换为Assembly.LoadFrom("测试项目dll的完整路径")即可,需要提前给控制台项目添加对测试项目的引用,避免程序集加载失败。 - 不要通过启动外部进程调用
dotnet test的方式实现,该方案要求运行程序的机器必须安装对应版本的.NET SDK,内嵌运行器的方案只需要对应版本的.NET运行时即可,部署兼容性更好。 - 发布单文件可执行程序时,需要在发布配置中开启包含所有依赖的选项,避免xUnit相关依赖缺失导致运行失败。
- 如果需要按分类、类名等规则过滤测试用例,可以在
runner.Start()前传入对应的过滤参数,xUnit原生支持Trait、名称匹配等过滤规则。
内容的提问来源于stack exchange,提问作者The Robcio
相关产品推荐
相关产品推荐

