pgtap

PostgreSQL单元测试框架

概览

扩展包名版本分类许可证语言
pgtap1.3.4LANGPostgreSQLC
ID扩展名BinLibLoadCreateTrustReloc模式
3200pgtap-
相关扩展plpgsql plpgsql_check plpgsql pldbgapi plprofiler faker unit dbt2 plperl

missing pg17 el9, breaking perl deps

版本

类型仓库版本PG 大版本包名依赖
EXTPGDG1.3.41817161514pgtapplpgsql
RPMPGDG1.3.41817161514pgtap_$v-
DEBPGDG1.3.41817161514postgresql-$v-pgtap-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
d12.aarch64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
d13.x86_64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
d13.aarch64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
u22.x86_64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
u22.aarch64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
u24.x86_64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
u24.aarch64
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4
PGDG 1.3.4

安装

您可以直接安装 pgtap 扩展包的预置二进制包,首先确保 PGDG 仓库已经添加并启用:

pig repo add pgdg -u          # 添加 PGDG 仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

pig install pgtap;          # 当前活跃 PG 版本安装
pig ext install -y pgtap -v 18  # PG 18
pig ext install -y pgtap -v 17  # PG 17
pig ext install -y pgtap -v 16  # PG 16
pig ext install -y pgtap -v 15  # PG 15
pig ext install -y pgtap -v 14  # PG 14
dnf install -y pgtap_18       # PG 18
dnf install -y pgtap_17       # PG 17
dnf install -y pgtap_16       # PG 16
dnf install -y pgtap_15       # PG 15
dnf install -y pgtap_14       # PG 14
apt install -y postgresql-18-pgtap   # PG 18
apt install -y postgresql-17-pgtap   # PG 17
apt install -y postgresql-16-pgtap   # PG 16
apt install -y postgresql-15-pgtap   # PG 15
apt install -y postgresql-14-pgtap   # PG 14

创建扩展

CREATE EXTENSION pgtap CASCADE;  -- 依赖: plpgsql

用法

pgtap: PostgreSQL 单元测试框架

pgtap 是一个 PostgreSQL 单元测试框架,输出 TAP(Test Anything Protocol)格式的结果,提供数百个断言函数用于测试数据库对象和查询结果。

CREATE EXTENSION pgtap;

测试结构

BEGIN;
SELECT plan(3);  -- 声明要运行的测试数量

SELECT ok(1 = 1, 'one equals one');
SELECT is(1 + 1, 2, 'addition works');
SELECT isnt(1, 2, 'one is not two');

SELECT * FROM finish();
ROLLBACK;

当测试数量未知时使用 no_plan()

BEGIN;
SELECT * FROM no_plan();
-- ... 测试 ...
SELECT * FROM finish();
ROLLBACK;

基本断言

SELECT ok(expression, description);           -- 布尔测试
SELECT is(got, expected, description);         -- 相等测试
SELECT isnt(got, unexpected, description);     -- 不等测试
SELECT matches(value, regex, description);     -- 正则匹配

模式测试

SELECT has_table('users');
SELECT has_table('myschema', 'users', 'users table exists');
SELECT has_column('users', 'email');
SELECT col_type_is('users', 'email', 'text');
SELECT col_not_null('users', 'id');
SELECT col_has_default('users', 'created_at');
SELECT has_function('calculate_total');
SELECT has_function('calculate_total', ARRAY['integer', 'numeric']);
SELECT has_index('users', 'users_email_idx');
SELECT has_pk('users');
SELECT has_fk('orders');

错误测试

SELECT lives_ok('INSERT INTO t(id) VALUES (1)', 'insert succeeds');
SELECT throws_ok(
  'SELECT 1/0',
  '22012',          -- 除零错误的 SQLSTATE
  'division by zero'
);

查询结果测试

-- 比较有序结果集
SELECT results_eq(
  'SELECT * FROM active_users()',
  'SELECT * FROM users WHERE active',
  'active_users returns correct rows'
);

-- 比较无序结果集
SELECT set_eq(
  'SELECT * FROM active_ids()',
  ARRAY[2, 3, 4, 5]
);

-- 检查查询返回空结果
SELECT is_empty('SELECT * FROM users WHERE id = -1');

-- 比较多重集结果
SELECT bag_eq(
  'SELECT color FROM items',
  $$VALUES ('red'), ('blue'), ('red')$$
);

使用 pg_prove 运行测试

pg_prove -d mydb tests/*.sql
pg_prove -d mydb --ext .sql --recurse tests/

xUnit 风格

CREATE FUNCTION test_my_feature() RETURNS SETOF text AS $$
  RETURN NEXT ok(1 = 1, 'basic check');
  RETURN NEXT is(my_func(1), 42, 'function works');
$$ LANGUAGE plpgsql;

SELECT * FROM runtests('test_my_feature');

最后修改 2026-03-14: update extension metadata (953cbd0)