Dr Schizo
Dr Schizo

Reputation: 4362

Docker compose run tests against container

Is it possible to verify a container (running tests against it) before pushing the image? For example, I have a docker compose which:

builds > runs unit tests > publishes the app

However, I want to also verify the published app and run some out of process tests against it. In a nutshell, I want to run the container and then run dotnet test Example.Api.FullstackTests.

My docker compose file

version: '3'

services:
  api:
    build: .
    ports: 
      - "80:80"
    depends_on:
      - "building"
      - "run-fullstack-tests"
  building:
    build:
      context: .
      dockerfile: Dockerfile.Build
  run-fullstack-tests:
    build:
      context: .
      dockerfile: Dockerfile.FullstackTests

Is this possible to do? Ultimately, I want to verify the running API is correct before pushing it to a registry.

Upvotes: 3

Views: 3343

Answers (2)

djangofan
djangofan

Reputation: 29669

Yes, there is a Docker command that lets you capture exit code when using docker-compose up. https://docs.docker.com/compose/reference/up/

If you started with my basic example project here: https://github.com/djangofan/karate-test-prime-example

Then run it with

docker-compose up --exit-code-from e2e-tests

I think that should do it, right?

Upvotes: 1

David Maze
David Maze

Reputation: 159040

There's different kinds of tests. I tend to think of unit tests as things that only depend on the code base, and ideally the smallest chunks of code within the system, and so you can and should run these on your development system before you build the container. These are tricky to run inside a container, since usually you wouldn't ship this kind of test code with the application, but there's a very tight code-level connection between the code and the tests.

On the other hand, integration tests or system tests tend to answer your final question, "verify the running API is correct", with real or at least test databases. For these you'd often have a separate test driver that contacted your service, made requests, and verified the results. Then you can do what you propose:

docker build -t myimage .
docker run -d --name test -p 12345:8080 myimage
./integration_tests http://localhost:12345
docker stop test
docker rm test
docker push myimage

In this example the service listens on port 8080; we map it to port 12345 on the host; and integration_tests is your test runner that connects to the running service, and we point it at the container. You could wrap many of these steps up in a Docker Compose YAML file, especially if running the container needs a lot of arguments.

Upvotes: 1

Related Questions