【问题标题】:How can I write output from a unit test?如何编写单元测试的输出?
【发布时间】:2011-06-14 18:51:56
【问题描述】:

在我的单元测试中对Debug.Write(line)Console.Write(Line) 的任何调用都会在调试时被跳过,并且永远不会打印输出。从我正在使用的类中调用这些函数可以正常工作。

我了解单元测试旨在实现自动化,但我仍然希望能够从单元测试中输出消息。

【问题讨论】:

    标签: c# visual-studio unit-testing debugging mstest


    【解决方案1】:

    我还试图让 Debug 或 Trace 或 Console 或 TestContext 在单元测试中工作。

    这些方法似乎都不起作用或在输出窗口中显示输出:

        Trace.WriteLine("test trace");
        Debug.WriteLine("test debug");
        TestContext.WriteLine("test context");
        Console.WriteLine("test console");
    

    Visual Studio 2012 及更高版本

    (来自 cmets) 在 Visual Studio 2012 中,没有图标。相反,测试结果中有一个名为 Output 的链接。如果你点击链接,你会看到所有的WriteLine

    Visual Studio 2012 之前的版本

    然后我注意到在我的测试结果窗口中,运行测试后,在小成功绿色圆圈旁边,还有另一个图标。我双击它。这是我的测试结果,它包含了上面所有类型的 writelines。

    【讨论】:

    • 在 Visual Studio 2012 中,没有图标。相反,测试结果中有一个名为“输出”的链接。如果你点击链接,你会看到所有的写行。
    • 天啊,“输出”链接本质上很难找到。如果有人在努力寻找它,它在文本资源管理器的底部。选择测试后,它会以“经过的时间:xxx”显示结果。下面是“输出”链接。
    • 如果有人想知道(像我一样)其中哪些出现在 TRX(测试结果输出)文件中,那么除了“Debug.WriteLine”之外,以上都是。
    • 在 Visual Studio 2017 中,它仍然是“输出”链接。
    • VS2022中不再有输出链接
    【解决方案2】:

    尝试使用在测试结果中输出文本的TestContext.WriteLine()

    例子:

    [TestClass]
    public class UnitTest1
    {
        private TestContext testContextInstance;
    
        /// <summary>
        /// Gets or sets the test context which provides
        /// information about and functionality for the current test run.
        /// </summary>
        public TestContext TestContext
        {
            get { return testContextInstance; }
            set { testContextInstance = value; }
        }
    
        [TestMethod]
        public void TestMethod1()
        {
            TestContext.WriteLine("Message...");
        }
    }
    

    “魔法”在MSDN中描述:

    要使用 TestContext,请在您的测试类中创建一个成员和属性 [...] 测试框架会自动设置该属性,然后您可以在单元测试中使用该属性。

    【讨论】:

    • 我发现(使用 VS2013)只有在调试模式下运行测试时才会打印一些东西。
    • 看来使用TestContext需要VS2015 Enterprise(或早期版本的高级版),根据this documentation
    • 我注意到如果你的字符串中有花括号,这个方法就会失败。所以 "_testContext.WriteLine("hello");"有效,但“_testContext.WriteLine("he{ll}o");"失败并显示“System.FormatException:输入字符串的格式不正确。”
    • TestContext 中的 WriteLine 方法采用与 Console.WriteWriteLine 相同的参数。这意味着该字符串是一个格式化字符串(记录在docs.microsoft.com/en-us/dotnet/standard/base-types/…)。要在字符串中使用文字 {,您需要将其加倍。要打印您的字符串,请使用 WriteLine("he{{ll}}o");
    • 这很有趣......虽然我仍然不知道他们为什么不将这个和类似的功能添加到我们可以从框架中使用的基类或接口中以避免混淆。
    【解决方案3】:

    在 Visual Studio 2017 中,您可以看到测试资源管理器的输出。

    1) 在您的测试方法中,Console.WriteLine("something");

    2) 运行测试。

    3) 在测试资源管理器窗口中,单击通过的测试方法。

    4) 然后点击“输出”链接。

    然后点击“输出”,可以看到 Console.Writeline() 的结果。

    【讨论】:

    • 优秀。 Visual Studio/C# 不是我的开发规范,这只是我需要的!感谢您发布此内容。
    • 我使用的是 2017 版本 15.5.6 位 O 看不到输出链接。
    • 是否取决于使用的测试框架?我在 .NET 4.6 测试项目中使用 xUnit 2.4 并且没有出现“标准输出”窗格。 Console.WriteLine 的输出在“测试”下的“输出”窗格中也不可见。
    • 对于 xUnit,jonzim 的回答对我有用,即使在测试产生的不同线程中也是如此。
    • 对于那些没有看到“输出”链接的人。 1) 你应该选择一个测试方法。 2)让Test Explorer窗口垂直填充VS窗口,否则链接被隐藏并且滚动条太小而无法注意到或使用。
    【解决方案4】:

    这取决于您的测试运行程序...例如,我使用的是 xUnit,所以如果您使用的是这种方式,请按照以下说明操作:

    https://xunit.net/docs/capturing-output

    此方法将您的输出与每个特定的单元测试分组。

    using Xunit;
    using Xunit.Abstractions;
    
    public class MyTestClass
    {
        private readonly ITestOutputHelper output;
    
        public MyTestClass(ITestOutputHelper output)
        {
            this.output = output;
        }
    
        [Fact]
        public void MyTest()
        {
            var temp = "my class!";
            output.WriteLine("This is output from {0}", temp);
        }
    }
    

    在我提供的用于写入输出窗口的链接中列出了另一种方法,但我更喜欢前一种。

    【讨论】:

      【解决方案5】:

      VS 2019

      1. 在 VS 主菜单栏中单击:View -> Test Explorer
      2. 在测试资源管理器中右键单击您的测试方法 -> 调试
      3. 点击下面的屏幕截图中的additional output 链接。

      你可以使用:

      • Debug.WriteLine
      • Console.WriteLine
      • TestContext.WriteLine

      all 将记录到额外的输出窗口。

      【讨论】:

      【解决方案6】:

      我认为它仍然是真实的。

      你可以使用这个 NuGet 包:Bitoxygen.Testing.Pane

      从此库中调用自定义 WriteLine 方法。 它在 Output 窗口内创建一个测试窗格,并始终将消息放在那里(在每个测试期间,它独立于 DEBUG 和 TRACE 标志运行)。

      为了使跟踪更容易,我建议创建一个基类:

      [TestClass]
      public abstract class BaseTest
      {
          #region Properties
          public TestContext TestContext { get; set; }
      
          public string Class
          {
              get { return this.TestContext.FullyQualifiedTestClassName; }
          }
          public string Method
          {
              get { return this.TestContext.TestName; }
          }
          #endregion
      
          #region Methods
          protected virtual void Trace(string message)
          {
              System.Diagnostics.Trace.WriteLine(message);
      
              Output.Testing.Trace.WriteLine(message);
          }
          #endregion
      }
      
      [TestClass]
      public class SomeTest : BaseTest
      {
          [TestMethod]
          public void SomeTest1()
          {
              this.Trace(string.Format("Yeah: {0} and {1}", this.Class, this.Method));
          }
      }
      

      【讨论】:

      • 神奇之处在于:Output.Testing.Trace.WriteLine(message);使用 BitOxygen。
      • 不适用于当前的 Visual Studio 版本,您会收到错误 Could not load file or assembly 'Microsoft.VisualStudio.Shell.12.0,
      • @Console 是的,它需要一些支持,但我不确定社区是否有兴趣以这种方式输出。 xUnit 有 OutputHandler 和 VS 可以显示它的结果。
      【解决方案7】:

      这确实取决于@jonzim 提到的测试运行器。 对于 NUnit 3,我必须使用 NUnit.Framework.TestContext.Progress.WriteLine() 在 Visual Studio 2017 的输出窗口中获得运行输出。

      NUnit 描述了如何:here

      据我了解,这围绕着测试运行者收到的附加测试执行并行化。

      【讨论】:

        【解决方案8】:

        尝试使用:

        Console.WriteLine()

        只有在定义 DEBUG 时才会调用Debug.WriteLine

        其他建议也可以使用:Trace.WriteLine,但我没有尝试过。

        还有一个选项(不确定 Visual Studio 2008 是否有),但是当您在 IDE 中使用 Test With Debuggeroption 运行测试时,您仍然可以使用 Debug.WriteLine

        【讨论】:

          【解决方案9】:

          用下面的例子解决:

          public void CheckConsoleOutput()
          {
              Console.WriteLine("Hello, World!");
              Trace.WriteLine("Trace Trace the World");
              Debug.WriteLine("Debug Debug World");
              Assert.IsTrue(true);
          }
          

          运行此测试后,在“测试通过”下,有查看输出的选项,这将打开输出窗口。

          【讨论】:

            【解决方案10】:

            我偶然发现DebugView(启用Capture &gt; Capture Win32 选项)会捕获对System.Console 的写入。

            示例测试:

            [Test]
            public void FooTest()
            {
                for (int i = 0; i < 5; i++)
                    Console.WriteLine($"[{DateTime.UtcNow.ToString("G")}] Hello World");
            }
            

            【讨论】:

              【解决方案11】:

              如果您使用dotnet test 运行测试,您可能会发现Console.Error.WriteLine 会产生输出。

              这就是我解决 NUnit 测试问题的方法,它似乎也抑制了所有 Debug、Trace 和标准输出。

              【讨论】:

              • 我可以确认。在Ubuntu MATE 20.04(Focal Fossa)上尝试使用 .NET Core 3.1。 System.Console.Error.WriteLine 有效,但 System.Diagnostics.Debug.WriteLine 无效。
              【解决方案12】:

              当我的测试/测试设置/默认处理器体系结构设置和我的测试项目引用的程序集不同时,我没有得到任何输出。否则 Trace.Writeline() 工作正常。

              【讨论】:

                【解决方案13】:

                您确定要在 Debug 中运行单元测试吗? Debug.WriteLine 不会在 Release 版本中被调用。

                两个可以尝试的选项是:

                • Trace.WriteLine(),内置于发布版本和调试中

                • 在单元测试的构建设置中取消定义 DEBUG

                【讨论】:

                  【解决方案14】:

                  我正在使用xUnit,所以这是我使用的:

                  Debugger.Log(0, "1", input);
                  

                  PS:你也可以使用Debugger.Break();,所以你可以在out看到你的登录。

                  【讨论】:

                  • 这是什么“out”?
                  【解决方案15】:

                  原因/解决方案的不同变体:

                  我的问题是我没有得到输出,因为我正在异步上下文中的循环中将异步 LINQ 调用的结果集写入控制台:

                  var p = _context.Payment.Where(pp => pp.applicationNumber.Trim() == "12345");
                  
                  p.ForEachAsync(payment => Console.WriteLine(payment.Amount));
                  

                  因此,在运行时清理控制台对象之前,测试并未写入控制台(仅运行一个测试时)。

                  解决方法是先将结果集转换为列表,这样我就可以使用非异步版本的forEach():

                  var p = _context.Payment.Where(pp => pp.applicationNumber.Trim() == "12345").ToList();
                  
                  p.ForEachAsync(payment =>Console.WriteLine(payment.Amount));
                  

                  【讨论】:

                    【解决方案16】:

                    Console.WriteLine 不起作用。在调试模式下,只有 Debug.WriteLine()Trace.WriteLine() 可以工作。

                    我执行以下操作:在测试模块中包含 using System.Diagnostics。然后,使用 Debug.WriteLine 作为我的输出,右键单击测试,然后选择 Debug Selected Tests。结果输出现在将出现在下面的 Output 窗口中。我使用 Visual Studio 2017 版本 15.8.1,以及 Visual Studio 提供的默认单元测试框架。

                    【讨论】:

                      【解决方案17】:

                      Trace.WriteLine 应该可以工作,只要您选择正确的输出(在 Output 窗口中找到标有“显示输出”的下拉菜单)。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2012-02-03
                        • 2019-01-28
                        • 2011-03-16
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多