【问题标题】:Why does NUnit not show console output from background threads?为什么 NUnit 不显示后台线程的控制台输出?
【发布时间】:2017-10-27 11:00:46
【问题描述】:

我的库有一些后台线程,可以将调试输出打印到 Console.WriteLine()。在第一个测试中,我可以在测试输出中看到来自后台线程的调试行。但接下来的测试不再显示此输出。

如果我在测试方法本身中调用 Console.WriteLine(),那么这将在测试输出中看到。我已经调试了它和测试调用

  • 测试中的第一个 Console.WriteLine()
  • 然后在后台测试中调用 Console.WriteLine()
  • 最后在测试中再次调用Console.WriteLine()。

但我只直接看到测试的输出,而不是后台线程的输出。

看起来 NUnit 已将捕获的范围保存在线程上下文中。

如何从所有后台线程获取控制台输出?

【问题讨论】:

  • 也许你应该打开一个关于 NUnit 的问题?无意冒犯,但我怀疑其他人会有答案。
  • TestContext.WriteLine() 有效吗?
  • @RobProuse 该库无权访问 NUnit API。
  • @RobProuse 感谢 TestContext 的提示。
  • @Horcrux7 如果你能想出一个最小的重现,请提出问题。我们应该为整个调用上下文捕获控制台输出。

标签: c# multithreading console nunit


【解决方案1】:

由于我们的库有重定向日志输出的选项,我们可以在测试中执行以下操作:

    [SetUp]
    public void FixtureSetUp()
    {
        MyLibrary.Console = TestContext.Out;
    }

这不是一个好的解决方案。

【讨论】:

  • 经过 100 次其他东西的试验后,唯一对我有用的东西。
【解决方案2】:

这取决于您使用的 NUnit 框架的特定运行时构建。与文本捕获有关的信息保存在 NUnit 的 TestExecutionContext 中,在不同的构建中存储方式不同。

对于所有桌面版本(.NET 2.0、3.5、4.0 和 4.5),当前的 TestExecutionContext 保留在 CallContext 中。由于TestExecutionClass 实现了ILogicalThreadAffinative,因此在创建新线程时上下文会跟随测试。

对于我们的两个 .NET Standard 版本(1.3 和 1.6),上下文保存在线程本地存储中,因此不会跟随新线程的创建。这是我们希望在构建 .NET Standard 2.0 时克服的限制。

【讨论】:

  • 你的意思是答案?这是完成的事情吗?我在其他地方的方法是让旧答案保持不变,无论正确还是错误,因为它们是……历史的。 :-)
【解决方案3】:

我发现的一种解决方法是使用 NUnitLiteRunner 并拥有自己的 Main 方法,如下所示:

public class Program
{
    public static TextWriter ConsoleOut { get; private set; }
    public static int Main(string[] args)
    {
        ConsoleOut = Console.Out;
        return new AutoRun().Execute(args);
    }
}

然后在一些全局的TestSetupFixture中可以恢复Console.Out

[OneTimeSetUp]
public async Task BeforeAll()
{
    // ignore nunit's console capture
    Console.SetOut(Program.ConsoleOut);
}

这样您将在最终报告中丢失测试输出,但您可以恢复控制台。 您还可以有一个自定义的TextWriter 实现,它可以写入原始Console.Out 和由NUnit 替换的那个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-05
    • 1970-01-01
    • 2014-09-06
    相关资源
    最近更新 更多