我可以写到控制台单元测试? 如果是的话,为什么不打开控制台窗口?(Can I write int

2019-06-25 18:57发布

我在Visual Studio中的测试项目。 我用Microsoft.VisualStudio.TestTools.UnitTesting。

我加入这一行中的我的单元测试之一:

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

当我运行测试,测试通过,但不是在所有打开控制台窗口。

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

Answer 1:

注:下面的原始答案应该向上穿过VS2012为VS的任何版本。 VS2013不会出现有一个测试结果窗口了。 相反,如果你需要特定的测试输出可以使用@舒展的建议Trace.Write()将输出写入到输出窗口。


Console.Write方法不写“控制台” -其写入无论是挂接到的正在运行的进程的标准输出句柄。 同样, Console.Read读取无论是挂在标准输入的输入。

当运行通过VS2010一个单元测试,标准输出由测试工具重定向和作为测试输出的一部分被存储。 您可以通过右键单击测试结果窗口,并添加一个名为“输出(stdout)”,以显示中的列看到这一点。 这将显示已写入到标准输出任何东西。

可以手动打开控制台窗口,使用P / Invoke为@ sinni800说。 从阅读AllocConsole文档,看来该功能将重置stdinstdout处理,使其指向新的控制台窗口。 (我不是100%肯定有关,这似乎有点错误的我,如果我已经重定向stdout为Windows从我偷,我没试过。)

总的来说,虽然,我认为这是一个坏主意; 如果你想要使用控制台是转储你的单元测试的更多信息,输出是有你。 继续使用Console.WriteLine你的方式,并检查测试结果窗口中的输出结果时,它的完成。



Answer 2:

有人评论了关于在VS2013这显然是新的功能。 我不知道他是什么意思,在第一,但现在,我做的,我认为它值得的它自己的答案。

我们可以正常使用Console.WriteLine并显示输出,只是没有在输出窗口,但在一个新的窗口之后,我们在测试详情点击“输出”。



Answer 3:

您可以使用此行写入输出窗口在Visual Studio中:

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

希望帮助



Answer 4:

如前所述,单元测试的目的是没有的互动运行。

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

能够调试意味着能够使用断点。 能够使用断点,那么,意味着能够使用跟踪点 ,我觉得在每一天的调试是非常有用的。

从本质上讲,跟踪点允许你写到输出窗口(或者,更精确地,以标准输出)。 或者,您可以继续运行,也可以停止像一个普通的断点。 这给你的“功能”你所要求的,而不需要重新构建你的代码,或调试信息填充它。

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

这将弹出对话框:

有几件事情需要注意:

  1. 请注意,该断点现在显示为菱形,而不是球,指示跟踪点
  2. 您可以通过内附像{}这个输出变量的值。
  3. 取消选中“继续执行”复选框,使该线路上的代码休息,就像任何普通的断点
  4. 您有运行宏的选项。 请小心 - 你可能会产生有害的副作用。

更多细节见文档。



Answer 5:

有几种方法可以在C#中的Visual Studio单元测试写输出:

  • Console.Write - Visual Studio的测试工具将捕捉这一点,并表明它,当你选择在测试浏览器的测试,并单击输出链接。 在Visual Studio输出窗口显示当运行或调试单元测试(可以说这是一个bug)。
  • Debug.Write - Visual Studio的测试工具将捕捉这一点,它显示测试输出。 调试单元测试时,除非Visual Studio中的调试选项被配置为输出重定向到即时窗口出现在Visual Studio的输出窗口。 什么都不会出现在输出(或立即)窗口,如果你只是运行测试而不调试。 默认情况下,只在调试版本(即,被定义DEBUG常数时)。
  • Trace.Write - Visual Studio的测试工具将捕捉这一点,它显示测试输出。 调试单元测试(而不是简单地时运行测试没有调试)时是否出现在Visual Studio输出(或立即)窗口。 通过在这两个调试和发布版本(即,被定义TRACE常数时)可用的默认。

证实在Visual Studio 2013专业版。



Answer 6:

您可以使用

Trace.WriteLine() 

调试单元测试时,写入到输出窗口。



Answer 7:

在Visual Studio 2017“的TestContext”不显示输出连接到测试资源管理器。 然而,Trace.Writeline()显示输出继电器的链接。



Answer 8:

首先,单元测试的是,按照设计 ,应该不完全的交互运行。

与放在一边,我不认为有这被认为的可能性。

您可以尝试与黑客AllocConsole的P / Invoke将打开,即使当前的应用程序是一个GUI应用程序的控制台。 该Console然后类将张贴到现在打开控制台。



Answer 9:

的Debug.WriteLine()可被使用。



Answer 10:

这恰好不是一个解决方案,但是从书中的方法计算

由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" );
        }
    }


Answer 11:

恕我直言输出消息仅限于在大多数情况下,失败的测试用例相关。 我做了下面的格式,你可以让你自己的了。 这显示在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.");

你可以奉献给这个给你一个单独的类。 希望能帮助到你!



Answer 12:

Visual Studio中对于Mac

其他解决方案的无工作的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.WriteConsole.WriteLine在你的代码在这种情况下。



文章来源: Can I write into console in a unit test? If yes, why the console window is not opened?