我在 Visual Studio 中有一个测试项目。我使用Microsoft.VisualStudio.TestTools.UnitTesting。
我在我的一个单元测试中添加了这一行:
Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();
当我运行测试时,测试通过了,但控制台窗口根本没有打开。
有没有办法让控制台窗口可以通过单元测试进行交互?
我在 Visual Studio 中有一个测试项目。我使用Microsoft.VisualStudio.TestTools.UnitTesting。
我在我的一个单元测试中添加了这一行:
Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();
当我运行测试时,测试通过了,但控制台窗口根本没有打开。
有没有办法让控制台窗口可以通过单元测试进行交互?
注意:下面的原始答案应该适用于从 Visual Studio 2012 开始的任何版本的 Visual Studio。Visual Studio 2013 似乎不再有测试结果窗口。相反,如果您需要特定于测试的输出,您可以使用@Stretch 的建议Trace.Write()
将输出写入输出窗口。
该Console.Write
方法不写入“控制台”——它写入连接到正在运行进程的标准输出句柄的任何内容。同样,Console.Read
从连接到标准输入的任何内容中读取输入。
通过 Visual Studio 2010 运行单元测试时,标准输出由测试工具重定向并存储为测试输出的一部分。您可以通过右键单击“测试结果”窗口并将名为“Output (StdOut)”的列添加到显示中来看到这一点。这将显示写入标准输出的任何内容。
您可以使用P/Invoke手动打开控制台窗口,如sinni800 所说。通过阅读AllocConsole
文档,该函数似乎将重置stdin
并stdout
处理以指向新的控制台窗口。(我对此不是 100% 确定;如果我已经重定向stdout
到 Windows 以从我这里窃取它,这对我来说似乎有点错误,但我没有尝试过。)
不过,总的来说,我认为这是一个坏主意。如果您只想使用控制台转储有关单元测试的更多信息,那么输出就在那里。继续使用Console.WriteLine
您的方式,并在完成后检查“测试结果”窗口中的输出结果。
如前所述,单元测试旨在无需交互即可运行。
但是,您可以调试单元测试,就像任何其他代码一样。最简单的方法是使用Debug“测试结果”选项卡中的按钮。
能够调试意味着能够使用断点。因此,能够使用断点意味着能够使用Tracepoints,我发现它在日常调试中非常有用。
本质上,跟踪点允许您写入输出窗口(或更准确地说,写入标准输出)。或者,您可以继续运行,也可以像常规断点一样停止。这为您提供了您所要求的“功能”,而无需重新构建代码或用调试信息填充它。
只需添加一个断点,然后右键单击该断点。选择“当命中...”选项:
这带来了对话框:
需要注意的几点:
有关更多详细信息,请参阅文档。
有几种方法可以在 C# 中编写 Visual Studio 单元测试的输出:
在 Visual Studio 2013 Professional 中确认。
您可以使用
Trace.WriteLine()
在调试单元测试时写入输出窗口。
在 Visual Studio 2017 中,“TestContext”不会在测试资源管理器中显示输出链接。
但是, Trace.Writeline() 显示输出链接。
首先,根据设计,单元测试应该在没有交互的情况下完全运行。
除此之外,我认为没有考虑过这种可能性。
您可以尝试使用AllocConsole P/Invoke进行破解,即使您当前的应用程序是 GUI 应用程序,它也会打开一个控制台。然后该Console
课程将发布到现在打开的控制台。
Debug.WriteLine() 也可以使用。
恕我直言,在大多数情况下,输出消息仅与失败的测试用例相关。我制作了以下格式,您也可以自己制作。这显示在 Visual Studio 测试资源管理器窗口本身中。
我们如何在 Visual Studio 测试资源管理器窗口中抛出此消息?
像这样的示例代码应该可以工作:
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.");
您可以为您专门开设一个单独的课程。
我有一个更简单的解决方案(出于许多懒惰的原因,我最近使用了自己)。将此方法添加到您正在使用的类中:
public static void DumbDebug(string message)
{
File.WriteAllText(@"C:\AdHocConsole\" + message + ".txt", "this is really dumb. I wish Microsoft had more obvious solutions to its solutions problems.");
}
然后...打开目录 AdHocConsole,并按创建时间排序。确保在添加“打印声明”时。虽然它们是不同的,否则会有杂耍。
其他解决方案均不适用于 Visual Studio for Mac
如果您使用的是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
在您的代码中。