CheckOps
pgTAP
pgTAP is a unit testing framework for PostgreSQL written in PL/pgSQL and PL/SQL, providing TAP-emitting assertions for schema, data and functions, run with pg_prove.
Latest public signals
Not refreshed yet. Refresh reads the public site and, when the entry has a GitHub repository, the latest release.
Introduction
pgTAP is a suite of database functions that make it easy to write TAP-emitting unit tests in psql scripts or xUnit-style test functions. Its README describes it as written in PL/pgSQL and PL/SQL, with a comprehensive collection of TAP-emitting assertion functions and the ability to integrate with other TAP-emitting test frameworks.
The value for quality teams is that database behaviour gets tested inside the database. Application tests often treat the database as a black box, but constraints, triggers, functions, row-level security policies and migrations are code too, and they break. pgTAP lets you assert that tables, columns, indexes, primary and foreign keys exist as designed, that functions return the right types and values, and that queries return expected result sets.
The documentation covers a wide set of assertions. Basic ones include ok(), is(), isnt(), matches() and cmp_ok(). Schema assertions include has_table(), has_column(), has_index(), col_is_pk(), fk_ok(), tables_are(), has_function(), function_returns() and policies_are(). Result-set assertions such as results_eq(), set_eq(), bag_eq(), row_eq() and is_empty() compare query output, while throws_ok() and lives_ok() test errors and performs_ok() checks that a query runs within a time limit.
Tests are usually wrapped in a transaction that is rolled back, so they leave no trace. A script declares a plan(), runs assertions and calls finish(). The pg_prove command-line tool runs test scripts or xUnit-style test functions through runtests() and reports TAP results that CI systems understand.
pgTAP installs as an extension with CREATE EXTENSION pgtap. It must be installed on a host with a PostgreSQL server, and building from source needs pg_config.
In the CheckOps stage model pgTAP spans Unit and Integration testing, and runs in Release and CI pipelines to check migrations before deployment.
The source code is at theory/pgtap on GitHub under the PostgreSQL licence, with about 1,200 stars; the most recent commit was on 27 September 2026.
Organising tests by schema object keeps suites maintainable: one file for table structure, one for functions, one for security policies. Seed data should be created inside each test transaction so tests do not depend on each other. Running the suite against a database built from migrations, rather than a dump, also verifies that migrations themselves produce the intended schema. For larger teams, publishing pg_prove’s TAP output through a TAP-to-JUnit converter lets CI dashboards show database test results alongside application tests, which makes failures in schema changes as visible as any other broken build.
Finally, keep an eye on the cost of the suite: schema assertions are cheap, but result-set tests on large seed data can slow CI. Split slow tests into a separate job if needed so that quick structural checks still give fast feedback on every pull request.
Clear test descriptions in each assertion make TAP failures easy to read.
Treat failing database tests as release blockers, like any other test.
Features
- TAP assertions: ok, is, isnt, matches, cmp_ok.
- Schema assertions: Tables, columns, indexes and keys.
- Function checks: has_function and function_returns.
- Result-set comparison: results_eq, set_eq, bag_eq.
- Error testing: throws_ok and lives_ok.
- Performance checks: performs_ok time limits.
- RLS policies: policies_are.
- xUnit style: Test functions run with runtests().
- pg_prove runner: CI-friendly TAP output.
Pros
- Tests inside PostgreSQL: Exercises real constraints, triggers and functions.
- Transaction isolation: Rollback keeps databases clean.
- Free to use: Open source under the PostgreSQL licence, so the core tool costs nothing to use.
- Actively maintained: The repository had commits as recent as 27 September 2026.
Cons
- PostgreSQL only: Not for other databases.
- SQL test code: Tests are written in SQL or PL/pgSQL.
- Install requirements: Needs the extension on the server.
- TAP output: Needs a TAP consumer for rich reports.
Usage and Links (Example)
BEGIN;
SELECT plan(4);
SELECT has_table('public', 'orders', 'orders table exists');
SELECT col_is_pk('public', 'orders', 'id', 'id is the primary key');
SELECT fk_ok('public', 'orders', 'customer_id', 'public', 'customers', 'id');
SELECT results_eq(
$$ SELECT status FROM orders WHERE id = 1 $$,
$$ VALUES ('paid'::text) $$,
'order 1 is paid'
);
SELECT * FROM finish();
ROLLBACK;
pg_prove -d app_test tests/*.sql
Practical tips:
- Run pgTAP after every migration in CI against a fresh database.
- Use schema assertions to lock down the intended design.
- Test row-level security as different roles.
Resources:
Pricing
pgTAP is free and open source under the PostgreSQL licence.
Recommended for?
- PostgreSQL teams with logic in the database.
- Supabase users testing schemas and policies.
- Platform teams gating migrations in CI.
- Not for non-PostgreSQL databases.
Conclusion
pgTAP is the standard way to unit test PostgreSQL schemas, functions and policies from inside the database.
Pair it with a migration linter such as Squawk and run it in CI against every schema change.
On CheckOps, pgTAP is filed under the Unit testing, Integration testing and Release & CI gates stages. Related tools listed here include utPLSQL, SQLFluff, Atlas, Squawk, Database Lab Engine and dbt tests. When comparing them, weigh the licence, the languages and platforms each supports, whether it is self-hosted or managed, and how cleanly it slots into your existing CI pipeline. Details on this page were checked against the official website, documentation and repository on 11 November 2026.
Alternatives
Other tools on CheckOps that cover similar ground. Open a page, or compare one with pgTAP side by side.
UutPLSQLutPLSQL is an Apache-2.0 unit testing framework for Oracle PL/SQL and SQL, with annotations, rich expectations and reporters for SonarQube, Jenkins and TeamCity.Compare with pgTAP
SSQLFluffSQLFluff is an MIT dialect-flexible SQL linter and auto-formatter with Jinja and dbt templating support.Compare with pgTAP
AAtlasAtlas is an Apache-2.0 schema-as-code tool from Ariga for declarative and versioned database migrations, with migration linting and schema tests in CI.Compare with pgTAP
SSquawkSquawk is an Apache-2.0 linter for PostgreSQL migrations that flags changes likely to cause downtime, with a CLI, Docker image, GitHub Action and browser playground.Compare with pgTAP
DDatabase Lab EngineDatabase Lab Engine (DBLab) is Postgres.ai's Apache-2.0 tool for thin cloning and branching of large PostgreSQL databases in seconds for development and testing.Compare with pgTAP
Ddbt testsdbt tests are the built-in data tests and unit tests of dbt, the Apache-2.0 data transformation framework, used to validate models with unique, not_null, accepted_values and relationships checks.Compare with pgTAP