[PYTHON] Démarrez le conteneur Docker lors de l'exécution de Pytest

Envisagez de démarrer le conteneur Docker avant d'exécuter le test Pytest. Les tests d'intégration avec les middlewares périphériques peuvent être facilement exécutés, et il y a un avantage que l'environnement, les données de test et l'égalité peuvent être obtenus.

Par exemple, démarrez le conteneur PostgreSQL au moment de l'exécution du test et essayez d'entrer des données.

Remarques

Avant l'exemple de code, considérez les restrictions d'utilisation du conteneur Docker ** dans le test unitaire.

--Le démon Docker doit être en cours d'exécution
-> Naturellement, mais important. Un obstacle de plus pour les cas où vous souhaitez effectuer un test dans un conteneur (?) --Il semble que vous puissiez le faire en créant un conteneur qui peut faire Docker dans Docker (non vérifié).

Bibliothèque utilisée

--pytest: test unitaire --docker: wrapper d'API Docker - docker --PyPI

$ pip install docker pytest SQLAlchemy psycopg2-binary

Constitution

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

Traitement principal / modèle DB

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()

Code de test

Le but est de faire du moteur de SQL Alchemy un accessoire pour qu'il puisse être utilisé dans les fonctions de test.

tests/conftest.py


import time
import pytest
import docker
from sqlalchemy import create_engine


@pytest.fixture()
def pg_conf():
    """Gérer les paramètres PostgreSQL"""
    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):
    """Démarrez le conteneur PostgreSQL"""
    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'})
    #Attendez que le conteneur soit prêt
    while True:
        log = container.logs(tail=1)
        if 'database system is ready to accept connections' in log.decode():
            break
        time.sleep(0.5)
    yield  #Transition à tester ici
    container.kill()

Je vérifie la sortie standard dans le conteneur, mais une erreur se produit lorsque l'intervalle d'attente est trop court (0,4 seconde ou moins). Il semble préférable d'avoir un temps d'attente avec un peu de grâce.

test_main.py


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


def test_add(engine):
    #Ajouter 1 enregistrement
    Base.metadata.create_all(bind=engine)  #Créer une table
    add_staff(engine=engine,
              name='alice')
    #Vérifiez l'enregistrement ajouté
    session = Session(bind=engine)
    assert session.query(Staff.id).filter_by(name='alice').first() == (1,)
    session.close()

Résultat d'exécution

$ 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

Démarrez le conteneur Docker lors de l'exécution de Pytest
Entrez dans stdin du conteneur Docker en cours d'exécution
Solution pour le serveur Gin inaccessible fonctionnant sur le conteneur Docker
Transportez un conteneur Docker
Vérifier quand le conteneur Docker ne se connecte pas à Internet
Spécifiez les options lors de l'exécution de python
Le nom de fichier japonais est déformé lors de la définition de la variable d'environnement LANG lors de l'exécution du programme Java sur le conteneur Docker
Tkinter canvas (fenêtre) ne démarre pas lors de l'exécution de Python 3.7.4 sur Atom