Package: penguins-pytest-docker
Create simplePytestfixtures for writing integration tests based on Docker
containers. The framework provides a service class to start and stop containers
based Docker Compose. Each single container can be started individually.Some parts of this package are taken fromhttps://github.com/AndreLouisCaron/pytest-dockerUsage with PytestThe docker compose file should contain all desired containers and the ports
should be exposed. In the following example we want to start the app to test
and a SQL database (Crate). Let’s assume there is aDockerfilefor the app
in the same folder as the docker compose file:version: "3"
services:
  app:
    build: .
    ports:
      - "8080"
    depends_on:
      - "crate"

  crate:
    image: crate:latest
    ports:
      - "4200"In theconftest.pyfile we can declare the docker fixtures for each service
we want to be able to start in the tests:import pytest

@pytest.fixture(scope='session')
def docker_app(docker_services):
    docker_services.start('app')
    public_port = docker_services.wait_for_service("app", 8080)
    url = "http://{docker_services.docker_ip}:{public_port}".format(**locals())
    return url

@pytest.fixture(scope='session')
def docker_crate(docker_services):
    docker_services.start('crate')
    public_port = docker_services.wait_for_service("crate", 4200)
    dsn = "{docker_services.docker_ip}:{public_port}".format(**locals())
    return dsnBy default the fixture will look for thedocker-compose.ymlfile in thetestssubfolder of the path wherepytest.iniresides (or the project’s
root directory if no ini file is given - as in the tests example). In many
cases you will want to override the location for the docker compose files. Just
overwrite thedocker_compose_filesfixture in yourconftest.pyfile:@pytest.fixture(scope='session')
def docker_compose_files(pytestconfig):
    """Get the docker-compose.yml absolute path.
    Override this fixture in your tests if you need a custom location.
    """
    return [
        project_path('docker', 'docker-compose.yml'),
    ]In your test file declare the fixtures you want to use:def test_something(docker_app, docker_crate):
    # e.g. initialize database
    ...
    # test something (e.g. request to docker_app)
    ...A working configuration and test example can be found in thetestsfolder
of this package.Execution in Docker ContainerIt’s possible to execute a command inside one of the Docker containers. Use
theexecmethod of thedocker_servicesfixture:def test_exec(docker_services):
    # the first argument is the service name of the compose file,
    # the following arguments build the command to run
    res = docker_services.exec('crate', 'ls', '-a')Wait for ServiceThewait_for_servicemethod of the service module checks whether the
docker service is really started. By default it makes a HTTP GET request to the
server’s/endpoint. The service will retry to check until a timeout of
30 seconds has passed.Custom Service CheckerSome services may work differently and require a custom checker.Create a custom service checker function which receives the IP address and the
port as parameters:def custom_service_checker(ip_address, port):
    # if service is ready
    return True
    # otherwise return FalseIn the fixture provide the custom service checker function ascheck_serviceparameter to thewait_for_servicemethod:@pytest.fixture(scope='session')
def docker_custom_service(docker_services):
    docker_services.start('custom_service')
    public_port = docker_services.wait_for_service(
        "app",
        8080,
        check_service=custom_service_checker
    )
    url = "http://{docker_services.docker_ip}:{public_port}".format(**locals())
    return urlRun TestsTests are held in thetestsdirectory. Running tests is done via the
pytest package with:./gradlew pytest