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.
Berücksichtigen Sie vor dem Codebeispiel die Einschränkungen bei der Verwendung des Docker-Containers ** im Komponententest.
Der Docker-Daemon muss ausgeführt werden -> Natürlich, aber wichtig. Eine weitere Hürde für Fälle, in denen Sie einen Testlauf in einem Container durchführen möchten (?)
Es scheint, dass Sie dies tun können, indem Sie einen Container erstellen, der Docker in Docker ausführen kann (nicht überprüft).
Referenz: Docker in Docker Better Practice
Sie müssen warten, bis der Container startet
Der Container selbst startet schnell, aber es dauert oft einige Sekunden, bis der interne Prozess abgeschlossen ist und ** verfügbar ist.
Mit zunehmender Anzahl von Testfunktionen erhöht sich die Ausführungszeit aller Testfälle erheblich. ――Es ist besser, ein Container-Image zu verwenden, das so leicht wie möglich ist.
** Beobachten Sie die Standardausgabe des Containers und warten Sie, bis er fertig ist **
--pytest: Unit Test --docker: Docker-API-Wrapper - Docker - PyPI
$ pip install docker pytest SQLAlchemy psycopg2-binary
├── main.py
├── models.py
└── tests
├── __init__.py
├── conftest.py
└── test_main.py
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()
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()
$ 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