使用Visual Studio测试运行器运行xUnit测试时,输出未显示在输出窗口中

4
我创建了一个新的.NET Core Class Library项目,命名为FooBarBaz。然后我使用包管理器控制台运行了以下命令:
  • Install-Package xunit xunit
  • Install-Package xunit xunit.runners.visualstudio
这是我添加的唯一代码:
using Xunit;
using Xunit.Abstractions;

namespace FooBarBaz
{
    public class Class1
    {
        private readonly ITestOutputHelper output;

        public Class1(ITestOutputHelper output)
        {
            this.output = output;
            output.WriteLine("OUTPUT FROM MY CONSTRUCTOR");
        }

        [Fact]
        public void SmokeTest()
        {
            output.WriteLine("OUTPUT FROM MY TEST");
            Assert.True(true);
        }
    }
}

这是基于 xUnit.net文档示例 的内容。我知道文档还会谈到“消息汇聚”之类的东西,但我记得在Visual Studio的输出窗口中看到该消息。但在我的真实项目中,这似乎只能偶尔起作用。
我知道我可以选择一个测试后单击“输出”超链接查看它,但那只是多了一步,而且输出也没有等宽字体(我想要有)。
请参见此内容:

Output window without output

如何配置xUnit以在“输出窗口”中提供输出?
2个回答

5
在输入问题并进行一些操作后,完全晦涩的解决方案出现了:只有失败的测试 才会在“输出”窗口中显示ITestOutputHelper 的输出结果。
尝试将断言更改为 Assert.True(false); ,你会得到这个: Output window with output 不确定为什么这是默认值,或者如何更改它。

1
如果您愿意,可以使用trace/debug.writeline将内容始终放入输出中进行跟踪/调试。默认情况下未连接的原因是,由于测试并行性,输出并不总是有用的(而且会影响性能)。 - Ruben Bartelink
感谢您的评论。然而,对于并行部分,我只能理解其中的一部分:如果在并行运行期间有1001个测试中的58个失败,那么输出也会变得混乱,不是吗? - Jeroen
(不过,性能方面的东西完全说得通。) - Jeroen
不,ITestOutputAdapter 是每次运行时传递给测试类,因此捕获的输出仅针对该运行-其是 VS shell 决定是否公开它,除非它失败(这样可以节省内存等以及屏幕空间)。 - Ruben Bartelink

1
关于ITestOutputHelper,Jeroen所写的是正确的,因此您不能用它来发送“实时”消息。但我有一个解决方法:

如果您正在进行调试并激活了“调试”模式,则可以执行以下操作:

loopCount ++;
System.Diagnostics.Debug.WriteLine($"Processing Entries ({loopCount} of {loopMax}) ...");

这将显示在“调试”窗口中(即在输出窗口中有一个下拉菜单,您需要选择“从调试显示输出”)。 它会立即出现,非常适合长时间运行的循环等。

不要担心,这些消息仅在“调试”配置中显示。 要禁用它们,请选择“发布”,它们将不再出现 - 因此轻松打开或关闭。

您还可以编写一个帮助函数,例如:

private void Print(string msg, string test = "") 
{ 
    Debug.WriteLine($"{nameof(NameOfTestClass)}{test}: {msg}"); 
    output?.WriteLine(msg); 
}

这将实时写入调试控制台,同时写入测试运行器的输出空间。

您可以在事实和理论中使用它,例如:

Print("Something happened");

或者

Print("Something happened", "-Test1");

一个完整的测试类看起来像:

using LiveOut = System.Diagnostics.Debug;
// using LiveOut = System.Console;
public class Test_Class
{

    ITestOutputHelper Output;
    public Test_Class(ITestOutputHelper _output)
    {
        Output = _output;
    }

    private void Print(string msg, string test = "") 
    {
        LiveOut.WriteLine($"{nameof(Test_Class)}{test}: {msg}");
        Output?.WriteLine(msg);
    }

    [Fact]
    void Test_Xunit()
    {
        void _print(string msg) => Print(msg, $"-{nameof(Test_Xunit)}");

        for (int i = 1; i < 100; i++)
        {
            _print(i.ToString());
            Assert.True(i > 0);
            Thread.Sleep(20);
        }
    }

}

在这种情况下,你可以选择使用两个命令之一:
using LiveOut = System.Diagnostics.Debug;

或者

using LiveOut = System.Console;

根据您的需求,输出结果将会在调试窗口或控制台窗口中显示。


请注意,您需要调试测试,以便Debug.WriteLine将写入调试输出。如果运行测试,则不会打印任何内容。 - ihebiheb
1
@ihebiheb - 是的,要使用Debug.Writeline,您必须处于Debug配置中。但是,您可以使用#if DEBUG using LiveOut = System.Diagnostics.Debug; #else using LiveOut = System.Console; #endif来解决此问题。 - Matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接