首页 > 解决方案 > 如何避免 C++ 未定义行为欺骗 GoogleTest

问题描述

我正在为我的容器类编写测试,其中许多测试检查查询方法,这些方法返回truefalse. 例子:

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() {}

我应该如何编写测试以使这种“偷偷摸摸”的机制无法欺骗他们,因为到目前为止,如果我只实现类似MyContainer::add,MyContainer::get然后MyContainer::remove我的所有测试都会通过,尽管所有这些查询方法都不起作用.

注意:我在没有任何编译器优化的情况下构建所有内容(测试和MyContainer)(Qt Creator 中的调试模式)。

注意 2:我使用 Qt Creator,但没有使用任何 Qt 模块/库。只是简单的 C++17googletestpthread(我在 Linux 上)。

标签: c++googletestundefined-behavior

解决方案


您的编译器应该警告您,您的函数中有不返回值的路径。如果没有,请提高您的警告级别(例如-Wall和/或-Wextra)并确保这些警告没有被抑制。

如果您(或您的同事)倾向于忽略这些警告,请使用-Werror将它们(好吧,所有警告)转换为编译错误 - 这样,如果有一些东西会触发这些警告,您的项目将不会编译,例如有路径不返回值。

也就是说,GoogleTest无法帮助您找到这些错误 - 它仅适用于编译的对象,因此它无法告诉您的bool sneaky()函数没有正确的返回值......请记住:未定义的行为可能导致时间旅行。 . 或允许b 同时为 TRUE 和 FALSE


推荐阅读