[PYTHON] Beispiel einer Pytest-Umgebung zum Reparieren der Datenbank mit Docker

Zweck

Ich möchte einfach einen Komponententest einer Python-Anwendung mithilfe einer Datenbank mit pytest ausführen, ohne von der Umgebung beeinflusst zu werden. (Diejenigen, die als Daemon anstelle von Dateien wie SQLite3 gestartet werden)

Was wurde gemacht

Beispielcode: https://github.com/hkato/pytest-docker-mysql-example

Starten Sie MySQL von pytest auf Docker, geben Sie das Schema und die Testdaten ein und führen Sie den Test aus. Wenn Sie Docker-Compose festlegen und SQL in Bezug auf Docker-Entrypoint-Initdb.d unterstützen, sollte dies für andere Datenbanken wie PostgreSQL grundsätzlich identisch sein. (Der Initialisierungsmechanismus in docker-entrypoint-initdb.d sollte für offizielle MySQL / PostgreSQL-Container identisch sein, aber ich weiß nichts anderes.)

Erforderliche Umgebung und Pytest-Plugin

In Bezug auf pytest habe ich Docker gestartet und mir das Plug-In angesehen, das die Datenbank verwaltet, aber pytest-docker ist der Wartungsstatus und meine Nutzung / Umgebung Sieht gut aus für. pytest-dotenv wurde von Docker und pytest verwendet, um Umgebungsvariablen in ENV-Dateien zu beschreiben und sie gemeinsam zu machen.

Andere Überlegungen

Als Ergebnis einer anderen Überlegung als Pytest-Docker

Immerhin scheint pytest-docker das Beste zu sein, da es den Container der Webanwendung wie im offiziellen Dokument beschrieben verwenden kann und unabhängig von der Datenbank für allgemeine Zwecke verwendet werden kann ([MinIO-Container starten und AWS S3 ersetzen](https :: //qiita.com/hkato/items/89e436300c50c46624b9) Ich denke auch darüber nach.

Verzeichnisaufbau

.
├── src                 #Anwendungscode
│   └── *.py
├── tests               #Testcode
│   ├── conftest.py
│   └── test_*.py
├── initdb.d            #Datenbankschema & Testdaten usw.
│   ├── *.sql
│   └── *.sh
├── pytest.ini          #pytest Einstellungen
├── .env                #Einstellungen für Umgebungsvariablen
└── docker-compose.yml  #Docker-Einstellungen

Codeübersicht

conftest.py

Unterstützung für die Platzierung von docker-compose.yml

Standardmäßig verweist pytest-docker unter "tests /" auf "docker-compose.yml". Wenn Sie es direkt unter dem Projekt festlegen (geben Sie im Beispiel in README.md von pytest-docker ein anderes Verzeichnis oder einen anderen Dateinamen an), führen Sie bei Webanwendungen usw. die Datenbank mit "docker-compose up -d" aus Sie können einen Web-App-Server mit Gunicorn, uWSGI, Uvicorn usw. ausführen und debuggen (ich schließe dies aus, da dies nicht die Essenz dieser Zeit ist).

Unterstützt das Warten auf den Start von MySQL

In der pytest-docker-Dokumentation wird es als Beispiel beschrieben, das einen httpbin REST-API-Container startet und auf 200 Antworten von Port 80 wartet. Im Fall von MySQL wurde entschieden, dass die Verbindung mit PyMySQL wie unten gezeigt hergestellt wurde und keine Ausnahme zurückgegeben wurde, dh der Docker-Container wurde gestartet und die anfänglichen Daten wurden eingegeben.

def is_database_ready(docker_ip):
    try:
        pymysql.connect(
            host=docker_ip,
            user=os.getenv('MYSQL_USER', ''),
            password=os.getenv('MYSQL_PASSWORD', ''),
            db=os.getenv('MYSQL_DATABASE')
        )
        return True
    except:
        return False

Warten Sie mit einem Timeout von 30 Sekunden in einem Zyklus von 0,1 Sekunden auf das oben Gesagte.

@pytest.fixture(scope="session")
def database_service(docker_ip, docker_services):
    docker_services.wait_until_responsive(
        timeout=30.0, pause=0.1, check=lambda: is_database_ready(docker_ip)
    )
    return

Ausführungsergebnis

Grundeinstellung der Python-Umgebung

$ #Im tatsächlichen Betrieb ist es möglicherweise besser, Pipenv oder Poetry für die Testumgebung und die Ausführungsumgebung zu verwenden.
$ python -m venv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt

Einstellungen für Umgebungsvariablen

$ cat << 'EOF' > .env
MYSQL_ROOT_PASSWORD='p@ssw0rd'
MYSQL_DATABASE='mydb'
MYSQL_USER='foo'
MYSQL_PASSWORD='pa$$Word'
EOF

Wenn der Test ausgeführt wird, wird der Docker-Container von Fixture gestartet, und der eigentliche Komponententest wird ausgeführt, nachdem SQL- und Shell-Skripte durch den Mechanismus von docker-entrypoint-initdb.d im Container angewendet wurden.

$ pytest
============================= test session starts ==============================
platform darwin -- Python 3.8.6, pytest-6.1.2, py-1.9.0, pluggy-0.13.1 -- /Users/username/tmp/.venv/bin/python
cachedir: .pytest_cache
rootdir: /Users/username/tmp, configfile: pytest.ini
plugins: dotenv-0.5.2, cov-2.10.1, docker-0.10.1
collected 1 item                                                               

tests/test_users.py::test_get_name_by_id PASSED                          [100%]

---------- coverage: platform darwin, python 3.8.6-final-0 -----------
Name         Stmts   Miss  Cover
--------------------------------
src/app.py       8      0   100%


============================== 1 passed in 16.35s ==============================

Zusammenfassung

--pytest-docker ist praktisch, da Sie mit Docker Dienste starten können, die von Tests und nicht nur von Datenbanken abhängen.

Recommended Posts

Beispiel einer Pytest-Umgebung zum Reparieren der Datenbank mit Docker
Bereiten Sie die Ausführungsumgebung von Python3 mit Docker vor
Korrigieren Sie die Datenbank mit pytest-docker
Von Kafka bis KSQL - Einfache Umgebungskonstruktion mit Docker
Vorbereiten der Ausführungsumgebung von PyTorch mit Docker November 2019
SSH in eine virtuelle Umgebung mit vscode Remote Development
Bereiten Sie die Python3-Umgebung mit Docker vor
Vor- und Nachteile der Konvertierung der Entwicklungsumgebung von Django in Docker
Vom Umgebungsaufbau bis zum Einsatz für Kolben + Heroku mit Docker
Erstellen Sie eine MySQL + Python-Umgebung mit Docker
So verwenden Sie das Jupyter-Notebook, ohne Ihre Umgebung mit Docker zu verschmutzen
Ich habe versucht zu beheben "Ich habe versucht, die Wahrscheinlichkeit eines Bingospiels mit Python zu simulieren"
Erstellen Sie die Entwicklungsumgebung von Django mit Docker neu! !! !! !!
Ich wollte ein Jupyter-Notebook mit Docker in einer Pip-Umgebung (Opticspy) verwenden.
Bereiten Sie eine Umgebung zum Berühren von Dateien im Grib2-Format mit Python vor (Docker Edition).
Einstellung, um den Inhalt der Bibliothek mit pytest einzugeben und einen Debug-Test durchzuführen
Mit Docker durchgeführte Umgebungswartung (Ich möchte GrADS in Python nachbearbeiten
Zusammenfassung zum Erstellen einer LAMP + Wordpress-Umgebung mit Sakura VPS
Ändern Sie die Python 64-Bit-Umgebung mit Anaconda in eine 32-Bit-Umgebung
So erstellen Sie eine NVIDIA Docker-Umgebung
Stellen Sie mit Python in Docker eine Verbindung zu MySQL her
Holen Sie sich mit Docker eine lokale Umgebung für DynamoDB
Beispielskript zum Anzeigen von BoundingBox mit PIL
Erstellen Sie mit Docker eine Python + uWSGI + Nginx-Umgebung
Versuchen Sie, jede Umgebung von Kivy vorzubereiten
[Linux] Erstellen einer Jenkins-Umgebung mit Docker
Starten Sie die Umgebung mit LineBot + Heroku + Docker + Python
Einführung in Docker Erstellen einer Ubuntu-Umgebung in Ubuntu
Beispiel für eine effiziente Datenverarbeitung mit PANDAS
Erstellen Sie mit Docker eine Umgebung aus NGINX + NGINX Unit + MySQL
So installieren Sie Python3 mit Docker Centos
[Linux] Aufbau einer Docker-Umgebung mit Amazon Linux 2
Ich habe versucht, mit Raspberry Pi 4 eine Umgebung von Ubuntu 20.04 LTS + ROS2 zu erstellen
Ein Beispiel für cloudbuild.yaml bei der automatischen Bereitstellung von Django für App Engine mit Cloud Build
Ubuntu 16.04 LTS, Anfänger-Memorandum zur Umgebungskonstruktion, um die Version von Anaconda durch Pyenv zu ersetzen
Hallo Welt mit gRPC / go in Docker-Umgebung
Erstellen einer Analyseumgebung mit Docker (Jupyter Notebook + PostgreSQL)
Ich möchte datetime.datetime.now () auch mit pytest verspotten!
[Python] Erstellen Sie mit Docker eine Django-Entwicklungsumgebung
Verwenden Sie mit pyenv mehrere Versionen der Python-Umgebung
Beispiel für das Abrufen eines Zugriffstokens von Mastodon mit authorisation_code
Erstellen Sie mit Docker eine Umgebung aus Nginx + uWSGI + Python (Django)
Skript zum Twittern mit Vielfachen von 3 und Zahlen mit 3 !!
So legen Sie Attribute mit Mock of Python fest
So implementieren Sie "named_scope" von RubyOnRails mit Django
Die Geschichte des Versuchs, Tensorboard mit Pytorch zu verwenden
Poetry-Virtualenv-Umgebungskonstruktion mit Centos-Sclo-Rh-Python ~ Hinweise
Es kann keine Verbindung zu MySQL über die Docker-Umgebung (Debian) hergestellt werden.
Ablauf beim Erstellen einer virtuellen Umgebung mit Anaconda
Senden Sie msgpack mit Ajax an die flk (werkzeug) Umgebung
Von der Python-Umgebungskonstruktion zur virtuellen Umgebungskonstruktion mit Anaconda
Verfahren zum Einstellen des Wasserstoffs des Atoms (virtuelle Umgebung)
Beispiel für das Lesen und Schreiben von CSV mit Python
Verwenden Sie die virtuelle Umgebung von anaconda mit Zsh (Problembehandlung)
Erste Schritte mit Visual Studio Online ~ Das Ende der Ära der Umgebungskonstruktion ~