XUnit测试C#自定义MSBuild任务时如何捕获构建输出日志
解决方案
实现思路
MSBuild自带的ConsoleLogger会直接输出到系统标准控制台,而xUnit会拦截默认控制台输出,只有通过ITestOutputHelper写入的内容才会展示在测试控制台中,所以你需要自定义实现一个MSBuild ILogger,将构建日志转发到ITestOutputHelper。
步骤1:自定义MSBuild日志器
using Microsoft.Build.Framework; using Xunit.Abstractions; public class XUnitMsBuildLogger : ILogger { private readonly ITestOutputHelper _outputHelper; public LoggerVerbosity Verbosity { get; set; } = LoggerVerbosity.Normal; public string Parameters { get; set; } public XUnitMsBuildLogger(ITestOutputHelper outputHelper) { _outputHelper = outputHelper; } public void Initialize(IEventSource eventSource) { // 注册需要监听的构建事件 eventSource.MessageRaised += OnMessageRaised; eventSource.WarningRaised += OnWarningRaised; eventSource.ErrorRaised += OnErrorRaised; } private void OnMessageRaised(object sender, BuildMessageEventArgs e) { // 可根据Verbosity调整过滤阈值 if (e.Importance <= MessageImportance.Normal) { _outputHelper.WriteLine($"[MSG] {e.Message}"); } } private void OnWarningRaised(object sender, BuildWarningEventArgs e) => _outputHelper.WriteLine($"[WARN] 行{e.LineNumber} 列{e.ColumnNumber}:{e.Message}"); private void OnErrorRaised(object sender, BuildErrorEventArgs e) => _outputHelper.WriteLine($"[ERROR] 行{e.LineNumber} 列{e.ColumnNumber}:{e.Message}"); public void Shutdown() { // 此处可按需解绑事件避免内存泄漏 } }
步骤2:修改测试代码注入日志器
xUnit会通过测试类的构造函数注入ITestOutputHelper,直接替换原来的ConsoleLogger即可:
using Xunit; using Xunit.Abstractions; using Microsoft.Build.Evaluation; using Microsoft.Build.Framework; public class MsBuildTaskTest { private readonly ITestOutputHelper _outputHelper; // 构造函数注入ITestOutputHelper public MsBuildTaskTest(ITestOutputHelper outputHelper) { _outputHelper = outputHelper; } [Fact] public void TestFullProjectBuild() { // 用自定义的XUnitMsBuildLogger代替默认ConsoleLogger List<ILogger> loggers = new() {new XUnitMsBuildLogger(_outputHelper)}; var projectCollection = new ProjectCollection(); projectCollection.RegisterLoggers(loggers); string fixtureDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "fixtures"); string projPath = Path.Combine(fixtureDir, "TestProject.csproj.xml"); var project = projectCollection.LoadProject(projPath); var ok = project.Build(); projectCollection.UnregisterAllLoggers(); Assert.True(ok); } }
可选配置
如果需要调整日志输出详细程度,可以在初始化XUnitMsBuildLogger时修改Verbosity属性,同时调整消息过滤的MessageImportance阈值即可。
内容的提问来源于stack exchange,提问作者Vikash Balasubramanian
相关产品推荐
相关产品推荐

