[英]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.