如何通过C#代码直接生成.trx单元测试结果文件?
直接用C#代码生成VSTest .trx测试结果文件
绝对可以!你不需要通过启动cmd.exe的间接方式,直接用C#调用Visual Studio测试平台的官方API就能生成.trx测试结果文件,这样不仅更高效,还能获得更好的可控性。
先看一下你当前通过cmd调用的实现:
System.Diagnostics.Process process = new System.Diagnostics.Process(); System.Diagnostics.ProcessStartInfo myStartInfo = new System.Diagnostics.ProcessStartInfo(); myStartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; myStartInfo.UseShellExecute = false; myStartInfo.FileName = "cmd.exe"; myStartInfo.Verb = "runas"; myStartInfo.WorkingDirectory = @"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow"; myStartInfo.Arguments = @"/C VSTest.console C:\UnitTestProject1\UnitTestProject1\bin\Debug\UnitTestProject1.dll /logger:trx"; process.StartInfo = myStartInfo; process.Start();
下面提供两种更优的实现方式:
方法1:使用Microsoft.TestPlatform官方API(推荐)
这是最原生的方式,不需要依赖外部进程,直接在代码中控制测试执行和结果输出。
步骤1:安装NuGet包
首先需要安装两个核心NuGet包:
Microsoft.TestPlatform.ObjectModelMicrosoft.TestPlatform.TestHost
步骤2:实现代码
using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; class VSTestRunner { static void Main(string[] args) { // 检查是否以管理员身份运行,若没有则重启进程获取权限 if (!IsRunningAsAdministrator()) { RestartProcessAsAdmin(); return; } // 配置测试路径和结果文件路径 string testDllPath = @"C:\UnitTestProject1\UnitTestProject1\bin\Debug\UnitTestProject1.dll"; string trxOutputPath = Path.Combine(Environment.CurrentDirectory, "TestResults.trx"); // 初始化测试运行配置 var runSettings = new RunSettings(); // 配置TRX日志记录器,指定输出文件 var loggerConfig = new Dictionary<string, string> { { "LogFileName", trxOutputPath } }; runSettings.AddLogger("trx", loggerConfig); // 创建测试请求 var testRequest = new TestRunRequest(testDllPath); testRequest.RunSettings = runSettings; // 创建测试客户端并监听日志 using var testClient = new TestPlatformClient(); testClient.TestRunMessage += (sender, eventArgs) => { if (eventArgs.MessageLevel == TestMessageLevel.Error) { Console.WriteLine($"测试错误: {eventArgs.Message}"); } else if (eventArgs.MessageLevel == TestMessageLevel.Informational) { Console.WriteLine($"测试信息: {eventArgs.Message}"); } }; // 执行测试并等待完成 TestRunResult result = testClient.RunTests(testRequest); Console.WriteLine($"\n测试执行完成!结果已保存到: {trxOutputPath}"); Console.WriteLine($"总测试数: {result.TestsTotal}, 通过: {result.TestsPassed}, 失败: {result.TestsFailed}"); } // 检查当前进程是否以管理员身份运行 private static bool IsRunningAsAdministrator() { using var identity = System.Security.Principal.WindowsIdentity.GetCurrent(); var principal = new System.Security.Principal.WindowsPrincipal(identity); return principal.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator); } // 以管理员身份重启当前进程 private static void RestartProcessAsAdmin() { var startInfo = new ProcessStartInfo(Environment.ProcessPath) { Verb = "runas", Arguments = string.Join(" ", Environment.GetCommandLineArgs().Skip(1)) }; try { Process.Start(startInfo); Environment.Exit(0); } catch (System.ComponentModel.Win32Exception) { Console.WriteLine("用户拒绝了管理员权限请求,无法继续执行测试。"); Environment.Exit(1); } } }
方法2:直接调用VSTest.console.exe(无需NuGet包)
如果你不想引入额外依赖,可以直接调用VSTest.console.exe进程,跳过cmd.exe的中转,同样支持管理员权限:
using System.Diagnostics; class VSTestProcessRunner { static void Main(string[] args) { string vstestExePath = @"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe"; string testDllPath = @"C:\UnitTestProject1\UnitTestProject1\bin\Debug\UnitTestProject1.dll"; var startInfo = new ProcessStartInfo(vstestExePath) { WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = true, // 必须设为true才能使用Verb="runas"请求管理员权限 Verb = "runas", Arguments = $@"""{testDllPath}"" /logger:trx" }; try { using var process = Process.Start(startInfo); process.WaitForExit(); if (process.ExitCode == 0) { Console.WriteLine("测试执行成功,.trx文件已生成在默认的TestResults目录下"); } else { Console.WriteLine($"测试执行失败,退出代码: {process.ExitCode}"); } } catch (System.ComponentModel.Win32Exception) { Console.WriteLine("用户拒绝管理员权限,测试无法执行。"); } } }
注意:此方法中
UseShellExecute必须设为true,否则无法通过Verb="runas"获取管理员权限,这和你原来调用cmd.exe的配置不同。
两种方法对比
| 方法 | 优势 | 劣势 |
|---|---|---|
| 官方API | 实时监听测试进度、灵活配置测试参数、无外部进程依赖 | 需要引入NuGet包,代码复杂度稍高 |
| 直接调用进程 | 无需额外依赖、代码简洁 | 无法实时获取测试细节,只能等待进程结束 |
内容的提问来源于stack exchange,提问作者Ishan Verma
相关产品推荐
相关产品推荐

