Подтвердить что ты не робот

XUnit.net не отображает вывод консоли

Я только начал тестировать xUnit.net, но, похоже, он не отображает какой-либо вывод (Console, Debug, Trace), как я и ожидал.

Это возможно? Я использую образец библиотеки классов .NET 4.0 с xUnit.net 1.8.

4b9b3361

Ответ 1

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

xunit.gui.exe отображает xunit.gui.exe консоли и трассировки, а xunit.console.exe - нет. Если это важно, вы можете подключить TraceListener, который перенаправляет в файл, сделав соответствующие стандартные записи конфигурации .NET(Theres ' FileWriterTraceListener который вы сможете подключить, если вы его Google).


ОБНОВЛЕНИЕ: Как обсуждалось в его сообщении в блоге, у Дамиана Хикки есть хороший пример возможной замены - ведение журнала в xUnit 2 ITestOutputHelper как показано в https://github.com/damianh/CapturingLogOutputWiспасибоunit2AndParallelTests/blob/master/srcLib. Испытания /Tests.cs

ОБНОВЛЕНИЕ 2: В некоторых случаях можно добавить ведение журнала и ITestOutputHelper его в ITestOutputHelper без использования LogContext, используя простой адаптер следующим образом (у меня это только в F #, извините):

// Requirement: Make SUT depend on Serilog NuGet
// Requirement: Make Tests depend on Serilog.Sinks.Observable

type TestOutputAdapter(testOutput : Xunit.Abstractions.ITestOutputHelper) =
    let formatter = Serilog.Formatting.Display.MessageTemplateTextFormatter(
        "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}", null);
    let write logEvent =
        use writer = new System.IO.StringWriter()
        formatter.Format(logEvent, writer);
        writer |> string |> testOutput.WriteLine
    member __.Subscribe(source: IObservable<Serilog.Events.LogEvent>) =
        source.Subscribe write

let createLogger hookObservers =
    LoggerConfiguration()
        .WriteTo.Observers(Action<_> hookObservers)
        .CreateLogger()
let createTestOutputLogger (output: ITestOutputHelper) =
    let adapter = TestOutputAdapter testOutputHelper
    createLogger (adapter.Subscribe >> ignore)

type Tests(testOutputHelper) =
    let log = createTestOutputLogger testOutputHelper

    [<Fact>] let feedToSut () =
        // TODO pass log to System Under Test either as a ctor arg or a method arg

Разница с этим подходом по сравнению с использованием контекста журнала заключается в том, что регистрация в глобальном [контекстуализированном] Serilog Logger не будет выполнена.

Ответ 2

С xUnit.net 2. ситуация немного изменилась. Я знаю, что вопрос касается более ранней версии, но, так как люди будут приземляться здесь, выполнив обновление, я подумал, что стоит указать на это.

Чтобы увидеть какой-то вывод в тестовом выводе в версии 2, вам нужно взять зависимость в вашем тестовом классе (через аргумент конструктора) от экземпляра Xunit.Abstractions.ITestOutputHelper, а затем использовать метод WriteLine на этом интерфейсе., Например.:

public class MyTestSpec
{
  private readonly ITestOutputHelper _testOutputHelper;

  public MyTestSpec(ITestOutputHelper testOutputHelper)
  {
    _testOutputHelper = testOutputHelper;
  }

  [Fact]
  public void MyFact()
  {
    _testOutputHelper.WriteLine("Hello world");
  }
}

Вы можете подключить свою структуру ведения журналов к этому интерфейсу, возможно, внедрив реализацию ILog, которая перенаправляла все вызовы на ITestOutpuHelper.

Я признаю, что вы не захотите делать это по умолчанию, но для диагностических целей время от времени это может быть весьма полезным. Это особенно верно в тех случаях, когда ваши тесты проваливаются только на некоторых облачных сборках & тестовый сервер!

Ответ 3

Это может помочь, если ваш Console.Write встроен вглубь некоторой иерархии классов, которую вы не хотите реорганизовывать:

    public MyTestClass(ITestOutputHelper output)
    {
        var converter = new Converter(output);
        Console.SetOut(converter);
    }

    private class Converter : TextWriter
    {
        ITestOutputHelper _output;
        public Converter(ITestOutputHelper output)
        {
            _output = output;
        }
        public override Encoding Encoding
        {
            get { return Encoding.Whatever; }
        }
        public override void WriteLine(string message)
        {
            _output.WriteLine(message);
        }
        public override void WriteLine(string format, params object[] args)
        {
            _output.WriteLine(format, args);
        }
    }

Ответ 4

Существует решение, найденное здесь: https://xunit.codeplex.com/discussions/211566

Просто добавьте это в свой конструктор или метод, где вы хотите отлаживать вывод:

Debug.Listeners.Add(new DefaultTraceListener());

Ответ 5

Я приземлился здесь с тем же вопросом. Вот чем я закончил. Я надеюсь, что это помогает кому-то еще.

Как написать собственную цель

    /// <summary>
    ///     Use this to output NLog information when running test cases.
    /// </summary>
    [Target("XUnit")]
    public class XUnitTarget : TargetWithLayout
    {
        [RequiredParameter] public ITestOutputHelper OutputHelper { get; set; }

        protected override void Write(LogEventInfo logEvent)
        {
            var logMessage = Layout.Render(logEvent);
            OutputHelper.WriteLine(logMessage);
        }

        /// <summary>
        /// Call this in the test where you wish to enable logging.
        /// </summary>
        /// <param name="testOutputHelper">The xUnit output helper from the test.</param>
        public static void Configure(ITestOutputHelper testOutputHelper)
        {
            var config = new LoggingConfiguration();
            var xUnitTarget = new XUnitTarget
            {
                OutputHelper = testOutputHelper
            };
            config.AddTarget("xUnit", xUnitTarget);
            config.AddRule(LogLevel.Trace, LogLevel.Fatal, xUnitTarget);
            LogManager.Configuration = config;
        }
    }