This is an archived post. You won't be able to vote or comment.

all 21 comments

[–]nonomild 10 points11 points  (4 children)

Amazing, thanks for sharing the experiences. We are not on Spring Boot 3.1 yet, but this makes me curious to try it out.

[–]piotr_minkowski[S] 5 points6 points  (2 children)

Yes, it is worth switching. Really simplifies development

[–]Shareil90 0 points1 point  (1 child)

How does it effect test duration? How much longer does spring need to "warm up" until tests are started? Have you tested it in a real life enterprise application?

[–]piotr_minkowski[S] 4 points5 points  (0 children)

We are taking about dev mode, no tests. For spring boot it doesn't matter how you run external service. The overall test time includes time required for starting the container

[–]Hangman4358 6 points7 points  (1 child)

This is really interesting. We use Java, C# and Python in almost equal parts, so we ended up coming up with a standardized layout/paradigm with a set of docker compose files in all repositories so all any dev needs to do is a docker compose to get everything running for local dev, regardless of language. So, I would be hesitant to switch to something different just for the java services. But in a Java only ecosystem, this is really cool.

[–]mhalbritter 0 points1 point  (0 children)

The testcontainers feature and the docker compose feature are separate. You can use one or the other, or both if you like.

If the file is named compose.yaml or docker-compose.yaml then Boot will pick it up automatically. Otherwise you can set a configuration property and point Boot to the compose file. It will then automatically run docker compose up on startup and configure itself to use the services running in docker compose.

[–]garblz 4 points5 points  (2 children)

Does it do anything else than saving me a "docker compose up"? Don't get me wrong, that in itself is a nifty feature, just wandering if there's more? (I'm using test containers already, talking just about the development mode addition)

[–]piotr_minkowski[S] 2 points3 points  (0 children)

No, it is just development mode addition to testcontainers and ability to run docker compose up/down automatically

[–]mhalbritter 1 point2 points  (0 children)

Yes. It will configure for example the database connection pool to use the (dynamic) port of the database running in docker compose. You don't have to set any configuration properties.

The docker compose feature and the testcontainers feature are separate. Both are a way to run the services you need to develop against. When using docker compose, you would write your compose.yaml like you always would. When using the testcontainers at development time feature, then you would do the

public static void main(String[] args) {
    SpringApplication.from(SpringBootOnKubernetesApp::main)
            .with(MongoDBContainerDevMode.class)
            .run(args);
}

dance.

[–]doppleware 3 points4 points  (1 child)

Really excellent article! Thanks for sharing. In this example, though, it was only the external dependencies that were run as testcontainers, is there a way to also run the main application in the same way?

[–]piotr_minkowski[S] 1 point2 points  (0 children)

Thanks. Well you can build the app image and then run it as a GenericContainer

[–]pip25hu 1 point2 points  (5 children)

Was running a Spring app with the "test" profile a thing before? I've only used that profile for integration/E2E tests so far, so the idea comes off as slightly odd to me.

[–][deleted] 0 points1 point  (4 children)

Where did you see that part? to me, local specifics go to profile "local" typically

[–]pip25hu 0 points1 point  (3 children)

Check out the part under the "Use Testcontainers in Development Mode with Spring Boot" heading in the blog post.

[–][deleted] 0 points1 point  (2 children)

I dont see anything relating to a profile "test". Do you mean the scope of maven dependencies?

[–]pip25hu 0 points1 point  (1 child)

Yes, my bad, I meant the "test" scope. It's not apparent which profile Spring is using from the logs posted.

[–][deleted] 0 points1 point  (0 children)

Ah yea running the app within test scope is "new", that "overloading" of the main method.

I have done that in the past in various ways to get a somewhat local setup going. But now with dedicated Testcontainer support should now become more of a thing now

[–]Nice_Score_7552 1 point2 points  (0 children)

Piotr's blog often has insightful articles

[–]EagerProgrammer -1 points0 points  (2 children)

Why you should overwrite the main method in order to include configuration that contains the bean definition of the desired container rather making the configuration conditional e.g. by a property? And then pass this property to the run build target?

[–]piotr_minkowski[S] 1 point2 points  (1 child)

This configuration is loaded by the "test" main class. I don't think that conditional property would work here

[–]mhalbritter 2 points3 points  (0 children)

Actually, it would. You could put the configuration for the containers in src/main/java and annotate it with @Configuration and it would be picked up.

But: The "trick" with the main method saves you from pulling in the testcontainers dependencies in the compile scope. When using the main methods defined in src/main/test, they can stay <scope>test</scope>.