[PYTHON] Starten Sie den Docker-Container, wenn Sie Pytest ausführen

Starten Sie den Docker-Container, bevor Sie den Pytest-Test ausführen. Integrationstests mit peripherer Middleware können problemlos durchgeführt werden, und es besteht der Vorteil, dass die Umgebung, Testdaten und Gleichheit erhalten werden können.

Starten Sie beispielsweise den PostgreSQL-Container zum Zeitpunkt der Testausführung und versuchen Sie, Daten einzugeben.

Bemerkungen

Berücksichtigen Sie vor dem Codebeispiel die Einschränkungen bei der Verwendung des Docker-Containers ** im Komponententest.

Bibliothek verwendet

--pytest: Unit Test --docker: Docker-API-Wrapper - Docker - PyPI

$ pip install docker pytest SQLAlchemy psycopg2-binary

Verfassung

├── main.py
├── models.py
└── tests
    ├── __init__.py
    ├── conftest.py
    └── test_main.py

Hauptverarbeitungs- / DB-Modell

models.py


from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()


class Staff(Base):
    __tablename__ = 'staff'
    id = Column(Integer, primary_key=True)
    name = Column(String)

main.py


from sqlalchemy.orm import Session
from models import Staff


def add_staff(engine, name):
    session = Session(bind=engine)
    staff = Staff()
    staff.name = name
    session.add(staff)
    session.commit()

Testcode

Es geht darum, die Engine von SQL Alchemy zu einem Fixpunkt zu machen, damit sie in Testfunktionen verwendet werden kann.

tests/conftest.py


import time
import pytest
import docker
from sqlalchemy import create_engine


@pytest.fixture()
def pg_conf():
    """Verwalten Sie die PostgreSQL-Einstellungen"""
    host = '127.0.0.1'
    port = 5432
    dbname = 'pytest'
    user = 'testuser'
    password = 'test'
    pg_conf = {'host': host,
               'port': port,
               'dbname': dbname,
               'user': user,
               'password': password,
               'url': f'postgresql://{user}:{password}@{host}/{dbname}'}
    return pg_conf


@pytest.fixture()
def engine(pg_conf):
    return create_engine(pg_conf['url'])


@pytest.fixture(autouse=True)
def pg_container(pg_conf):
    """Starten Sie den PostgreSQL-Container"""
    client = docker.from_env()
    container = client.containers.run(image='postgres:11.6-alpine',
                                      tty=True,
                                      detach=True,
                                      auto_remove=True,
                                      environment={'POSTGRES_DB': pg_conf['dbname'],
                                                   'POSTGRES_USER': pg_conf['user'],
                                                   'POSTGRES_PASSWORD': pg_conf['password']},
                                      ports={pg_conf['port']: '5432'})
    #Warten Sie, bis der Behälter fertig ist
    while True:
        log = container.logs(tail=1)
        if 'database system is ready to accept connections' in log.decode():
            break
        time.sleep(0.5)
    yield  #Übergang zum Test hier
    container.kill()

Ich überprüfe die Standardausgabe im Container, aber ein Fehler tritt auf, wenn das Warteintervall zu kurz ist (0,4 Sekunden oder weniger). Es scheint besser, mit ein wenig Anmut eine Wartezeit zu haben.

test_main.py


from sqlalchemy.orm import Session
from models import Base, Staff
from main import add_staff


def test_add(engine):
    #1 Datensatz hinzufügen
    Base.metadata.create_all(bind=engine)  #Tabelle erstellen
    add_staff(engine=engine,
              name='alice')
    #Überprüfen Sie den hinzugefügten Datensatz
    session = Session(bind=engine)
    assert session.query(Staff.id).filter_by(name='alice').first() == (1,)
    session.close()

Ausführungsergebnis

$ pytest --setup-show tests/ -v -s
========================================= test session starts =========================================platform linux -- Python 3.8.1, pytest-5.3.3, py-1.8.1, pluggy-0.13.1 -- /home/skokado/.local/share/virtualenvs/sandbox-pTebjwBw/bin/python3.8
cachedir: .pytest_cache
rootdir: ***
collected 1 item

tests/test_pg.py::test_add
        SETUP    F pg_conf
        SETUP    F pg_container (fixtures used: pg_conf)
        SETUP    F engine (fixtures used: pg_conf)
        tests/test_main.py::test_add (fixtures used: engine, pg_conf, pg_container)PASSED
        TEARDOWN F engine
        TEARDOWN F pg_container
        TEARDOWN F pg_conf

========================================== 1 passed in 2.00s ==========================================

Recommended Posts

Starten Sie den Docker-Container, wenn Sie Pytest ausführen
Geben Sie in stdin den laufenden Docker-Container ein
Lösung für unzugänglichen Gin-Server, der auf dem Docker-Container ausgeführt wird
Tragen Sie einen Docker-Container
Überprüfen Sie, ob der Docker-Container keine Verbindung zum Internet herstellt
Geben Sie Optionen an, wenn Sie Python ausführen
Der japanische Dateiname wird beim Festlegen der LANG-Umgebungsvariablen beim Ausführen des Java-Programms auf dem Docker-Container verstümmelt
Tkinter canvas (Fenster) startet nicht, wenn Python 3.7.4 unter Atom ausgeführt wird