#c# #.net #unit-testing #mstest #stdout
#c# #.net #модульное тестирование #mstest #стандартный вывод
Вопрос:
есть много примеров, которые показывают, как перенаправить стандартный вывод другого приложения. Однако я хотел бы, чтобы приложение сохраняло свой стандартный вывод и получало копию стандартного вывода только в моем родительском процессе. Возможно ли это?
Мой сценарий: у меня есть несколько тестов (с использованием Visual Studio Test Runner), которые запускают внешний процесс (сервер) для их тестирования. Сервер выводит много полезной отладочной информации в своем стандартном выводе, который я хотел бы включить в результаты моего тестирования.
Я могу захватить вывод процесса и вывести его с помощью трассировки.WriteLine, чтобы он отображался в деталях теста позже. Однако было бы неплохо увидеть окно сервера с его выводом во время выполнения теста, чтобы увидеть текущий прогресс (тест может выполняться долгое время).
Поэтому я ищу способы скопировать эту информацию вместо простого перенаправления.
Есть идеи?
Комментарии:
1. ммм, возможно, поток Echo / Tee может помочь? codeproject.com/KB/dotnet/echostream.aspx (погуглите «c # tee stream», чтобы найти еще много просмотров)
2. Не уверен в этом, поскольку я не могу протестировать здесь, но может быть правдой, что процесс. Событие OutputDataReceived выдает желаемое поведение, см.: msdn.microsoft.com/en-us/library /…
3. OutputDataReceived — это то, что я использую, но для этого требуется перенаправление потока и, следовательно, удаляет вывод из окна консоли сервера…
Ответ №1:
Будет ли это работать для вас?
var outputText = new StringBuilder();
var errorText = new StringBuilder();
using (var process = Process.Start(new ProcessStartInfo(
@"YourProgram.exe",
"arguments go here")
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false
}))
{
process.OutputDataReceived = (sendingProcess, outLine) =>
{
outputText.AppendLine(outLine.Data); // capture the output
Console.Out.WriteLine(outLine.Data); // echo the output
}
process.ErrorDataReceived = (sendingProcess, errorLine) =>
{
errorText.AppendLine(errorLine.Data); // capture the error
Console.Error.WriteLine(errorLine.Data); // echo the error
}
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
// At this point, errorText and outputText StringBuilders
// have the captured text. The event handlers already echoed the
// output back to the console.
}
Комментарии:
1. Это. Скопируйте вывод консоли, перенаправив его в составной класс вывода, который будет «транслировать» вывод нескольким «слушателям». Существует много шаблонов; это, вероятно, один из менее сложных в реализации.
2. проблема в том, что этот код выполняется как часть модульного теста внутри тестового модуля Microsoft Visual Studio. у самого тестового запуска нет окна консоли…
Ответ №2:
Как насчет написания небольшой программы, которая перенаправляет стандартный ввод в стандартный вывод, в то же время делая с ним что-то еще?
Затем вы можете заменить команду, которая запускает серверный процесс, на ту, которая запускает его и передает его вывод в указанную выше утилиту. Таким образом, вы будете иметь программный доступ к выводу и видеть его в режиме реального времени в окне вывода.
Комментарии:
1. да, это решение, и я думал об этом, просто кажется немного излишним для использования в моих тестах. Я надеялся на более простое решение. Другим (небольшим) недостатком является то, что мой сервер использует цветной вывод, который не будет виден в приложении пересылки.
2. Я решил, что небольшого преимущества отображения окна сервера недостаточно, чтобы еще больше усложнить мой тестовый код. Однако ваша идея сработала бы с небольшой модификацией: захват вывода моего сервера в тестовом коде и отправка его в эту программу «echo», которая просто отобразила бы его в консоли.