[C#]Outputting Debug Messages in xUnit.net Unit Tests

目次

Overview

When executing tests in xUnit.net, standard Console.WriteLine statements do not display output. Instead, you must receive the ITestOutputHelper interface via the constructor (Dependency Injection) and use its WriteLine method. This allows logs to appear in the results screen of the Test Explorer.

Specifications (Input/Output)

  • Interface: ITestOutputHelper (located in xunit.Abstractions)
  • Primary Methods:
    • WriteLine(string message): Outputs a string followed by a line terminator.
    • WriteLine(string format, params object[] args): Outputs a formatted string using the same syntax as string.Format.

Basic Usage

public class MyTests
{
    private readonly ITestOutputHelper _output;

    // Receive the instance via the constructor
    public MyTests(ITestOutputHelper output)
    {
        _output = output;
    }

    [Fact]
    public void Test1()
    {
        // Log output
        _output.WriteLine("Test1 started.");
        
        Assert.True(true);
    }
}

Full Code

The following example verifies a method that returns the larger of two numbers while logging the input values.

using System;
using Xunit;
using Xunit.Abstractions; // Required

namespace TestProject
{
    public class DebugOutputTests
    {
        // Field to hold the output helper
        private readonly ITestOutputHelper _output;

        // xUnit automatically injects the implementation of ITestOutputHelper
        public DebugOutputTests(ITestOutputHelper output)
        {
            _output = output;
        }

        [Theory]
        [InlineData(10, 5, 10)]
        [InlineData(2, 8, 8)]
        [InlineData(-1, -5, -1)]
        public void Max_ReturnsLargerValue(int val1, int val2, int expected)
        {
            // Log input values for easier tracking
            _output.WriteLine($"Input Values: val1={val1}, val2={val2}");
            _output.WriteLine($"Expected Max: {expected}");

            var utils = new MathUtilities();
            var result = utils.Max(val1, val2);

            _output.WriteLine($"Actual Result: {result}");

            Assert.Equal(expected, result);
        }
    }

    // Class to be tested
    public class MathUtilities
    {
        public int Max(int a, int b)
        {
            // Same behavior as Math.Max
            return (a >= b) ? a : b;
        }
    }
}

Customization Points

  • Formatted Output: You can use the string.Format style, such as _output.WriteLine("Value: {0}, ID: {1}", value, id);.
  • Where to View Output: In Visual Studio, select the specific test in the Test Explorer. Click the “Output” link in the summary pane to view the logs.

Points of Caution

  • Console.WriteLine is Disabled: Because xUnit runs tests in parallel, writes to the standard output (Console) are not captured and are ignored. You must use ITestOutputHelper.
  • Only Available in Constructors: This helper is injected only into the test class constructor. You cannot receive it as a direct argument in a [Fact] method.
  • Limitations with Class Fixtures: Even if you implement IClassFixture, ITestOutputHelper is injected into the test class instance, not the fixture class. This is a design constraint in xUnit.

Application

Logging Execution Time

This example measures and outputs the time taken for a specific process.

[Fact]
public void PerformanceTest()
{
    var sw = System.Diagnostics.Stopwatch.StartNew();
    
    // Simulate a heavy process
    System.Threading.Thread.Sleep(100); 

    sw.Stop();
    _output.WriteLine($"Elapsed Time: {sw.ElapsedMilliseconds} ms");
}

Summary

To output debug messages in xUnit.net, you must receive ITestOutputHelper through the constructor. This ensures that the correct logs are associated with each test case even during parallel execution, making it easier to investigate failures and trace input values.

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次