簡體   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