C# 我可以在单元测试中写入控制台吗?如果是,为什么控制台窗口没有打开?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11209639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I write into console in a unit test? If yes, why the console window is not opened?
提问by pencilCake
I have a test project in Visual Studio. I use Microsoft.VisualStudio.TestTools.UnitTesting.
我在 Visual Studio 中有一个测试项目。我使用 Microsoft.VisualStudio.TestTools.UnitTesting。
I add this line in one of my unit tests:
我在我的一个单元测试中添加了这一行:
Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();
When I run the test, test passes but console window is not opened at all.
当我运行测试时,测试通过但根本没有打开控制台窗口。
Is there a way to make the Console window available to be interacted via a unit test?
有没有办法让控制台窗口可以通过单元测试进行交互?
采纳答案by Michael Edenfield
NOTE: The original answer below should work for any version of VS up through VS2012. VS2013 does not appear to have a Test Results window anymore. Instead, if you need test-specific output you can use @Stretch's suggestion of Trace.Write()to write output to the Output window.
注意:下面的原始答案应该适用于 VS2012 之前的任何版本的 VS。VS2013 似乎不再有测试结果窗口。相反,如果您需要特定于测试的输出,您可以使用@Stretch 的建议Trace.Write()将输出写入输出窗口。
The Console.Writemethod does not write to the "console" -- it writes to whatever is hooked up to the standard output handle for the running process. Similarly, Console.Readreads input from whatever is hooked up to the standard input.
该Console.Write方法不写入“控制台”——它写入连接到正在运行的进程的标准输出句柄的任何内容。类似地,Console.Read从连接到标准输入的任何内容读取输入。
When you run a unit test through VS2010, standard output is redirected by the test harness and stored as part of the test output. You can see this by right-clicking the Test Results window and adding the column named "Output (StdOut)" to the display. This will show anything that was written to stdout.
当您通过 VS2010 运行单元测试时,标准输出由测试工具重定向并存储为测试输出的一部分。您可以通过右键单击“测试结果”窗口并将名为“输出 (StdOut)”的列添加到显示中来查看这一点。这将显示写入标准输出的任何内容。
You couldmanually open a console window, using P/Invoke as @sinni800 says. From reading the AllocConsoledocumentation, it appears that the function will reset stdinand stdouthandles to point to the new console window. (I'm not 100% sure about that; it seems kinda wrong to me if I've already redirected stdoutfor Windows to steal it from me, but I haven't tried.)
您可以像@sinni800 所说的那样,使用 P/Invoke 手动打开控制台窗口。从阅读AllocConsole文档来看,该函数似乎将重置stdin并stdout处理指向新的控制台窗口。(我对此不是 100% 确定;如果我已经重定向stdout到 Windows 以从我这里窃取它,这对我来说似乎有点错误,但我还没有尝试过。)
In general, though, I think it's a bad idea; if all you want to use the console for is to dump more information about your unit test, the output is there for you. Keep using Console.WriteLinethe way you are, and check the output results in the Test Results window when it's done.
不过,总的来说,我认为这是一个坏主意。如果您只想使用控制台来转储有关单元测试的更多信息,那么输出就在那里。继续使用Console.WriteLine您的方式,并在完成后在“测试结果”窗口中检查输出结果。
回答by sinni800
First of all unit tests are, by design, supposed to run completely without interaction.
首先,按照设计,单元测试应该在没有交互的情况下完全运行。
With that aside, I don't think there's a possibility that was thought of.
除此之外,我认为没有想到的可能性。
You could try hacking with the AllocConsole P/Invokewhich will open a console even when your current application is a GUI application. The Consoleclass will then post to the now opened console.
您可以尝试使用AllocConsole P/Invoke进行黑客攻击,即使您当前的应用程序是 GUI 应用程序,它也会打开控制台。然后Console该类将发布到现在打开的控制台。
回答by Wonko the Sane
As stated, unit tests are designed to run without interaction.
如前所述,单元测试旨在无需交互即可运行。
However, you can Debug unit tests, just like any other code. The easiest way is to use the Debug button in the Test Results tab.
但是,您可以调试单元测试,就像任何其他代码一样。最简单的方法是使用“测试结果”选项卡中的“调试”按钮。
Being able to Debug means being able to use breakpoints. Being able to use breakpoints, then, means being able to use Tracepoints, which I find extremely useful in every day debugging.
能够调试意味着能够使用断点。能够使用断点意味着能够使用Tracepoints,我发现它在日常调试中非常有用。
Essentially, Tracepoints allow you to write to the Output window (or, more accurately, to standard output). Optionally, you can continue to run, or you can stop like a regular breakpoint. This gives you the "functionality" you are asking for, without the need to rebuild your code, or fill it up with debug information.
本质上,跟踪点允许您写入输出窗口(或更准确地说,写入标准输出)。或者,您可以继续运行,也可以像常规断点一样停止。这为您提供了您所要求的“功能”,而无需重新构建您的代码,或用调试信息填充它。
Simply add a breakpoint, and then right-click on that breakpoint. Select the "When Hit..." option:

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

Which brings up the dialog:

弹出对话框:

A few things to note:
需要注意的几点:
- Notice that the breakpoint is now shown as a diamond, instead of a sphere, indicating a trace point
- You can output the value of a variable by enclosing it like {this}.
- Uncheck the "Continue Execution" checkbox to have the code break on this line, like any regular breakpoint
- You have the option of running a macro. Please be careful - you may cause harmful side effects.
- 请注意,断点现在显示为菱形,而不是球体,表示跟踪点
- 您可以通过像 {this} 一样将变量括起来来输出变量的值。
- 取消选中“继续执行”复选框以使代码在此行中断,就像任何常规断点一样
- 您可以选择运行宏。请小心 - 您可能会导致有害的副作用。
See the documentation for more details.
有关更多详细信息,请参阅文档。
回答by Dmitry Pavlov
You could use this line to write to Output Windowof the Visual Studio:
您可以使用此行写入Visual Studio 的输出窗口:
System.Diagnostics.Debug.WriteLine("Matrix has you...");
Must run at Debug mode.
必须在调试模式下运行。
回答by Sturla
You can use
您可以使用
Trace.WriteLine()
to write to the Output window when debugging a unittest.
在调试单元测试时写入输出窗口。
回答by Hymanie
Debug.WriteLine() can be used as well.
也可以使用 Debug.WriteLine()。
回答by yoyo
There are several ways to write output from a Visual Studio unit test in C#:
有几种方法可以在 C# 中编写 Visual Studio 单元测试的输出:
- Console.Write - The Visual Studio test harness will capture this and show it when you select the test in the Test Explorer and click the Output link. Does notshow up in the Visual Studio Output Window when either running or debugging a unit test (arguably this is a bug).
- Debug.Write - The Visual Studio test harness will capture this and show it in the test output. Doesappear in the Visual Studio Output Window when debugging a unit test, unless Visual Studio Debugging options are configured to redirect Output to the Immediate Window. Nothing will appear in the Output (or Immediate) Window if you simply run the test without debugging. By default only available in a Debug build (that is, when DEBUG constant is defined).
- Trace.Write - The Visual Studio test harness will capture this and show it in the test output. Doesappear in the Visual Studio Output (or Immediate) Window when debugging a unit test (but not when simply running the test without debugging). By default available in both Debug and Release builds (that is, when TRACE constant is defined).
- Console.Write - 当您在测试资源管理器中选择测试并单击输出链接时,Visual Studio 测试工具将捕获并显示它。难道不是在Visual Studio输出窗口显示运行或调试单元测试时(可以说这是一个bug)。
- Debug.Write - Visual Studio 测试工具将捕获它并在测试输出中显示它。调试单元测试时会出现在 Visual Studio 输出窗口中,除非 Visual Studio 调试选项配置为将输出重定向到立即窗口。如果您只是在没有调试的情况下运行测试,则输出(或立即)窗口中不会出现任何内容。默认情况下,仅在 Debug 版本中可用(即定义 DEBUG 常量时)。
- Trace.Write - Visual Studio 测试工具将捕获它并将其显示在测试输出中。在调试单元测试时(而不是在没有调试的情况下简单地运行测试时),是否出现在 Visual Studio 输出(或立即)窗口中。默认情况下,在 Debug 和 Release 版本中都可用(即,当定义了 TRACE 常量时)。
Confirmed in Visual Studio 2013 Professional.
在 Visual Studio 2013 Professional 中得到确认。
回答by Tiago Duarte
Someone commented about this apparently new functionality in VS2013. I wasn't sure what he meant at first, but now that I do, I think it deserve's it's own answer.
有人评论了 VS2013 中这个明显的新功能。一开始我不确定他的意思,但现在我知道了,我认为它应该得到自己的答案。
We can use Console.WriteLine normally and the output is displayed, just not in the Output window, but in a new window after we click "Output" in the test details.
我们可以正常使用 Console.WriteLine 并显示输出,只是不在输出窗口中,而是在我们单击测试详细信息中的“输出”后的新窗口中。
回答by naz hassan
In visual Studio 2017, "TestContext" doesn't show Output link into Test Explorer. However, Trace.Writeline() shows the Ouput link.
在 Visual Studio 2017 中,“TestContext”不会在测试资源管理器中显示输出链接。但是,Trace.Writeline() 显示输出链接。
回答by SwiftArchitect
Visual Studio For Mac
适用于 Mac 的 Visual Studio
None of the other solutions worked on VS for Mac
其他解决方案均不适用于 VS for Mac
If you are using NUnit, you can add a small .NETConsole Projectto your Solution, then reference the project you wish to test in the Referencesof that new Console Project.
如果您使用的是NUnit,您可以将一个小的.NET控制台项目添加到您的解决方案中,然后在该新控制台项目的引用中引用您希望测试的项目。
Whatever you were doing in your [Test()]methods can be done in the Mainof the console app in this fashion:
无论您在[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}");
}
}
You are free to use Console.Writeand Console.WriteLinein your code under these circumstances.
在这些情况下,您可以在您的代码中自由使用Console.Write和Console.WriteLine。

