我在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();
当我运行测试,测试通过,但不是在所有打开控制台窗口。
有没有一种方法,使可通过单元测试来进行交互控制台窗口?
注:下面的原始答案应该向上穿过VS2012为VS的任何版本。 VS2013不会出现有一个测试结果窗口了。 相反,如果你需要特定的测试输出可以使用@舒展的建议Trace.Write()
将输出写入到输出窗口。
该Console.Write
方法不写“控制台” -其写入无论是挂接到的正在运行的进程的标准输出句柄。 同样, Console.Read
读取无论是挂在标准输入的输入。
当运行通过VS2010一个单元测试,标准输出由测试工具重定向和作为测试输出的一部分被存储。 您可以通过右键单击测试结果窗口,并添加一个名为“输出(stdout)”,以显示中的列看到这一点。 这将显示已写入到标准输出任何东西。
您可以手动打开控制台窗口,使用P / Invoke为@ sinni800说。 从阅读AllocConsole
文档,看来该功能将重置stdin
和stdout
处理,使其指向新的控制台窗口。 (我不是100%肯定有关,这似乎有点错误的我,如果我已经重定向stdout
为Windows从我偷,我没试过。)
总的来说,虽然,我认为这是一个坏主意; 如果你想要使用控制台是转储你的单元测试的更多信息,输出是有你。 继续使用Console.WriteLine
你的方式,并检查测试结果窗口中的输出结果时,它的完成。
有人评论了关于在VS2013这显然是新的功能。 我不知道他是什么意思,在第一,但现在,我做的,我认为它值得的它自己的答案。
我们可以正常使用Console.WriteLine并显示输出,只是没有在输出窗口,但在一个新的窗口之后,我们在测试详情点击“输出”。
您可以使用此行写入输出窗口在Visual Studio中:
System.Diagnostics.Debug.WriteLine("Matrix has you...");
希望帮助
如前所述,单元测试的目的是没有的互动运行。
但是,您可以调试单元测试,就像任何其他代码。 最简单的方法是在测试结果选项卡使用调试按钮。
能够调试意味着能够使用断点。 能够使用断点,那么,意味着能够使用跟踪点 ,我觉得在每一天的调试是非常有用的。
从本质上讲,跟踪点允许你写到输出窗口(或者,更精确地,以标准输出)。 或者,您可以继续运行,也可以停止像一个普通的断点。 这给你的“功能”你所要求的,而不需要重新构建你的代码,或调试信息填充它。
只需添加一个断点,在该断点,然后单击鼠标右键。 选择“当打...”选项:
这将弹出对话框:
有几件事情需要注意:
更多细节见文档。
有几种方法可以在C#中的Visual Studio单元测试写输出:
证实在Visual Studio 2013专业版。
您可以使用
Trace.WriteLine()
调试单元测试时,写入到输出窗口。
在Visual Studio 2017“的TestContext”不显示输出连接到测试资源管理器。 然而,Trace.Writeline()显示输出继电器的链接。
首先,单元测试的是,按照设计 ,应该不完全的交互运行。
与放在一边,我不认为有这被认为的可能性。
您可以尝试与黑客AllocConsole的P / Invoke将打开,即使当前的应用程序是一个GUI应用程序的控制台。 该Console
然后类将张贴到现在打开控制台。
的Debug.WriteLine()可被使用。
这恰好不是一个解决方案,但是从书中的方法计算
由Roy Osherove单元测试的艺术
我们需要存根打破这些依赖关系,就像写文件系统或书面形式向事件日志或写入到控制台 -
存根可以传递到主类,如果没有存根空然后写存根。 但是它可以改变API(就像现在的构造函数有一个存根参数)。 另一种方法是继承和创建一个模拟对象。 这将在下面描述。
namespace ClassLibrary1
{
// TO BE TESTED
public class MyBusinessClass
{
ConsoleStub myConsoleForTest;
public MyBusinessClass()
{
// Constructor
}
// This is test stub approach - 2
public MyBusinessClass(ConsoleStub console)
{
this.myConsoleForTest = console;
}
public virtual void MyBusinessMethod(string s)
{
// this needs to be unit tested
Console.WriteLine(s);
// Just an example - you need to be creative here
// there are many ways
if (myConsoleForTest !=null){
myConsoleForTest.WriteLine(s);
}
}
}
public class ConsoleStub
{
private string textToBeWrittenInConsole;
public string GetLastTextWrittenInConsole
{
get
{
return this.textToBeWrittenInConsole;
}
}
public void WriteLine(string text)
{
this.textToBeWrittenInConsole = text;
}
}
public class MyBusinessClassMock :MyBusinessClass
{
private ConsoleStub consoleStub;
public MyBusinessClassMock()
{
// Constructor
}
public MyBusinessClassMock(ConsoleStub stub)
{
this.consoleStub = stub;
}
public override void MyBusinessMethod(string s)
{
// if MOCK is not an option then pass this stub
// as property or parameter in constructor
// if you do not want to change the api still want
// to pass in main class then , make it protected and
// then inherit it and make just a property for consoleStub
base.MyBusinessMethod(s);
this.consoleStub.WriteLine(s);
}
}
[TestClass]
public class ConsoleTest
{
private ConsoleStub consoleStub;
private MyBusinessClassMock mybusinessObj
[TestInitialize]
public void Initialize()
{
consoleStub = new ConsoleStub();
mybusinessObj = new MyBusinessClassMock(consoleStub);
}
[TestMethod]
public void TestMyBusinessMethod()
{
mybusinessObj.MyBusinessMethod("hello world");
Assert.AreEqual(this.consoleStub.GetLastTextWrittenInConsole,"hello world" );
}
}
}
// Approach - 2
[TestClass]
public class ConsoleTest
{
private ConsoleStub consoleStub;
private MyBusinessClass mybusinessObj
[TestInitialize]
public void Initialize()
{
consoleStub = new ConsoleStub();
mybusinessObj = new MyBusinessClass(consoleStub);
}
[TestMethod]
public void TestMyBusinessMethod()
{
mybusinessObj.MyBusinessMethod("hello world");
Assert.AreEqual(this.consoleStub.GetLastTextWrittenInConsole,"hello world" );
}
}
恕我直言输出消息仅限于在大多数情况下,失败的测试用例相关。 我做了下面的格式,你可以让你自己的了。 这显示在VS测试资源管理器窗口本身。
如何扔在VS测试资源管理器窗口此消息? 像这样的示例代码应该工作。
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.");
你可以奉献给这个给你一个单独的类。 希望能帮助到你!
其他解决方案的无工作的VS为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
在你的代码在这种情况下。