誰もが好む Python テスト フレームワークである Pytest では、フィクスチャは、テストが開始される前に 何か を配置し、終了後にクリーンアップする再利用可能なコードです。たとえば、一時ファイルやフォルダー、環境のセットアップ、Web サーバーの起動などです。この投稿では、テスト データベース (空または既知の状態) を作成する Pytest フィクスチャの作成方法を見ていきます。クリーンアップされ、完全にクリーンなデータベースで各テストを実行できるようになります。
Psycopg 3 を使用して Pytest フィクスチャを作成し、テスト データベースを準備およびクリーンアップします。空のデータベースがテストに役立つことはほとんどないため、必要に応じて Yoyo 移行 (この記事の執筆時点では Web サイトがダウンしており、archive.org スナップショットに移動) を適用してデータベースを埋めます。
このブログ投稿で作成した test_db という名前の Pytest フィクスチャの要件は次のとおりです。
テスト メソッドの引数をリストしてリクエストするテスト メソッド:
def test_create_admin_table(test_db): ...
テスト DB に接続された通常の Psycopg Connection インスタンスを受け取ります。テストは、単純な Psycopg の一般的な使用法と同様に、必要なことを何でも実行できます。例:
def test_create_admin_table(test_db): # Open a cursor to perform database operations cur = test_db.cursor() # Pass data to fill a query placeholders and let Psycopg perform # the correct conversion (no SQL injections!) cur.execute( "INSERT INTO test (num, data) VALUES (%s, %s)", (100, "abc'def")) # Query the database and obtain data as Python objects. cur.execute("SELECT * FROM test") cur.fetchone() # will return (1, 100, "abc'def") # You can use `cur.fetchmany()`, `cur.fetchall()` to return a list # of several records, or even iterate on the cursor for record in cur: print(record)
同じことを約束する pytest-postgresql を試しました。独自のフィクスチャを作成する前に試してみましたが、うまく動作させることができませんでした。おそらく、彼らのドキュメントが私にとって非常にわかりにくかったからでしょう。 もう 1 つの pytest-dbt-postgres は、まったく試していません。動機と選択肢
データベースに依存するテストに PostgreSQL フィクスチャを約束する Pytest プラグインがいくつかあるようです。それらはあなたにとってうまくいくかもしれません。
古典的な Python プロジェクトでは、ソースは src/ に存在し、テストは testing/:
├── src │ └── tuvok │ ├── __init__.py │ └── sales │ └── new_user.py ├── tests │ ├── conftest.py │ └── sales │ └── test_new_user.py ├── requirements.txt └── yoyo.ini
幻想的な Yoyo のような移行ライブラリを使用する場合、移行スクリプトはおそらく migrations/:
にあります。
├── migrations ├── 20240816_01_Yn3Ca-sales-user-user-add-last-run-table.py ├── ...
私たちのテスト DB フィクスチャには、非常に小さな構成が必要です:
Pytest には、複数のファイル間でフィクスチャを共有するための conftest.py という自然な場所があります。フィクスチャ設定もそこに移動します:
# Without DB name! TEST_DB_URL = "postgresql://localhost" TEST_DB_NAME = "test_tuvok" TEST_DB_MIGRATIONS_DIR = str(Path(__file__, "../../migrations").resolve())
これらの値は環境変数から設定することも、状況に応じて設定することもできます。
PostgreSQL および Psycopg ライブラリ の知識を基に、conftest.py にフィクスチャを作成します。
@pytest.fixture def test_db(): # autocommit=True start no transaction because CREATE/DROP DATABASE # cannot be executed in a transaction block. with psycopg.connect(TEST_DB_URL, autocommit=True) as conn: cur = conn.cursor() # create test DB, drop before cur.execute(f'DROP DATABASE IF EXISTS "{TEST_DB_NAME}" WITH (FORCE)') cur.execute(f'CREATE DATABASE "{TEST_DB_NAME}"') # Return (a new) connection to just created test DB # Unfortunately, you cannot directly change the database for an existing Psycopg connection. Once a connection is established to a specific database, it's tied to that database. with psycopg.connect(TEST_DB_URL, dbname=TEST_DB_NAME) as conn: yield conn cur.execute(f'DROP DATABASE IF EXISTS "{TEST_DB_NAME}" WITH (FORCE)')
私たちの場合、Yoyo マイグレーションを使用します。マイグレーションの適用を yoyo という別のフィクスチャとして記述します:
@pytest.fixture def yoyo(): # Yoyo expect `driver://user:pass@host:port/database_name?param=value`. # In passed URL we need to url = ( urlparse(TEST_DB_URL) . # 1) Change driver (schema part) with `postgresql+psycopg` to use # psycopg 3 (not 2 which is `postgresql+psycopg2`) _replace(scheme="postgresql+psycopg") . # 2) Change database to test db (in which migrations will apply) _replace(path=TEST_DB_NAME) .geturl() ) backend = get_backend(url) migrations = read_migrations(TEST_DB_MIGRATIONS_DIR) if len(migrations) == 0: raise ValueError(f"No Yoyo migrations found in '{TEST_DB_MIGRATIONS_DIR}'") with backend.lock(): backend.apply_migrations(backend.to_apply(migrations))
すべてのテスト データベースに移行を適用する場合は、test_db フィクスチャにヨーヨー フィクスチャが必要です:
@pytest.fixture def test_db(yoyo): ...
一部のテストのみに移行を適用するには、ヨーヨーを個別に必要とします:
def test_create_admin_table(test_db, yoyo): ...
テストにクリーンなデータベースを提供するための独自のフィクスチャを構築することは、私にとって Pytest と Postgres の両方をより深く掘り下げることができる貴重な経験でした。
この記事が独自のデータベース テスト スイートに役立つことを願っています。お気軽にコメント欄に質問を残していただき、コーディングを楽しんでください!
以上がPytest と PostgreSQL: すべてのテストに使用できる最新のデータベースの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。