You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:03:50