Могу ли я писать в консоль в модульном тесте? Если да, то почему консоль не открывается?



У меня есть тестовый проект в Visual Studio. Я использую Microsoft.VisualStudio.TestTools.UnitTesting.



Я добавляю эту строку в один из моих модульных тестов:



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


когда я запускаю тест, тест проходит, но окно консоли не открывается вообще.



есть ли способ сделать окно консоли доступным для взаимодействия с помощью модульного теста?

653   11  

11 ответов:

Примечание: оригинальный ответ ниже должен работать для любой версии VS до VS2012. VS2013, похоже, больше не имеет окна результатов тестирования. Вместо этого, если вам нужен тестовый выход, вы можете использовать предложение @Stretch Trace.Write() для записи вывода в окно вывода.


The Console.Write метод не записывает в "консоль" -- он записывает все, что подключено к стандартному выходному дескриптору для запущенного процесса. Точно так же,Console.Read читает входной сигнал от все, что подключено к стандартному входу.

при выполнении модульного теста через VS2010 стандартный вывод перенаправляется тестовым жгутом и сохраняется как часть тестового вывода. Вы можете увидеть это, щелкнув правой кнопкой мыши окно результатов теста и добавив столбец с именем "Output (StdOut)" на дисплей. Это покажет все, что было написано в stdout.

вы может вручную откройте окно консоли, используя P / Invoke, как говорит @sinni800. От чтения AllocConsole документация, похоже, что функция будет сброшена stdin и stdout маркеры для указания на новое окно консоли. (Я не на 100% уверен в этом; мне кажется, что это неправильно, если я уже перенаправил stdout для Windows, чтобы украсть его от меня, но я не пробовал.)

в общем, хотя, я думаю, что это плохая идея; если все, что вы хотите использовать консоль для того, чтобы сбросить более подробную информацию о тесте блока, Выход есть для вас. Продолжайте использовать Console.WriteLine как вы, и проверьте выходные результаты в окне результатов тестирования, когда это будет сделано.

кто-то прокомментировал эту, по-видимому, новую функциональность в VS2013. Сначала я не был уверен, что он имел в виду, но теперь, когда я это делаю, я думаю, что это заслуживает собственного ответа.

мы можем использовать консоль.WriteLine обычно и вывод отображается, только не в окне вывода, а в новом окне после того, как мы нажмем "выход" в деталях теста.

enter image description here

Как говорится, модульные тесты предназначены для работы без взаимодействия.

однако вы можете отлаживать модульные тесты, как и любой другой код. Самый простой способ - использовать кнопку отладка на вкладке Результаты теста.

возможность отладки означает возможность использования точек останова. Таким образом, возможность использовать точки останова означает возможность использовать точки, который я нахожу чрезвычайно полезным в каждый день отладки.

По Существу, Точки Трассировки разрешить запись в окно вывода (или, точнее, в стандартный вывод). При необходимости можно продолжить выполнение или остановиться как обычная точка останова. Это дает вам "функциональность", которую вы просите, без необходимости перестраивать свой код или заполнять его отладочной информацией.

просто добавить точку останова, а затем щелкните правой кнопкой мыши на этой точке останова. Выберите "при попадании..." опцион: When Hit option

который вызывает диалоговое окно: When Breakpoint Is Hit

A несколько вещей, чтобы отметить:

  1. обратите внимание, что точка останова теперь отображается как алмаз, а не сфера, указывая точку трассировки
  2. вы можете вывести значение переменной, заключив его как {this}.
  3. снимите флажок" продолжить выполнение", чтобы иметь разрыв кода в этой строке, как и любая обычная точка останова
  4. у вас есть возможность запустить макрос. Пожалуйста, будьте осторожны - вы можете вызвать вредную сторону эффекты.

дополнительную информацию см. В документации.

вы можете использовать эту строку, чтобы написать Окно Вывода из Visual Studio:

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

надеюсь, что это поможет

существует несколько способов записи выходных данных из модульного теста Visual Studio в C#:

    можно использовать

    Trace.WriteLine() 
    

    для записи в окно вывода при отладке unittest.

    в visual Studio 2017 "TestContext" не показывает выходную ссылку в Обозревателе тестов. Впрочем, След.Writeline () показывает ссылку выхода.

    прежде всего модульные тесты, по конструкция, должен работать полностью без взаимодействия.

    С этим в сторону, я не думаю, что есть возможность, о которой думали.

    вы можете попробовать взломать с помощью AllocConsole P / Invoke который откроет консоль, даже если ваше текущее приложение является приложением GUI. Элемент Console класс затем отправит сообщение на открывшуюся консоль.

    "отладка".WriteLine () также может быть использован.

    Это точно не решение , а подход из книги

    искусство модульного тестирования Роя Osherove

    нам нужны заглушки, чтобы сломать эти зависимости, такие как запись в файловую систему или запись в журнал событий или запись в консоль -

    заглушка может быть передана в основной класс, и если заглушка не null, то напишите в заглушку. Однако он может изменить 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" );
            }
        }
    

    Visual Studio Для Mac

    ни одно из других решений не работало на VS для Mac

    если вы используете Нанит, вы можете добавить небольшое .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 в коде при таких обстоятельствах.

    Comments

      Ничего не найдено.