在使用TestServer进行集成测试时,在Visual Studio测试运行器中获得控制台登录 &



当直接使用我的模块执行集成测试(跳过API)时,我在Visual Studio测试运行器中获得控制台输出。

当我尝试执行集成测试,包括我的API与TestServer,我得到所有的日志到调试窗口,如果我在调试中运行,但我没有得到任何输出在Visual Studio测试运行器正常运行时。

我正在使用NUnit。

集成测试设置(跳过API)

public class Tests
{
private ILogger _loggerForModule;
[SetUp]
public void InitializeModule()
{
// Create the logger
using (ILoggerFactory loggerFactory = LoggerFactory.Create(b =>
{
b.AddConsole();
b.AddDebug();
}))
{
_loggerForModule = loggerFactory.CreateLogger("Module.Logging");
}
// Initialize the module with the logger created for it.
ModuleInitializer.Initialize(_loggerForModule);
}
[Test]
public async Task TestMyMethod()
{
ModuleCommands.ExecuteCommand(new DoMethodCommand("method param"));
}
}

当我运行这个测试时,在我的模块中的DoMethodCommand中执行的所有日志记录都记录到测试运行器的控制台中。

API集成测试

public class Tests
{
private TestServer _testServer;
private HttpClient _httpClient;
[OneTimeSetUp]
public void SetupTestServerAndHttpClient()
{
_testServer = new TestServer(new WebHostBuilder()
.UseStartup<MyWebAPIProject.Startup>();
_httpClient = _testServer.CreateClient();
}
[Test]
public async Task TestMyAPIMethod()
{
await _httpClient.PostAsync("myapiroute", "method param");
}
}

MyWebAPIProject.Startup.cs

public void ConfigureServices(IServiceCollection services)
{
ILogger loggerForModule;
using (ILoggerFactory loggerFactory.Create(b => 
{
b.AddConsole();
b.AddDebug();
}))
{
loggerForModule = loggerFactory.CreateLogger("Module.Logging")
}
ModuleInitializer.Initialize(loggerForModule);
}

使用上面的命令,API将命令传递到我的模块,一切都执行正常,我可以在调试窗口中看到所有模块的日志记录,但我在Visual Studio测试运行器输出中一无所获。

我也在使用Nunit,我有同样的问题,我在AspNetCore找到了答案。如何从进程内服务器获得日志输出?

我使用了serilog . sink。在内存中,增加了以下内容:

public class InMemoryAPIHosting
{
public WebApplicationFactory<Startup> API { get; set; }
public InMemoryAPIHosting()
{
API = new APIWebApplicationFactory()
.WithWebHostBuilder(builder =>
{
//This allows us to access Serilog entries created while the API is running during integration tests. We can inspect them using InMemorySink.Instance.LogEvents.
builder.UseSerilog((ctx, conf) => conf.WriteTo.InMemory());
});
}
public void Dispose()
{
API.Dispose();
}
}

最后,在我的测试方法中,我创建了一个可以这样调用的方法:

//Helper method that checks the In Memory API logs and writes it to the test output if it finds any
public static void CheckSeriLogEvents(bool throwOnError = false)
{
//After starting up the in memory API, let's review the log items to see if there are any errors. If so, spit them out into the test output.
if (InMemorySink.Instance.LogEvents.Any(x => x.Level == Serilog.Events.LogEventLevel.Error))
{
//There was an error in the logs of the In Memory API! Spit it out.
TestLogger.WriteTestOutput("Error in Memory API. Please review the log data.");
foreach (var logEvent in InMemorySink.Instance.LogEvents.Where(x => x.Level >= Serilog.Events.LogEventLevel.Warning))
{
TestLogger.WriteTestOutput(logEvent.Timestamp + ": " + logEvent.RenderMessage(), false);
}
//End the test immediately with an error, if a throw was requested
if (throwOnError)
{
throw new SerilogInMemoryStartupException("Error in Memory API. Please review the log data. Test aborted.");
}
}
}

最新更新