Logging in Integration Testing

Daniel Crenna
2 min readMar 5, 2021

--

There are three main concerns when you’re using in-memory integration tests for ASP.NET Core, when it comes to logging.

Logging Providers may produce unintended side effects

Because the principle behind integration testing at this level is to ensure that no modifications are necessary to your web application, with changes coming only where necessary, usually in the form of dependency injection in order to indirect code flow away from actual live services, logging is often overlooked. It’s easy to forget to remove remote-source loggers, or add unnecessary overhead for event logs.

The recommended testing framework doesn’t log to the console, or capture logging statements, by default

Xunit is the de facto testing framework for ASP.NET Core Web Applications. By default, it does not log to the Console, electing to do the right thing by way of asynchronous test execution. Instead, you’re meant to use the ITestOutputHelperinterface via constructor injection, and call it as a surrogate for logging statements. This means you won’t see Console logs, even if you’ve configured them for the web application, and you don’t have direct access to the statements you’ve already written using ILogger.

To solve these issues, you can use an extension method that is meant to chain WebApplicationFactory<TStartup>. Its purpose is to redirect logging statements to Xunit’s output helper, as well as clear the providers referenced in startup. By design, it should mimic the Console logging format that you’re accustomed to seeing when running Kestrel, as well as support external scopes if you’re using them.

Now, when you want to run integration tests, but get logging feedback the same way as a running application, you just have to setup your testing class to use this additional feature.

Now your test output will faithfully reproduce logging, including appsettings.jsonconfiguration preferences and scope inclusions, without additional logging overhead or accidental remote exposure.

The full solution is available on GitHub.

--

--