Skip to content

feat: Require explicit container image in Testcontainers.Xunit#1612

Merged
HofmeisterAn merged 3 commits intotestcontainers:developfrom
0xced:feature/Testcontainers.Xunit-explicit-builder
Dec 31, 2025
Merged

feat: Require explicit container image in Testcontainers.Xunit#1612
HofmeisterAn merged 3 commits intotestcontainers:developfrom
0xced:feature/Testcontainers.Xunit-explicit-builder

Conversation

@0xced
Copy link
Contributor

@0xced 0xced commented Dec 30, 2025

What does this PR do?

This pull request introduce a new parameterless Configure() method on the ContainerLifetime class, hence also on the derived (Db)ContainerFixture and (Db)ContainerTest classes.

It also makes the TBuilderEntity Configure(TBuilderEntity builder) method obsolete.

Why is it important?

This matches the changes discussed in #1540 and introduced in #1584.

Related issues

This is a follow-up to #1584. Closes #1598.

/cc @digital88

How to test this PR

All relevant tests have been adapted to use the new parameterless Configure() method.

Follow-ups

When the parameterless constructors (now obsolete) are eventually removed from the builders, the following changes will need to be performed.

  1. Remove the new() constraint on ContainerLifetime, ContainerFixture, ContainerTest, DbContainerFixture and DbContainerTest
  2. Make the ContainerFixture class abstract
  3. Change protected virtual TBuilderEntity Configure() => new(); to protected abstract TBuilderEntity Configure(); on ContainerLifetime, forcing consumers to provide the image name/tag when creating builders.
  4. Delete the obsolete methods: protected virtual TBuilderEntity Configure(TBuilderEntity builder)

Summary by CodeRabbit

  • Refactor

    • Standardized container configuration to a parameterless builder initialization across fixtures, simplifying how builders are created and extended.
  • Bug Fixes

    • Updated derived fixtures to obtain base configuration before applying additional options (e.g., wait strategies, credentials).
  • Documentation

    • Added XML docs and examples for the new configuration extension point and marked the old overload as deprecated.

✏️ Tip: You can customize this high-level summary in your review settings.

Follow-up to testcontainers#1584

When the parameterless constructors are actually removed
1. Remove the `new()` constraint on ContainerLifetime, ContainerFixture, ContainerTest, DbContainerFixture and DbContainerTest
2. Make ContainerFixture abstract
3. Change `protected virtual TBuilderEntity Configure() => new();` to `protected abstract TBuilderEntity Configure();` on ContainerLifetime
4. Delete the obsolete methods: `protected virtual TBuilderEntity Configure(TBuilderEntity builder)`
@netlify
Copy link

netlify bot commented Dec 30, 2025

Deploy Preview for testcontainers-dotnet ready!

Name Link
🔨 Latest commit 416c6da
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-dotnet/deploys/6954fe78601e770008401d57
😎 Deploy Preview https://deploy-preview-1612--testcontainers-dotnet.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Dec 30, 2025

Walkthrough

Parameterless Configure() was introduced on the container lifetime base class and many test fixtures were converted from Configure(TBuilder builder) to Configure(); the old Configure(TBuilder) was marked [Obsolete]. Fixtures now construct or obtain builders directly and chain additional configuration via base.Configure().

Changes

Cohort / File(s) Summary
Core API
src/Testcontainers.Xunit/ContainerLifetime.cs, src/Testcontainers.Xunit/ContainerTest.cs
Added protected virtual TBuilderEntity Configure() that returns a new builder; marked protected virtual TBuilderEntity Configure(TBuilderEntity builder) as [Obsolete]; adjusted initialization to apply logger after obtaining builder.
Database Fixtures
tests/Testcontainers.Cassandra.Tests/CassandraContainerTest.cs, tests/Testcontainers.ClickHouse.Tests/ClickHouseContainerTest.cs, tests/Testcontainers.CockroachDb.Tests/CockroachDbContainerTest.cs, tests/Testcontainers.Db2.Tests/Db2ContainerTest.cs, tests/Testcontainers.MariaDb.Tests/MariaDbContainerTest.cs, tests/Testcontainers.MsSql.Tests/MsSqlContainerTest.cs, tests/Testcontainers.PostgreSql.Tests/PostgreSqlContainerTest.cs, tests/Testcontainers.Xunit.Tests/PostgreSqlContainer.cs
Replaced Configure(builder) overrides with parameterless Configure() that returns a new builder (often new Builder(TestSession.GetImageFromDockerfile())); wait-for-database variants now call base.Configure().WithWaitStrategy(...).
Multi-Stage / Variant DB Fixtures
tests/Testcontainers.FirebirdSql.Tests/FirebirdSqlContainerTest.cs, tests/Testcontainers.MySql.Tests/MySqlContainerTest.cs
Converted stage-specific and variant fixtures to parameterless Configure() returning new builders or delegating to base.Configure() then applying stage-specific options (credentials, wait strategies, stages).
Oracle Fixtures
tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs
Changed OracleFixture constructor to accept string version (was int? version); converted Configure(OracleBuilder) to parameterless Configure() and simplified builder creation to always use new OracleBuilder(image) with optional database chaining; updated derived fixtures to pass string literals for edition/version.
Message Broker Fixtures
tests/Testcontainers.Mosquitto.Tests/MosquittoContainerTest.cs
Added protected override MosquittoBuilder Configure() in base test; refactored subclasses to parameterless Configure() and to use base.Configure().WithCertificate(...) where applicable; removed some builder-parameter overrides.
Cache Fixtures
tests/Testcontainers.Xunit.Tests/RedisContainerTest\1.cs, tests/Testcontainers.Xunit.Tests/RedisContainerTest`2.cs`
Replaced Configure(RedisBuilder builder) with parameterless Configure() returning new RedisBuilder("redis:7.0").
Misc Test Fixtures
tests/Testcontainers.Mosquitto.Tests/..., tests/* (many test files)
Numerous fixtures updated to the new parameterless Configure() pattern; overall pattern change from mutating an injected builder to returning/deriving a builder instance and applying additional options via base.Configure() chaining.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • feat: Add Mosquitto module #1522: Deprecates Configure(TBuilderEntity) in favor of parameterless Configure() and updates tests (includes Mosquitto-related changes).

Suggested labels

enhancement

Suggested reviewers

  • HofmeisterAn

Poem

🐰 The builder hops to start anew,

Fresh Configure springs into view—
Old methods nap with gentle sigh,
New paths leap onwards, bright and spry. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: introducing a requirement for explicit container images in the Testcontainers.Xunit library by refactoring the Configure method pattern.
Description check ✅ Passed The PR description covers all required sections from the template: What does this PR do, Why is it important, Related issues, How to test, and Follow-ups with actionable next steps.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 518814e and 416c6da.

📒 Files selected for processing (2)
  • tests/Testcontainers.Cassandra.Tests/CassandraContainerTest.cs
  • tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: diegosasw
Repo: testcontainers/testcontainers-dotnet PR: 1583
File: src/Testcontainers.KurrentDb/Testcontainers.KurrentDb.csproj:7-7
Timestamp: 2025-11-17T17:58:43.958Z
Learning: In the testcontainers-dotnet repository, JetBrains.Annotations should use version 2023.3.0 to maintain consistency with the main Testcontainers csproj, rather than always using the latest available version.
Learnt from: HofmeisterAn
Repo: testcontainers/testcontainers-dotnet PR: 1509
File: tests/Testcontainers.Grafana.Tests/GrafanaContainerTest.cs:45-46
Timestamp: 2025-11-08T09:04:00.045Z
Learning: In xUnit.net test methods in the testcontainers-dotnet project, ConfigureAwait(true) is recommended and correct to use, as it ensures proper synchronization context capture for xUnit's test parallelism management. Do not suggest changing ConfigureAwait(true) to ConfigureAwait(false) in test methods.
📚 Learning: 2025-11-17T17:58:43.958Z
Learnt from: diegosasw
Repo: testcontainers/testcontainers-dotnet PR: 1583
File: src/Testcontainers.KurrentDb/Testcontainers.KurrentDb.csproj:7-7
Timestamp: 2025-11-17T17:58:43.958Z
Learning: In the testcontainers-dotnet repository, JetBrains.Annotations should use version 2023.3.0 to maintain consistency with the main Testcontainers csproj, rather than always using the latest available version.

Applied to files:

  • tests/Testcontainers.Cassandra.Tests/CassandraContainerTest.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: ci (Testcontainers.CockroachDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Db2, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.FirebirdSql, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.Cassandra, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.MariaDb, ubuntu-24.04)
  • GitHub Check: ci (Testcontainers.ClickHouse, ubuntu-24.04)
  • GitHub Check: analyze (csharp)
🔇 Additional comments (5)
tests/Testcontainers.Cassandra.Tests/CassandraContainerTest.cs (2)

63-64: LGTM! Clean implementation of parameterless Configure().

The new parameterless pattern is cleaner and more explicit than the previous approach. Constructing a fresh CassandraBuilder with an explicit image from TestSession.GetImageFromDockerfile() aligns perfectly with the PR's goal of requiring explicit container images.


74-75: LGTM! Proper inheritance and configuration chaining.

Calling base.Configure() to obtain the configured builder and then chaining WithWaitStrategy() is the correct approach. This maintains the explicit image configuration from the parent while cleanly extending it with additional wait behavior.

tests/Testcontainers.Oracle.Tests/OracleContainerTest.cs (3)

35-36: LGTM! Parameter type change aligns with explicit image requirement.

The change from int? version to string version enables flexible version specification and is consistent with the PR objective to require explicit container images. All fixture instantiations have been correctly updated to pass string literals.


39-43: Excellent implementation of explicit image configuration.

The parameterless Configure() now explicitly creates an OracleBuilder with the image name, directly addressing the previous review comment. The image format gvenzl/oracle-{edition}:{version}-slim-faststart is correctly constructed from constructor parameters, and the conditional logic cleanly handles optional database configuration.


53-86: All fixture instantiations correctly updated.

All fixture classes have been consistently updated to pass string version literals. The version strings ("21.3.0", "11", "18", "21", "23") match expected Oracle version formats, and the distinction between "xe" and "free" editions for different versions is correctly maintained.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Collaborator

@HofmeisterAn HofmeisterAn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a few small things to fix before we can merge it.

Copy link
Collaborator

@HofmeisterAn HofmeisterAn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@HofmeisterAn HofmeisterAn added the enhancement New feature or request label Dec 31, 2025
@HofmeisterAn HofmeisterAn merged commit e98d679 into testcontainers:develop Dec 31, 2025
28 checks passed
@0xced 0xced deleted the feature/Testcontainers.Xunit-explicit-builder branch December 31, 2025 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement]: Refactor Testcontainers.Xunit module

2 participants