pgtap
PostgreSQL单元测试框架
概览
| 扩展包名 | 版本 | 分类 | 许可证 | 语言 |
|---|---|---|---|---|
pgtap | 1.3.4 | LANG | PostgreSQL | C |
| ID | 扩展名 | Bin | Lib | Load | Create | Trust | Reloc | 模式 |
|---|---|---|---|---|---|---|---|---|
| 3200 | pgtap | 否 | 是 | 否 | 是 | 否 | 否 | - |
| 相关扩展 | plpgsql plpgsql_check plpgsql pldbgapi plprofiler faker unit dbt2 plperl |
|---|
missing pg17 el9, breaking perl deps
版本
| 类型 | 仓库 | 版本 | PG 大版本 | 包名 | 依赖 |
|---|---|---|---|---|---|
| EXT | PGDG | 1.3.4 | 1817161514 | pgtap | plpgsql |
| RPM | PGDG | 1.3.4 | 1817161514 | pgtap_$v | - |
| DEB | PGDG | 1.3.4 | 1817161514 | postgresql-$v-pgtap | - |
安装
您可以直接安装 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 单元测试框架,输出 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');