如何避免 C++ 未定义行为欺骗 GoogleTest
How to avoid C++ undefined behavior fooling GoogleTest
我正在为我的容器 class 编写测试,其中许多测试检查查询方法,return true
或 false
。示例:
myContainer.add(obj);
EXPECT_TRUE(myContainer.contains(obj));
问题是即使没有 MyContainer
实施,其中许多测试也会通过。
我认为我已经找到了这是什么原因,下面演示(问题是RealityTest.Sneaky
通过):
TEST(RealityTest, True) {
bool b = true;
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, False) {
bool b = false;
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, RandomBool) {
bool b = random_bool();
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, Sneaky) {
bool b = sneaky();
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, NoBool) {
bool b = no_bool();
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
测试中使用的函数定义如下:
bool random_bool() {
static std::random_device dev;
static std::uniform_int_distribution dist(0, 1);
return dist(dev);
};
bool sneaky() { cout << "brought to you by GCC (C++17)" << endl; }
bool no_bool() {}
我应该如何编写测试才能使 "sneaky" 机制无法欺骗他们,因为就目前而言,如果我只实现 MyContainer::add
、MyContainer::get
和MyContainer::remove
那么尽管所有这些查询方法都不起作用,但我的所有测试都会通过。
注意:我在没有任何编译器优化(Qt Creator 中的调试模式)的情况下构建所有内容(测试和 MyContainer
)。
注意 2:我使用 Qt Creator 但没有使用任何 Qt modules/libs。只是带有 googletest
和 pthread
的普通 C++17(我在 Linux)。
您的编译器应该警告您函数中的某些路径没有return值。如果没有,请提高 警告级别 (例如 -Wall
and/or -Wextra
)并确保这些警告未被抑制。
如果您(或您的同事)容易忽略这些警告,请使用 -Werror
将它们(好吧,所有 警告)变成编译错误 - 这如果有些事情会触发这些警告,例如,您的项目将无法 compile有一个没有 return 值的路径。
也就是说,GoogleTest 不能 帮助您找到这些错误 - 它只适用于编译对象,所以它不能告诉您的 bool sneaky()
函数没有没有合适的 return 值...记住:Undefined behavior can result in time travel.. or allow b to be TRUE and FALSE at the same time
我正在为我的容器 class 编写测试,其中许多测试检查查询方法,return true
或 false
。示例:
myContainer.add(obj);
EXPECT_TRUE(myContainer.contains(obj));
问题是即使没有 MyContainer
实施,其中许多测试也会通过。
我认为我已经找到了这是什么原因,下面演示(问题是RealityTest.Sneaky
通过):
TEST(RealityTest, True) {
bool b = true;
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, False) {
bool b = false;
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, RandomBool) {
bool b = random_bool();
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, Sneaky) {
bool b = sneaky();
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
TEST(RealityTest, NoBool) {
bool b = no_bool();
EXPECT_TRUE(b);
EXPECT_FALSE(b);
}
测试中使用的函数定义如下:
bool random_bool() {
static std::random_device dev;
static std::uniform_int_distribution dist(0, 1);
return dist(dev);
};
bool sneaky() { cout << "brought to you by GCC (C++17)" << endl; }
bool no_bool() {}
我应该如何编写测试才能使 "sneaky" 机制无法欺骗他们,因为就目前而言,如果我只实现 MyContainer::add
、MyContainer::get
和MyContainer::remove
那么尽管所有这些查询方法都不起作用,但我的所有测试都会通过。
注意:我在没有任何编译器优化(Qt Creator 中的调试模式)的情况下构建所有内容(测试和 MyContainer
)。
注意 2:我使用 Qt Creator 但没有使用任何 Qt modules/libs。只是带有 googletest
和 pthread
的普通 C++17(我在 Linux)。
您的编译器应该警告您函数中的某些路径没有return值。如果没有,请提高 警告级别 (例如 -Wall
and/or -Wextra
)并确保这些警告未被抑制。
如果您(或您的同事)容易忽略这些警告,请使用 -Werror
将它们(好吧,所有 警告)变成编译错误 - 这如果有些事情会触发这些警告,例如,您的项目将无法 compile有一个没有 return 值的路径。
也就是说,GoogleTest 不能 帮助您找到这些错误 - 它只适用于编译对象,所以它不能告诉您的 bool sneaky()
函数没有没有合适的 return 值...记住:Undefined behavior can result in time travel.. or allow b to be TRUE and FALSE at the same time