postgresql - 为我的 Postgres 对象编写基本测试代码
问题描述
我想为我的 Postgres 11.5 数据库中的各种对象构建一些测试代码,并且想知道是否有一种直接的方法可以在直接 SQL 中实现简单的检查。例如,我有一个简单的域,可以接受三个值中的任何一个,即不区分大小写。这只是我选择的一个示例,因为测试用例是有限且简单的。
DROP DOMAIN IF EXISTS domains.test_outcome;
CREATE DOMAIN domains.test_outcome AS
citext
NOT NULL
CONSTRAINT test_outcome_legal_values
CHECK(
VALUE IN ('pass','warning','fail')
);
COMMENT ON DOMAIN domains.test_outcome IS
'The test_outcome must be pass, warning, or fail, case-insensitive.';
下面是一些简单的测试语句,它们可以使用好值和坏值:
-- Good values
select 'warning'::test_outcome;
select 'fail'::test_outcome;
select 'PASS'::test_outcome;
select 'WARNING'::test_outcome;
select 'FAIL'::test_outcome;
-- Bad values
select NULL::test_outcome;
select ''::test_outcome;
select 'foo'::test_outcome;
我想做的是为每种情况获取一行,而不是因错误而崩溃。我尝试过使用DO
块,并且可以使用 PL/PgSQL 函数。这是DO
我尝试过的代码:
DO $TESTS$
BEGIN
-- Good values
select 'warning'::test_outcome;
select 'fail'::test_outcome;
select 'PASS'::test_outcome;
select 'WARNING'::test_outcome;
select 'FAIL'::test_outcome;
-- Bad values
select NULL::test_outcome;
select ''::test_outcome;
select 'foo'::test_outcome;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE 'Error Name:%', SQLERRM;
RAISE NOTICE 'Error State:%', SQLSTATE;
END;
$TESTS$
我得到的是几条通知。据我所知,我无法将这些与具体的陈述联系起来,而且我对成功案例一无所获。
NOTICE: Error Name:query has no destination for result data
NOTICE: Error State:42601
DO
Command completed successfully. (Line 20)
我已经看到周围有一些 PG 单元测试框架,使用我们不使用的语言。有没有办法在直接 SQL 或 PL/PgSQL 中进行类似上面的简单测试?
解决方案
没有什么我知道的,但也许以下可以为您提供一个模板。
我需要修改您的域定义,稍微删除其中的 NOT NULL 约束。下面的脚本声明了test_outcome的工作变量。但是 Postgres 强制执行 NOT NULL,因此不允许声明。(如果你问我,这是一个错误,但是......)。在这种情况下,无论如何都不会在有效值列表中出现NULL,这不会造成很大的损失。
CREATE DOMAIN test_outcome AS
citext
-- NOT NULL
CONSTRAINT test_outcome_legal_values
CHECK(
VALUE IN ('pass','warning','fail')
);
这个想法是创建一个测试项目数组并迭代该数组,将每个值分配给声明的域变量并捕获任何异常。请注意,这部分位于内部 begin...end 块中。这可以防止在生成错误时终止脚本。对于这种类型/级别的测试,我喜欢记录成功的测试以及失败的测试,因此我也会对这些测试进行加薪通知。
do $$
declare
-- list items to be tested
test_set text[] = $Q${warning,Fail,pass,WARNING,FAIL,null,'',foo}$Q$;
-- define variable of data type being testes
indx_val test_outcome;
-- variable to contain text value
indx text;
begin
-- loop through test set,
-- Note the index variable must of same base type as array
foreach indx in array test_set
loop
begin
indx_val = indx; -- assign test
raise notice 'Testing: <%>. Successful.',indx;
-- capture error in assign above
exception when others then
raise notice 'Testing: <%>. Failed.',indx;
raise notice ' *Error Name:%', sqlerrm;
raise notice ' *Error State:%', sqlstate;
end ;
end loop;
exception when others then
raise notice 'Error Name:%', sqlerrm;
raise notice 'Error State:%', sqlstate;
END;
$$;
您应该能够适应这种通用格式的其他类型定义。祝你好运!
推荐阅读
- drools - Drools 如何比较整数
- java - 如何播放存储在 java 项目中的 mp3 音频?
- php - PHP中的动态数组引用
- android - 耳机插入接收器收不到广播
- arrays - PowerShell 4.0 版(.PS1 文件)- 将文本框中的文本添加到要在控制台上打印的数组中
- mongodb - 我应该至少使用哪个版本的 Parse-server 和 mongodb 驱动程序来支持 MongoDB 4.2?
- python - PyQt5 QtWebEngineWidgets 在 pyqt5 和 sip 重新安装后停止工作
- python - 在二维 Numpy 数组中切片非连续索引
- google-apps-script - 导入 CSV 错误异常:无法将 ',' 转换为 char
- python - 根据数据更改图表列颜色