-
-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Enhancement]: ILogger should be injected into all AbstractBuilder subclasses #996
Comments
I agree that the current logging approach is far from perfect, and I am not very happy with it either, especially given the situation with VSTest. I haven't had a chance to review your implementation yet; however, I will take a look at it in the next days. I just wanted to share my initial thoughts, as I hadn't digged into the details yet. I've been thinking of developing an xUnit.net module that integrates Testcontainers into the xUnit.net test framework upon assembly load or through a similar mechanism. A dedicated xUnit.net module could also be useful for incorporating additional features, such as leveraging Testcontainers with annotations, into tests. |
What about extending the abstract builder and adding a member for setting the So far, so good. However, I'm still uncertain about when we should log the information regarding the container runtime. Currently, my idea is to log it each time the logger changes (this would support xUnit.net's grouped output). Unfortunately, this approach doesn't work seamlessly with xUnit.net's shared context, such as class fixtures, etc. These contexts do not have access to I still think that a module that leverages the test framework API and integrates with its logging mechanism is something worth to dig into. Perhaps we come up with a solution that works right out of the box (without additional configuration). |
Just after filing this issue I realized that this may be a better approach. And indeed it is! My ILoggerBuilder branch looks better than the ILogger injection approach in my opinion. Note that I still had to touch all containers to remove the For the PostgreSQL container, this change looks like this: diff --git a/src/Testcontainers.PostgreSql/PostgreSqlBuilder.cs b/src/Testcontainers.PostgreSql/PostgreSqlBuilder.cs
index fc7e5be..a3650de 100644
--- a/src/Testcontainers.PostgreSql/PostgreSqlBuilder.cs
+++ b/src/Testcontainers.PostgreSql/PostgreSqlBuilder.cs
@@ -73,7 +73,7 @@ public sealed class PostgreSqlBuilder : ContainerBuilder<PostgreSqlBuilder, Post
public override PostgreSqlContainer Build()
{
Validate();
- return new PostgreSqlContainer(DockerResourceConfiguration, TestcontainersSettings.Logger);
+ return new PostgreSqlContainer(DockerResourceConfiguration);
}
/// <inheritdoc />
diff --git a/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs b/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs
index 3ac4844..2535fba 100644
--- a/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs
+++ b/src/Testcontainers.PostgreSql/PostgreSqlContainer.cs
@@ -10,9 +10,8 @@ public sealed class PostgreSqlContainer : DockerContainer
/// Initializes a new instance of the <see cref="PostgreSqlContainer" /> class.
/// </summary>
/// <param name="configuration">The container configuration.</param>
- /// <param name="logger">The logger.</param>
- public PostgreSqlContainer(PostgreSqlConfiguration configuration, ILogger logger)
- : base(configuration, logger)
+ public PostgreSqlContainer(PostgreSqlConfiguration configuration)
+ : base(configuration)
{
_configuration = configuration;
}
That was the hardest part. I tried several places and was not satisfied (or it just plain did not work). In the end I chose to log the runtime information at the very beginning of
I'm well aware of this but there's no other way around for xUnit. For this purpose I prototyped a new |
If we cannot find a better solution, we can continue in this direction. However, it requires a more effective approach to log container runtime information. Generally, the current approach works well for all other testing frameworks; it's mostly xUnit.net that's causing issues. I also attempted using events like this: ConsoleLogger.Instance.MessageLogged += (_, message) => testOutputHelper.WriteLine(message); But that approach didn't work well either. In general, I've been considering using xUnit.net's I've noticed that xUnit 3 has introduced some significant changes. The TestContext looks promising. Perhaps we should get in touch with Brad and seek his guidance. He likely has more knowledge about it and can point us in the right direction. It's a bit of an unusual case because Testcontainer sits between the test framework and the test itself. |
Do you mean that you don't like logging at the very beginning of
I think I nailed the Testcontainers/xUnit integration in my Testcontainers.Xunit branch (which sits on top of my ILoggerBuilder branch). Excerpt of the public class ContainerFixture<TBuilderEntity, TContainerEntity> : IAsyncLifetime
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity>, new()
where TContainerEntity : IContainer
{
private readonly TBuilderEntity _builder;
public ContainerFixture(IMessageSink messageSink)
{
_builder = new TBuilderEntity().WithLogger(new MessageSinkLogger(messageSink));
}
// ...
} public abstract class ContainerTest<TBuilderEntity, TContainerEntity> : IAsyncLifetime
where TBuilderEntity : IContainerBuilder<TBuilderEntity, TContainerEntity>, new()
where TContainerEntity : IContainer
{
protected ContainerTest(ITestOutputHelper testOutputHelper, Func<TBuilderEntity, TBuilderEntity> configure = null)
{
var builder = new TBuilderEntity().WithLogger(new TestOutputLogger(testOutputHelper));
Container = configure == null ? builder.Build() : configure(builder).Build();
}
// ...
} By having the logger configurable through the new Does that make sense? |
Yeah, kind of. That one is difficult... For the We also need to keep the other builders and resources in mind.
I do not want to make it more complex (it is already complex enough). I just want to collect all valid cases to think about the best implementation and to evaluate pros and cons (or cases we do not support at all).
Thanks again for your efforts. Much appreciated. I will look at the changes and the proposal by the weekend at the latest. Edit: Sorry, I haven't had the time yet. I hope I'll be able to look at it by the end of this week. I haven't forgotten it. |
I was playing around with xUnit.net's diagnostic messages in another project and felt very unsatisfied. Getting the output properly in Rider requires even more individual configurations (BTW, I stumbled across your JB ticket too). As mentioned earlier, I think it makes total sense to extend the builders and allow configuring the used logger instances through the builder. That is definitely something we should offer. I need to test a few different configurations, but as also mentioned, |
I will add the |
I just rebased my ILoggerBuilder branch on |
…ders This will enable a seamless integration with xUnit.net (both ITestOutputHelper and IMessageSink) Fixes testcontainers#996
…ders This will enable a seamless integration with xUnit.net (both ITestOutputHelper and IMessageSink) Fixes testcontainers#996
…ders This will enable a seamless integration with xUnit.net (both ITestOutputHelper and IMessageSink) Fixes testcontainers#996
…ders This will enable a seamless integration with xUnit.net (both ITestOutputHelper and IMessageSink) Fixes testcontainers#996
…ders This will enable a seamless integration with xUnit.net (both ITestOutputHelper and IMessageSink) Fixes testcontainers#996
…ders This will enable a seamless integration with xUnit.net (both ITestOutputHelper and IMessageSink) Fixes testcontainers#996
Problem
Shipping a default console logger that works with any .NET test framework has been dismissed as impossible to do by VSTest engineers in microsoft/vstest#4125. Yet we'd still want to collect logs in xUnit.net.
Solution
Injecting an
ILogger
into all AbstractBuilder subclasses would allow to pass a logger implementation that writes logs to xUnit's ITestOutputHelper. I have started prototyping this in my ILoggerInjection branch but it's far from complete.I'm not familiar enough with other testing frameworks but I hope they have a similar solution to xUnit's ITestOutputHelper. I think that NUnit captures the console output so it might already work with the current ConsoleLogger implementation.
Benefit
The Testcontainers logs can be captured when running unit tests in xUnit.net.
Here's the output when running
dotnet test --logger "console;verbosity=detailed"
for Testcontainers.PostgreSql.Tests (still in my ILoggerInjection branch)Alternatives
No other alternatives were considered to solve this issue.
Would you like to help contributing this enhancement?
Yes
The text was updated successfully, but these errors were encountered: