只有在测试失败时,c ++ gtest才会在测试结束时输出其他信息

baz*_*rek 4 c++ assert expectations googletest assertions

我想做这样的事情:

TEST(MyTestFixture, printAfterExpectationFailure)
{
  const string request("bring me tea");

  const string&& response = sendRequestAndGetResponse(request);

  checkResponseWithExpectarions1(response);
  checkResponseWithExpectarions2(response);
  checkResponseWithExpectarions3(response);
  checkResponseWithExpectarions4(response);

  if (anyOfExpectsFailed())
      cout << "Request: " << request << "\nresponse: " << response << endl;
}

TEST(MyTestFixture, printAfterAssertionFailure)
{
  const string request("bring me tea");

  const string&& response = sendRequestAndGetResponse(request);

  doWhenFailure([&request, &response]()
  {
      cout << "Request: " << request << "\nresponse: " << response << endl;
  });

  checkResponseWithAssertion1(response);
  checkResponseWithAssertion2(response);
  checkResponseWithAssertion3(response);
  checkResponseWithAssertion4(response);
}
Run Code Online (Sandbox Code Playgroud)

我仅在期望/断言失败时才打印一些其他信息。

我知道我可以做这样的事情:

#define MY_ASSERT_EQ(lhr, rhs, message) if(lhs != rhs) ASSERT_EQ(lhs, rhs) << message
Run Code Online (Sandbox Code Playgroud)

但是这种解决方案并不令人满意,因为:

  1. 我检查两次
  2. 我使用预处理程序,因此可能需要一些时间才能找到错误。
  3. 当函数真正嵌套时,很难使用该解决方案。
  4. 当许多EXPECTATIONS失败时,它将多次打印消息。
  5. 必须重新定义宏以进行各种检查

mar*_*o.m 5

实际上,很难做到自己想做的事情是测试代码的味道。特别是,这两个测试(1)做得太多,并且(2)在它们没有描述被测单元的功能的意义上是不可读的。

我推荐两个读物:单元测试是第一本,以及《现代C ++编程与测试驱动开发》一书

建议不要尝试调用4个函数,每个函数先检查一些内容,然后再想知道如何在出现故障的情况下打印错误消息,而不是调用4个函数:

  • 问自己:“我在这里测试什么?” 当您有答案时,请使用答案为测试命名。如果找不到答案,则意味着(我怀疑)该测试做得太多。尝试遵循“每个测试一个声明”的准则,并相应地拆分测试。
  • 本着同样的精神,看一下这四个函数中的每个,并尝试给每个函数起一个名字。如果不能,则每个功能都检查过多。拆分这些功能。
  • 问问自己,您是否真的需要期望(而不是主张)。通常,拥有EXPECT而不是ASSERT的唯一原因是因为单个测试做得太多。拆分它。

在此过程的最后,您应该会发现自己处于一种可以通过以下类似方式实现打印有关测试失败的其他信息的目标:

ASSERT_THAT(Response, EQ("something")) << "Request: " << request;
Run Code Online (Sandbox Code Playgroud)

注意:如果最好还是作为起点,我认为上述示例不够好。测试名称应如此好,具有描述性,以至于您可以通过打印的值获得零信息request

我意识到这是一种哲学上的回答;另一方面,这直接来自于我尝试编写好的,可维护的测试的经验。编写良好的测试与编写良好的代码需要同样的照顾,并且它会多次回报:-)