我的Catch Testframework中有以下简单表达式。理想情况下,如果测试失败,测试应发出警告。
不幸的是,Catch无法编译以下代码片段:
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
TEST_CASE("Simple") {
int a = 4;
int b = 1;
CHECK(a == 5 || b == 2);
}
Visual Studio 2015发出以下错误:
error C2676: Binary operator "||": "const Catch::BinaryExpr<LhsT,const int &>" does not define this operator or a conversion for this operator of to suitable type
我希望如下:
4==5 || 1==2 => false || false => false
这可能与Catch有关,还是我必须使用额外的parantheses:
#define CATCH_CONFIG_MAIN
#include "catch2.hpp"
TEST_CASE("Simple") {
int a = 4;
int b = 1;
CHECK((a == 5 || b == 2));
}
答案 0 :(得分:4)
如果你看过docs,你会发现一个部分说:
检查(a == 2 || b == 1);这个表达式因为太复杂了 ||运营商。如果要检查其中一个属性 保持,您可以将表达式括在括号中(与&amp;&amp ;,不同, 表达式分解成几个CHECK是不可能的。)
另请注意......
我希望如下:
4==5 || 1==2 => false || false => false
......你的期望略有下降。 ||
被短路,这意味着如果第一个操作数计算为false
,则第二个操作数不会被评估。
答案 1 :(得分:2)
Catch Classic用于提供更好的错误,因为它会出错
在一个名为某事物的类型的实例中
CATCH_STATIC_ASSERT_EXPRESSION_TOO_COMPLEX_REWRITE_...
,但显然
在重写表达式捕获层时消失了。
无论如何,简单的答案已由user463035818提供,附上 括号中的表达式。我想扩展为什么表达式包含
&&或||
。
为什么不支持&&
和||
运算符,有三个部分,
其中两个是实用的,一个是哲学的。
1)TMP魔法用于分解表达并漂亮打印它 无法正确模拟内置运算符的短路行为。 这意味着这些表达式的行为会有所不同 用户的期望。
2)已经提到的TMP魔术相当昂贵 编译时,即使我们有一元和二元的专用路径 表达式。可能具有可变表达式的一般路径 最终过于昂贵。
3)在断言中使用||
通常是代码(测试)气味。在
合理的单元测试,你应该能够表达预期的结果
确切地说,并且对于不正确的情况(例如迭代
一个无序的集合,逻辑或仍然不是一个好的工具解决方案。
注1:在单元测试中使用&&
(逻辑和)是完全合理的
实际上使用&&
重写表达式是相当简单的
编译并仍然短路:
REQUIRE((expr1 && expr2 && expr3));
REQUIRE(expr1);
REQUIRE(expr2);
REQUIRE(expr3);
注意2:这开始是对另一个答案的评论,但随后是 超过允许的长度,我注意到错误消息 Catch2确实不好,所以我opened up an issue。