我可以在单元测试中写入控制台吗?如果是,为什么控制台窗口没有打开?


148

我在Visual Studio中有一个测试项目。我使用Microsoft.VisualStudio.TestTools.UnitTesting。

我在我的一个单元测试中添加了这一行:

Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();

当我运行测试时,测试通过了,但控制台窗口根本没有打开。

有没有一种方法可以使控制台窗口可通过单元测试进行交互?


1
这真的取决于跑步者。您可以使用TestDriven.Net(一个很棒的,免费的供个人使用的测试运行程序)-Console.WriteLine将写入VS输出窗格。
2012年

1
感谢您在TestDriven.Net上传播信息
GrayFox374

NCrunch也具有此功能,仅此一项就值得IMO付出代价。我有一个Dump扩展方法,可以将对象的内容输出到控制台中,从而使调试变得非常容易。i.imgur.com/MEZwy7X.png
DharmaTurtle

Answers:


125

注意:以下原始答案应适用于VS2012之前的任何版本的VS。VS2013似乎不再具有“测试结果”窗口。相反,如果您需要特定于测试的输出,则可以使用@Stretch的建议Trace.Write()将输出写入“输出”窗口。


Console.Write方法不会写到“控制台”上,而是写到正在运行的进程的标准输出句柄上。同样,Console.Read从连接到标准输入的任何内容读取输入。

当您通过VS2010运行单元测试时,标准线束将由测试线束重定向并存储为测试输出的一部分。您可以通过右键单击“测试结果”窗口并在显示中添加名为“输出(StdOut)”的列来查看。这将显示任何写入标准输出的内容。

可以按照@ sinni800的说明使用P / Invoke手动打开控制台窗口。通过阅读AllocConsole文档,似乎该功能将重置stdin并进行stdout处理以指向新的控制台窗口。(我对此不是100%的确定;如果我已经重定向stdout到Windows以从我那里窃取它,但对我来说似乎有点不对劲,但是我没有尝试过。)

总的来说,我认为这是一个坏主意。如果您要使用控制台的全部目的是转储有关单元测试的更多信息,那么输出就在那里。保持原样Console.WriteLine,并在“测试结果”窗口中检查输出结果。


尝试打开一个新的WindowsApplication,使用AllocConsole分配一个控制台,它将在此处编写。我不知道它的真正作用,但可能无法在单元测试环境中使用。知道这真的很高兴...
sinni800 2012年

人力资源部 重新阅读AllocConsole文档,我可能不正确,但是我必须对其进行测试。
Michael Edenfield 2012年

2
对我来说,迈克尔的这段话说了我需要考虑的一切:“当您通过VS2010运行单元测试时,标准输出将由测试工具重定向并存储为测试输出的一部分。”
罗伯特·帕特森

5
在VS2013中,如果您在控制台上进行写操作,则TestExplorer / Test / Summary上将有一个[Output]链接标签。单击它,您将获得所需的输出。等待?您还想调用Console.ReadLine()吗?
Visar '16

3
在V2017(社区)中,转到“测试资源管理器”,在列表中选择测试结果项,然后在另一个窗口(测试结果窗口?)上单击“输出”链接。由于它可能会被截断,因此请使用“全部复制”并越过其他地方。
heringer

180

有人评论了VS2013中的这一显然新功能。我一开始不确定他的意思,但是现在我知道了,我认为这应该是自己的答案。

我们可以正常使用Console.WriteLine并显示输出,只是不在“输出”窗口中显示,而是在测试详细信息中单击“输出”后在新窗口中显示。

在此处输入图片说明


2
优秀的解决方案。确认它可以在VS2015 Enterprise中使用。
garfbradaz

6
不幸的是,您无法在该输出区域中选择任何文本进行复制和粘贴:(他们在想什么?!
或Mapper

3
@ORMapper,右键单击“标准输出”区域,然后选择全部复制
bychance

2
@ Ovi-WanKenobi尝试使用Console.Write输出某些内容
Tiago Duarte

5
在vs 2017中,您必须选择要运行的EACH测试,然后单击输出-在进行大量测试时不是很有用。我想一起查看所有输出-不在单独的窗口中。
inliner49er

37

您可以使用以下行来写入Visual Studio的“ 输出窗口 ”:

System.Diagnostics.Debug.WriteLine("Matrix has you...");

必须在调试模式下运行。


7
它没有写在我的VS上
Luis Filipe


1
使用MSTest和R#查看输出对我来说非常有用。谢谢!
艾萨克·贝克

2
@William如果您调试测试,则会显示它,但如果您不调试而直接运行它,则不会显示。
yoyo

29

如上所述,单元测试被设计为无需交互即可运行。

但是,您可以像其他任何代码一样调试单元测试。最简单的方法是使用“测试结果”选项卡中的“调试”按钮。

能够进行调试意味着能够使用断点。因此,能够使用断点意味着能够使用Tracepoints,我发现它在日常调试中非常有用。

本质上,Tracepoints允许您写入“输出”窗口(或更准确地说,写入标准输出)。(可选)您可以继续运行,也可以像常规断点一样停止。这为您提供了您所需要的“功能”,而无需重新构建代码或在其中添加调试信息。

只需添加一个断点,然后在该断点上单击鼠标右键。选择“击中时...”选项: 当命中选项

弹出对话框: 当断点被击中

注意事项:

  1. 请注意,断点现在显示为菱形,而不是球形,表示跟踪点
  2. 您可以通过像{this}一样将变量括起来来输出变量的值。
  3. 取消选中“继续执行”复选框以使代码在此行中断,就像任何常规断点一样
  4. 您可以选择运行宏。请小心-可能导致有害的副作用。

有关更多详细信息,请参见文档。


24

有几种方法可以用C#编写来自Visual Studio单元测试的输出:

  • Console.Write-当您在“测试资源管理器”中选择测试并单击“输出”链接时,Visual Studio测试工具将捕获并显示它。在运行或调试单元测试时,它不会显示在Visual Studio输出窗口中(可以说这是一个错误)。
  • Debug.Write-Visual Studio测试工具将捕获此内容并将其显示在测试输出中。是否调试单元测试时,除非Visual Studio中的调试选项被配置为输出重定向到即时窗口出现在Visual Studio输出窗口。如果仅运行测试而不进行调试,则“输出(或立即)”窗口中将不会显示任何内容。默认情况下,仅在Debug版本中可用(即,定义DEBUG常量时)。
  • Trace.Write-Visual Studio测试工具将捕获它并将其显示在测试输出中。在调试单元测试时,会出现在Visual Studio输出(或立即)窗口中(但在没有调试的情况下简单地运行测试时,不会出现)。默认情况下,“调试”和“发布”版本中均可用(即,定义了TRACE常量时)。

在Visual Studio 2013专业版中确认。


1
请注意,如果您将NUnit和NUnit测试适配器扩展用于Visual Studio,而不是内置的Microsoft测试框架,则规则会稍有不同。
yoyo

9

您可以使用

Trace.WriteLine() 

在调试单元测试时写入“输出”窗口。


5

在Visual Studio 2017中,“ TestContext”不显示“输出到测试资源管理器”的链接。但是,Trace.Writeline()显示了Ouput链接。


仅供参考,其Trace.WriteLine
TroySteven

4

首先,根据设计,单元测试应该完全运行而无需交互。

除此之外,我认为没有想到这种可能性。

您可以尝试使用AllocConsole P / Invoke进行黑客入侵,即使您当前的应用程序是GUI应用程序,它也会打开控制台。Console然后,该课程将发布到现在打开的控制台。


1
嗯..我的主要动机是向控制台写入一些额外的数据,以查看更深入的细节。这将是我以后可能不需要的特别东西。
penCakeCake 2012年


2

在大多数情况下,IMHO输出消息仅与失败的测试用例相关。我编造了以下格式,您也可以自己制作。这显示在VS Test Explorer窗口本身中。

如何在VS Test Explorer窗口中抛出此消息?这样的示例代码应该可以工作。

if(test_condition_fails)
    Assert.Fail(@"Test Type: Positive/Negative.
                Mock Properties: someclass.propertyOne: True
                someclass.propertyTwo: True
                Test Properties: someclass.testPropertyOne: True
                someclass.testPropertyOne: False
                Reason for Failure: The Mail was not sent on Success Task completion.");

您可以为自己准备一个单独的课程。希望能帮助到你!


我把它也加进去了。在使用XUNIT的Visual Studio 2019中,您可以执行以下操作:Assert.True(成功,“ DELETE RECORD FAILED”);删除记录失败然后将显示在VS 2019 Test Explorer中。再次,像上面的答案一样,这仅在您的单元测试未达到预期条件时有效。
TroySteven

1

我有一个更简单的解决方案(出于种种懒惰原因,我最近使用了自己)。将此方法添加到您正在使用的类中:

public static void DumbDebug(string message)
    {
        File.WriteAllText(@"C:\AdHocConsole\" + message + ".txt", "this is really dumb, I wish microsoft had more obvious solutions to it's solutions' problems.");
    }

然后...打开目录AdHocConsole,按创建时间排序。确保在添加“打印声明”时它们是不同的,否则会很杂乱。


0

适用于Mac的Visual Studio

其他解决方案均无法在Mac上的VS上运行

如果您使用的是NUnit,则可以在解决方案中添加一个小型.NET 控制台项目,然后在该新控制台项目参考中引用要测试的项目

您在[Test()]方法中所做的任何操作都可以通过以下Main方式在控制台应用程序中完成:

class MainClass
{
    public static void Main(string[] args)
    {
        Console.WriteLine("Console");

        // Reproduce the Unit Test
        var classToTest = new ClassToTest();
        var expected = 42;
        var actual = classToTest.MeaningOfLife();
        Console.WriteLine($"Pass: {expected.Equals(actual)}, expected={expected}, actual={actual}");
    }
}

您可以自由使用Console.Write,并Console.WriteLine在这些情况下你的代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.