Skip to content

Add Testcontainers 1.x to 2.x migration rules#21

Merged
rpalcolea merged 6 commits intomainfrom
testcontainers-rules
Dec 10, 2025
Merged

Add Testcontainers 1.x to 2.x migration rules#21
rpalcolea merged 6 commits intomainfrom
testcontainers-rules

Conversation

@rpalcolea
Copy link
Member

This PR adds architecture rules to help teams migrate from Testcontainers 1.x to 2.x by detecting breaking changes before upgrading and deprecated patterns after upgrading.

Testcontainers 2.x introduced several breaking changes that will cause compilation errors:

  • DockerComposeContainer renamed to ComposeContainer
  • getContainerIpAddress() replaced with getHost()
  • No-argument constructors removed (must specify explicit image versions)
  • Container classes moved to module-specific packages

What's Added

Pre-Upgrade Rules (Testcontainers1xRule)

Run these before upgrading to find patterns that will break:

  1. dockerComposeContainerRule (MEDIUM) - Detects DockerComposeContainer usage

    // Before
    DockerComposeContainer container = ...
    
    // After
    ComposeContainer container = ...
  2. containerIpAddressMethodRule (MEDIUM) - Detects getContainerIpAddress() calls

    // Before
    String ip = container.getContainerIpAddress();
    
    // After
    String host = container.getHost();
  3. noArgConstructorRule (MEDIUM) - Detects no-arg constructors

    // Before (breaks in 2.x)
    new PostgreSQLContainer()
    
    // After (works in both, more reproducible)
    new PostgreSQLContainer(DockerImageName.parse("postgres:16-alpine"))

Post-Upgrade Rules (Testcontainers2xRule)

Run these after upgrading to clean up deprecated patterns:

  1. legacyContainerPackageRule (LOW) - Detects deprecated package imports
    // Before (deprecated in 2.x)
    import org.testcontainers.containers.PostgreSQLContainer;
    
    // After (canonical in 2.x)
    import org.testcontainers.postgresql.PostgreSQLContainer;

Big remaining question

Should this be in the testing-frameworks module? or in a new one?

}

try {
Class.forName(newPackageName + "." + simpleName);
Copy link
Member

Choose a reason for hiding this comment

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

I dont think this is safe because the classpath where we evaluate rules is not the same as the runtime classpath of the code we are checking

Copy link
Member Author

Choose a reason for hiding this comment

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

addressed this by detecting if the container class is deprecated or not

@rpalcolea rpalcolea requested a review from wakingrufus December 9, 2025 19:40
*/
private static final Map<String, String> OVERRIDES = new HashMap<>();

static {
Copy link
Member

Choose a reason for hiding this comment

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

instead of static, I think ideally this should be a lazy singleton, just to prevent running this when the rule is not selected

Copy link
Member Author

Choose a reason for hiding this comment

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

good eye. 67678c5 takes care of it

…der to avoid loading things one very execution even when the rule is not used
}

// Test classes using 1.x patterns
@SuppressWarnings("unused")
Copy link
Contributor

Choose a reason for hiding this comment

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

I like the SuppressWarnings! (we should add it to the other test cases)

@rpalcolea rpalcolea merged commit f7a03ff into main Dec 10, 2025
3 checks passed
@rpalcolea rpalcolea deleted the testcontainers-rules branch December 10, 2025 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants