如何用pytest-postgresql复用Docker化PostgreSQL作为测试模板数据库?
解决pytest-postgresql复用模板数据库的完整示例
前提准备
- 确保Docker化的PostgreSQL已启动,提前创建好带目标Schema的模板数据库(比如命名为
test_template),执行以下SQL将其标记为可复用模板:
ALTER DATABASE test_template IS_TEMPLATE = true;
配置conftest.py
在项目根目录创建conftest.py,配置noprocess工厂连接现有Docker数据库,同时手动控制测试库从指定模板创建:
import pytest from pytest_postgresql.factories import postgresql_noprocess # 配置noprocess工厂,连接到Docker中PostgreSQL的管理库(用于创建/删除测试库) postgres_admin = postgresql_noprocess( dbname="postgres", user="your_db_user", password="your_db_password", host="localhost", # Docker映射的主机地址 port="5432" # Docker映射的端口 ) # 自定义fixture:从模板创建独立测试库,测试后自动清理 @pytest.fixture(scope="function") def postgres_test_db(postgres_admin): # 生成唯一测试库名,避免并行测试冲突 test_db_name = f"test_run_{id(postgres_admin)}" # 从预定义模板创建新测试库 with postgres_admin.cursor() as cur: cur.execute(f"CREATE DATABASE {test_db_name} TEMPLATE test_template;") postgres_admin.commit() # 创建连接到新测试库的客户端 test_client = postgresql_noprocess( dbname=test_db_name, user="your_db_user", password="your_db_password", host="localhost", port="5432" ) yield test_client # 测试完成后清理:先终止连接,再删除数据库 test_client.close() with postgres_admin.cursor() as cur: cur.execute(f""" SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '{test_db_name}' AND pid <> pg_backend_pid(); """) cur.execute(f"DROP DATABASE {test_db_name};") postgres_admin.commit()
测试用例示例
直接使用自定义fixture编写测试,验证模板Schema已被复用:
def test_existing_schema(postgres_test_db): cursor = postgres_test_db.cursor() # 查询模板中已创建的表,确认测试库继承了Schema cursor.execute("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';") tables = cursor.fetchall() assert len(tables) > 0 # 验证模板表已存在 cursor.close()
错误原因说明
你之前遇到的database already exists问题,是因为默认postgresql工厂会自动尝试创建{dbname}_tmpl作为模板库,再基于它生成测试库。但我们已经提前准备了自定义模板库,因此需要跳过自动生成_tmpl的逻辑,手动控制测试库的创建流程。
内容的提问来源于stack exchange,提问作者CptPicard
相关产品推荐
相关产品推荐

