繁体   English   中英

为我的 Postgres 对象编写基本的测试代码

[英]Writing basic test code for my Postgres objects

我想为 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;
$$;  

您应该能够适应这种通用格式的其他类型定义。 祝你好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM