Skip to main content

Pytest plugin for running pgTAP tests

Project description

pytest-pgtap

What is pytest-pgtap?

pytest-pgtap is a pytest plugin for running pgTAP tests against PostgreSQL. pgTAP is a mature and sadly underappreciated Postgres extension that enables running unit tests for database constructs in the database itself. You can use SQL to test your SQL.

You should read the documentation for pgTAP, which describes the functions and strategies for testing Postgres schemas, views, triggers, queries, etc.

Why?

I wanted a to run tests against my Alembic revisions and pgTAP is a great tool, but I have no idea how to install a CPAN package. Anyway, if you are testing a Flask or Django app (or whatever), it's easier to have a single test runner that fits easily into a Python toolchain. Hence a plugin for pytest.

How?

pytest-pgtap provides three entry points into the pgTAP test framework. It is designed to be a replacement for pg_prove, pgTAP's native test runner (which is written in Perl) that can...

  1. Execute SQL Test Scripts directly (test_*.sql files collected by pytest)

  2. Or run xUnit test functions already defined in your database. (i.e runtests())

    ...it can also be used...

  3. As a pytest marker (@pytest.mark.pgtap) on pytest test cases to allow defining pgTAP tests in Python test files alongside application tests.

Requirements

  • Python 3.10+
  • pytest
  • PostgreSQL
  • pgTAP extension installed in the target database

pytest-pgtap does not automatically install pgTAP. Install it in your Postgres instance first.

Installation

Install from source:

pip install -e .

Or directly from GitHub:

pip install -U git+https://github.com/lmergner/pytest-pgtap.git

Note: To report PgTAP results, this plugin relies on the Pytest subtests feature introduced in Pytest v9. If you are using Pytest 8, you'll need to install the optional subtests dependency, that adds pytest-subtests as an extra plugin for backwards-compatibility.

pip install -U "git+https://github.com/lmergner/pytest-pgtap.git#egg=pytest-pgtap[subtests]"

Usage

Connection

Set a connection URI explicitly:

pytest --pgtap-uri postgresql://user:pass@host:5432/dbname

Or rely on standard libpq environment variables (PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD).

Mode 1: SQL file tests

Any file named test*.sql is collected as a pytest item.

Example tests/test_schema.sql:

BEGIN;
SELECT plan(2);
SELECT has_table('public', 'users', 'users table exists');
SELECT has_column('public', 'users', 'email', 'users.email exists');
SELECT * FROM finish();
ROLLBACK;

Run:

pytest --pgtap-uri postgresql://user:pass@host:5432/dbname

Mode 2: xUnit runtests() mode

Run pgTAP xUnit functions from a schema using pgTAP runtests():

pytest --pgtap-uri postgresql://user:pass@host:5432/dbname --pgtap-schema mytests

Optional regex function filter:

pytest --pgtap-uri postgresql://user:pass@host:5432/dbname --pgtap-schema mytests --pgtap-match '^test_'

Mode 3: Inline Python marker mode

Use @pytest.mark.pgtap on a Python test function that returns SQL assertions:

import pytest


@pytest.mark.pgtap
def test_contacts_table():
    return [
        "SELECT has_table('public', 'contacts', 'contacts table exists');",
        "SELECT has_column('public', 'contacts', 'name', 'contacts.name exists');",
    ]

Returning a single SQL string is also supported.

CLI options

  • --pgtap-uri: Postgres connection URI (defaults to DATABASE_URL if set)
  • --pgtap-schema: Enable xUnit mode by running runtests(<schema>)
  • --pgtap-match: Regex filter used with --pgtap-schema

Development

This project suggests Hatch for managing your environment and automating development tasks:

hatch run dev:format
hatch run dev:lint
hatch run dev:test
hatch run docs:build

Similar to tox, Hatch supports multi-version matrix testing so we can verify this library works across different versions of Python, Pytest and Postgres.

hatch run test:run  # run all combinations
hatch -e test.py3.13-pytest9-pg18 run  # single combination
hatch run test:run -- -x  # pass extra args to pytest

The test suite uses testcontainers to spin up Postgres. You'll need Docker or some other OCI runtime.

Using Podman instead of Docker

If you use Podman, enable the compatibility socket and set two environment variables:

systemctl --user enable --now podman.socket
export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock
export TESTCONTAINERS_RYUK_DISABLED=true

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest_pgtap-0.2.0.tar.gz (9.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_pgtap-0.2.0-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

File details

Details for the file pytest_pgtap-0.2.0.tar.gz.

File metadata

  • Download URL: pytest_pgtap-0.2.0.tar.gz
  • Upload date:
  • Size: 9.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for pytest_pgtap-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a231bcca667949d048edb41708c1b52e5ff4cde262e5f2154135b34b026f95b6
MD5 85511b1cc9e25379610382f1020992fa
BLAKE2b-256 2b107f2fd898667b04f939d6f377e804dfea2a2295804403296100802396fde8

See more details on using hashes here.

File details

Details for the file pytest_pgtap-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pytest_pgtap-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 9.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for pytest_pgtap-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 97f5d492378510ce9d3eb28247c98539ad17f8f07fd6f8eb6088e5e89c6129d8
MD5 6e02e5fcfb8c5251481a39991bd7c799
BLAKE2b-256 b96bd002a8e3fe2902b61a31d1dc8e55505b781a60f934de9389367c84efaa60

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page