모두가 선호하는 Python 테스트 프레임워크인 Pytest에서 픽스처는 테스트가 시작되기 전에 무언가를 정렬하고 종료 후에 정리하는 재사용 가능한 코드 조각입니다. 예를 들어, 임시 파일이나 폴더, 환경 설정, 웹 서버 시작 등이 있습니다. 이 게시물에서는 다음을 얻는 테스트 데이터베이스(비어 있거나 알려진 상태)를 생성하는 Pytest 픽스쳐를 생성하는 방법을 살펴보겠습니다. 정리하여 각 테스트를 완전히 깨끗한 데이터베이스에서 실행할 수 있습니다.
테스트 데이터베이스를 준비하고 정리하기 위해 Psycopg 3을 사용하여 Pytest 픽스처를 생성하겠습니다. 빈 데이터베이스는 테스트에 거의 도움이 되지 않기 때문에 선택적으로 Yoyo 마이그레이션(웹사이트 작성 시 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을 사용해 보았습니다. 나는 내 자신의 픽스처를 작성하기 전에 그것을 시도했지만 나에게 적합하게 만들 수 없었습니다. 아마도 그들의 문서가 나에게 매우 혼란스럽기 때문일 것입니다. 또 다른 pytest-dbt-postgres는 전혀 시도하지 않았습니다.동기 부여 및 대안
데이터베이스에 의존하는 테스트를 위한 PostgreSQL 고정 장치를 약속하는 일부 Pytest 플러그인이 있는 것 같습니다. 그들은 당신에게 잘 작동할 수도 있습니다.
클래식 Python 프로젝트에서 소스는 src/에 있고 테스트는 test/에 있습니다.
├── 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라는 또 다른 픽스처로 Apply migration을 작성하세요.
@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 고정 장치에 yoyo 고정 장치가 필요합니다.
@pytest.fixture def test_db(yoyo): ...
일부 테스트에만 마이그레이션을 적용하려면 yoyo를 개별적으로 요구하세요.
def test_create_admin_table(test_db, yoyo): ...
테스트에 깨끗한 데이터베이스를 제공하기 위해 자체 픽스처를 구축하는 것은 Pytest와 Postgres에 대해 더 깊이 탐구할 수 있는 보람 있는 경험이었습니다.
이 기사가 귀하의 데이터베이스 테스트 스위트에 도움이 되었기를 바랍니다. 궁금한 점은 댓글로 남겨주시고 행복한 코딩하세요!
위 내용은 Pytest 및 PostgreSQL: 모든 테스트를 위한 새로운 데이터베이스의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!