pgtap:预期和获得的结果相等,但测试失败

Posted

技术标签:

【中文标题】pgtap:预期和获得的结果相等,但测试失败【英文标题】:pgtap: expected and obtained result are equal, yet the test fails 【发布时间】:2011-09-06 17:36:22 【问题描述】:

我使用pgtap 来测试postgresql 存储过程。它的results_eq 函数获取存储过程的结果,将其与预期结果进行比较,如果两者不相等则报告失败。

这是我正在运行的代码:

PREPARE result_have AS SELECT select_some_data(12345, 'test_string');
PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)');
SELECT results_eq('result_have', 'result_want');

这是失败的输出:

not ok 21
# Failed test 21: "this should return a result"
#     Columns differ between queries:
#         have: ("(""2010-09-07 06:05:00+00"",100.0)")
#         want: ("(""2010-09-07 06:05:00+00"",100.0)")
# Looks like you failed 1 test of 21

我可能真的睡眠不足,但想要和看起来和我很相似。

有谁知道为什么这被报告为失败?


更新有关细节:这就是我定义相关存储过程的方式:

CREATE OR REPLACE FUNCTION select_some_data
(
    IN p_some_pkey integer,
    IN p_some_code varchar(16)
)
RETURNS TABLE(timestamp_utc timestamp with time zone, value varchar)
  ...

所以跟随peters advice,我尝试更改我的代码,但没有成功:

PREPARE result_have AS SELECT select_some_data(12345, 'test_string');
-- TODO: none of these work, syntax error at or near "TABLE"
-- PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)'::TABLE(timestamp with time zone, varchar));
-- PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)'::'TABLE(timestamp with time zone, varchar)');
-- this is the old code...
PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)');

SELECT results_eq('result_have', 'result_want');

您可能会说,即使是基本的 postgresql 语法,我也几乎是一头雾水——而且在搜索 :: 时,无论是谷歌还是在 postgresql.org 上的搜索都没有返回任何有用的信息。我最终冒险猜测这可能是一个操作员,并发现:: 是一个type cast。 CREATE FUNCTION 的 column_name 参数文档说 'RETURNS TABLE 也暗示 RETURNS SETOF' 这让我例如here 可能还有 here 和 here。新尝试:

PREPARE result_have AS SELECT select_some_data(12345, 'test_string');
-- TODO: doesn't work, syntax error at or near "("
-- PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)'::SETOF(timestamp with time zone, varchar));
-- TODO: doesn't work, syntax error at or near ","
-- PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)'::SETOF RECORD(timestamp with time zone, varchar));
-- this is the old code...
PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)');

SELECT results_eq('result_have', 'result_want');

这是没有意义的,我只是在这里做猜测。任何人都可以用正确的语法帮助我吗?另请注意,该功能只是RETURNS TABLE,因为这是我能够开始工作的第一件事,所以如果有需要更改的解决方案,我很乐意更改它。


更新 2:postgresql IRC 频道 (irc://irc.freenode.net/#postgresql) 上的 RhodiumToad 帮助我使用了正确的语法。如果我对 postgresql 的了解比我多一点,我可能会认为这才有意义:两种数据类型,两种强制转换(DOH!):o)。

另外,目前测试数据库中只有一个数据集,所以上面使用的语法可能仍然有效。据我了解,一旦返回多个数据集,它可能会失败,所以它应该是SELECT * FROM,而不仅仅是SELECT

PREPARE result_have AS SELECT * FROM select_some_data(12345, 'test_param_code');
PREPARE result_want AS VALUES ('2010-09-07 06:05:00+00'::timestamp with time zone, '100.0'::varchar);

SELECT results_eq('result_have', 'result_want', 'have and want should be equal');

现在已经和想要的结果被比较为相等并且测试通过。运行测试时的日志输出:

ok 21 - have and want should be equal
ok
All tests successful.
Files=1, Tests=21,  1 wallclock secs ( 0.02 usr  0.00 sys +  0.05 cusr  0.03 csys =  0.10 CPU)
Result: PASS

哇! :-)

【问题讨论】:

hmmm,不,我再看一遍,我意识到函数返回的表中的第二列是 varchar,而 pgtap 报告的是浮点数。奇怪... @mu 太短:我不确定 result_have 和 result_want 中是否有任何微秒;毕竟,如果他们在那里,他们会被展示出来,不是吗?但是后来,我确实在整个地方都看到了带有和不带有微秒的时间戳,到目前为止,我真的无法弄清楚为什么它们有时会在那里,有时却没有。到目前为止,这并不重要...... 感谢@past_self 提出这个问题! :+1: 8 年后,同样的问题 - 语法和引用仍然很糟糕,并且在 PostgreSQL 单元测试框架方面仍然没有其他选择。很高兴我在这里找到了一些帮助。 【参考方案1】:

您没有提供所有详细信息,但我怀疑这是数据类型不匹配。 pgTAP 往往需要完全匹配。试试这个:

PREPARE result_want AS VALUES ('("2010-09-07 06:05:00+00",100.0)'::foo);

其中foo 是函数select_some_data 的返回类型。

【讨论】:

以上是关于pgtap:预期和获得的结果相等,但测试失败的主要内容,如果未能解决你的问题,请参考以下文章

转单元测试接口测试功能测试的区别

浅谈自动化测试行为的本质

如何在测试过程中停止 PHPUnit 但仍然获得失败/报告列表?

Mocha Chai 基本 GET 请求未正确记录通过和失败

PHPUnit:预期状态码 200 但使用 Laravel 收到 419

运行所有测试时单元测试失败,但调试时通过