如何在运行MSTest测试时向Console.Out输出内容

133

背景:
我们的Web应用程序中有一些用户报告了文件上传功能的问题。这种情况只是偶尔发生,并没有特定的规律。我们一直在尝试找出问题所在,添加调试信息,查看日志等,但一直无法重现或弄清楚原因。

问题:
我现在正在使用MSTest和WatiN尝试复制这个问题,重复执行可能会失败的操作多次(几百次)。只是为了了解测试已经进行到循环的哪个阶段,我想打印类似于以下内容:

Console.WriteLine(String.Format("Uploaded file, attempt {0} of {1}", i, maxUploads));

然而,这在输出窗口中并不显示。我知道测试结果将会包括控制台输出(以及通过Debug.Writeline等输出的内容),但是这些输出在测试完成之前是不可用的。由于我的测试要进行数百次重复可能需要相当长的时间,所以我想知道它执行到了哪个阶段。

问题:
在测试执行期间,有没有一种方法可以在输出窗口中获取控制台输出?


如果你正在寻找一种打印测试结果输出的方法: https://dev59.com/q2445IYBdhLWcg3wl7XW#4787047 - Risadinha
6个回答

121
控制台输出未显示的原因是后端代码没有在测试上下文中运行。
最好使用Trace.WriteLine(在System.Diagnostics中),然后添加一个将跟踪侦听器写入文件的跟踪侦听器。 这个MSDN主题展示了一种实现方式。

根据Marty Neal和Dave Anderson的评论:

using System;
using System.Diagnostics;

...

Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
// or Trace.Listeners.Add(new ConsoleTraceListener());
Trace.WriteLine("Hello World");

74
基本上,以下代码会将"Hello World"输出到控制台,并将其记录在跟踪侦听器中:Trace.Listeners.Add(new TextWriterTraceListener(Console.Out)); Trace.WriteLine("Hello World"); - Marty Neal
7
嗯,我发现@Martin Neal的建议会将Trace.WriteLine()Console.WriteLine()输出发送到测试结果视图,而不是输出视图。 (请注意,在测试结果视图中,可能需要通过右键单击并选择添加/删除列...来添加输出(Stdout)列。)但是,也许我仍然没有在输出视图中看到输出意味着我漏掉了什么...... - DavidRR
3
使用 Trace.Listeners.Add(new ConsoleTraceListener()); 就足够了,然后在输出窗口中显示来自 Debug 的输出。 - Dave Anderson
3
我很难在VS2017中找到输出结果...测试资源管理器窗口 -> 单击单个测试 -> 如果测试有输出结果,在详细信息窗口中的经过时间下方会有一个名为"output"的链接,点击它会弹出一个新窗口。 - Mike Walsh
3
如果您正在使用Xunit,只需通过ctor将ITestOutputHelper传入并在其上调用WriteLine即可。在集成测试期间编写内容花了一些时间,希望这能帮助到某些人。 - Alexander Høst
显示剩余7条评论

85

使用Debug.WriteLine。这将立即在Output窗口中显示您的消息。唯一的限制是您必须在Debug模式下运行测试。

[TestMethod]
public void TestMethod1()
{
    Debug.WriteLine("Time {0}", DateTime.Now);
    System.Threading.Thread.Sleep(30000);
    Debug.WriteLine("Time {0}", DateTime.Now);
}

输出

输入图像描述


9
需要使用 System.Diagnostics 命名空间。 - kmote
7
不要使用DateTime.Now,最好使用Stopwatch(http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx)。 - suizo
2
我无法让它正常工作。当我运行测试时,输出窗口立即切换到构建,并且没有发送任何内容到调试。你有什么想法? - InteXX
7
请确保点击“调试测试”而不是“运行测试”,这对我有效。 - John Henckel
如果您运行 dotnet test -l "console;verbosity=detailed",则可以将其输出到测试输出中。https://github.com/microsoft/vstest/issues/799#issuecomment-1003819952 - Tamás Kovács
显示剩余2条评论

16

我找到了自己的解决方案。我知道Andras的答案可能是与MSTEST最一致的,但我不想重构我的代码。

[TestMethod]
public void OneIsOne()
{
    using (ConsoleRedirector cr = new ConsoleRedirector())
    {
        Assert.IsFalse(cr.ToString().Contains("New text"));
        /* call some method that writes "New text" to stdout */
        Assert.IsTrue(cr.ToString().Contains("New text"));
    }
}

ConsoleRedirector是一种可丢弃的类,定义如下:

internal class ConsoleRedirector : IDisposable
{
    private StringWriter _consoleOutput = new StringWriter();
    private TextWriter _originalConsoleOutput;
    public ConsoleRedirector()
    {
        this._originalConsoleOutput = Console.Out;
        Console.SetOut(_consoleOutput);
    }
    public void Dispose()
    {
        Console.SetOut(_originalConsoleOutput);
        Console.Write(this.ToString());
        this._consoleOutput.Dispose();
    }
    public override string ToString()
    {
        return this._consoleOutput.ToString();
    }
}

6

我曾经也遇到过同样的问题,当时我在“运行”测试。如果我改为使用“调试”测试时,就可以像所有其他的 Trace 和 Console 一样正常显示调试信息。 但我不确定如果你“运行”测试的话,如何查看输出结果。


1
我可以使用 System.Diagnostics.Debug.WriteLine 在调试测试时显示一些内容,但是如何让 Console.WriteLine 正常工作呢?这对我来说不会出现在正常(实时更新)的输出中。 - O. R. Mapper
你有找到在运行测试时查看输出的方法吗? - hima

4
这不是控制台,而是在输出面板中。
public class Test
{
 public TestContext TestContext { get; set; }

 [TestMethod]
 public void Foo()
 {
   TestContext.WriteLine("Hello World");
 }
}

-3

更新: 负载测试功能已经弃用

--- 原始回答
你最好设置一个单一的测试,并从这个测试创建一个性能测试。这样,你可以使用默认工具集监视进度。


这样你就可以使用默认工具集来监控进度。问题在于一旦测试运行,它就是一个黑盒子,我只能在测试完成后在输出窗口中看到输出(我在测试运行时逐渐编写)。 - O. R. Mapper
https://www.visualstudio.com/en-us/docs/test/performance-testing/run-performance-tests-app-before-release#create-a-load-test - riezebosch

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