Могу ли я писать в консоль в модульном тесте? Если да, то почему консоль не открывается?
У меня есть тестовый проект в Visual Studio. Я использую Microsoft.VisualStudio.TestTools.UnitTesting.
Я добавляю эту строку в один из моих модульных тестов:
Console.WriteLine("Some foo was very angry with boo");
Console.ReadLine();
когда я запускаю тест, тест проходит, но окно консоли не открывается вообще.
есть ли способ сделать окно консоли доступным для взаимодействия с помощью модульного теста?
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 обычно и вывод отображается, только не в окне вывода, а в новом окне после того, как мы нажмем "выход" в деталях теста.
Как говорится, модульные тесты предназначены для работы без взаимодействия.
однако вы можете отлаживать модульные тесты, как и любой другой код. Самый простой способ - использовать кнопку отладка на вкладке Результаты теста.
возможность отладки означает возможность использования точек останова. Таким образом, возможность использовать точки останова означает возможность использовать точки, который я нахожу чрезвычайно полезным в каждый день отладки.
По Существу, Точки Трассировки разрешить запись в окно вывода (или, точнее, в стандартный вывод). При необходимости можно продолжить выполнение или остановиться как обычная точка останова. Это дает вам "функциональность", которую вы просите, без необходимости перестраивать свой код или заполнять его отладочной информацией.
просто добавить точку останова, а затем щелкните правой кнопкой мыши на этой точке останова. Выберите "при попадании..." опцион:
который вызывает диалоговое окно:
A несколько вещей, чтобы отметить:
- обратите внимание, что точка останова теперь отображается как алмаз, а не сфера, указывая точку трассировки
- вы можете вывести значение переменной, заключив его как {this}.
- снимите флажок" продолжить выполнение", чтобы иметь разрыв кода в этой строке, как и любая обычная точка останова
- у вас есть возможность запустить макрос. Пожалуйста, будьте осторожны - вы можете вызвать вредную сторону эффекты.
дополнительную информацию см. В документации.
вы можете использовать эту строку, чтобы написать Окно Вывода из Visual Studio:
System.Diagnostics.Debug.WriteLine("Matrix has you...");надеюсь, что это поможет
в visual Studio 2017 "TestContext" не показывает выходную ссылку в Обозревателе тестов. Впрочем, След.Writeline () показывает ссылку выхода.
прежде всего модульные тесты, по конструкция, должен работать полностью без взаимодействия.
С этим в сторону, я не думаю, что есть возможность, о которой думали.
вы можете попробовать взломать с помощью AllocConsole P / Invoke который откроет консоль, даже если ваше текущее приложение является приложением GUI. Элемент
Consoleкласс затем отправит сообщение на открывшуюся консоль.
Это точно не решение , а подход из книги
искусство модульного тестирования Роя 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