GoogleTest源码研究--如何获取输出结果信息

gtest的输出结果,要么是输出到控制台,要么输出到文件,但是有时候我们需要直接从程序返回输出信息,而不是从文件里读,这里通过借助gtest留给我们的拓展可以实现。
首先看信息输出到xml文件是如何实现的:

GTEST_API_ int main(int argc, char **argv) {
  printf("Running main() from %s\n", __FILE__);
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
inline int RUN_ALL_TESTS() {
  return ::testing::UnitTest::GetInstance()->Run();
}
return internal::HandleExceptionsInMethodIfSupported(
      impl(),
      &internal::UnitTestImpl::RunAllTests,
      "auxiliary test code (environments or event listeners)") ? 0 : 1;
bool UnitTestImpl::RunAllTests() {
  // True if and only if Google Test is initialized before RUN_ALL_TESTS() is
  // called.
  const bool gtest_is_initialized_before_run_all_tests = GTestIsInitialized();

  // Do not run any test if the --help flag was specified.
  if (g_help_flag)
    return true;

  // Repeats the call to the post-flag parsing initialization in case the
  // user didn't call InitGoogleTest.
  PostFlagParsingInit();
void UnitTestImpl::ConfigureXmlOutput() {
  const std::string& output_format = UnitTestOptions::GetOutputFormat();
  if (output_format == "xml") {
    listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter(
        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
  } else if (output_format == "json") {
    listeners()->SetDefaultXmlGenerator(new JsonUnitTestResultPrinter(
        UnitTestOptions::GetAbsolutePathToOutputFile().c_str()));
  } else if (output_format != "") {
    GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \""
                        << output_format << "\" ignored.";
  }
}

在InitGoogleTest中,会解析用户命令行下输入的 --output 字段信息,放到 UnitTestOption中保存。运行用例函数的时候,在RUN_ALL_TESTS中,执行到函数ConfigureXmlOutput里面时,会读取UnitTestOption里刚才存的信息,判断如果是xml,则用XmlUnitTestResultPrinter来初始化 TestEventListener, XmlUnitTestResultPrinter是TestEventListener的子类,而这个TestEventListener,在测试用例程序运行的整个周期的不同时机,会调用各个不同的函数。

    // Tells the unit test event listener that the tests have just finished.
    repeater->OnTestIterationEnd(*parent_, i);
// Called after the unit test ends.
void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
                                                  int /*iteration*/) {
  FILE* xmlout = OpenFileForWriting(output_file_);
  std::stringstream stream;
  PrintXmlUnitTest(&stream, unit_test);
  fprintf(xmlout, "%s", StringStreamToString(&stream).c_str());
  fclose(xmlout);
}

直到调用OnTestIterationEnd的时候,这个时候测试用例运行结果的所有信息都包含在参数UnitTest中, 将这个信息转成xml格式即可。也就是说,我们只需要创建自己的类,同样继承TestEventListener,覆盖OnTestIterationEnd方法,让整个运行过程中的listener变成我们自定义的类,这样我们就可以在OnTestIterationEnd回调中,获取包含所有结果信息的UnitTest类。为了方便继承,可以继承EmptyTestEventListener类,这个类也是继承TestEventListener,只不过覆盖了所有抽象方法,按源码注释说明,这是为了方便用户只覆盖一两个接口。于是,实现我们要实现的功能的主要代码如下:

#include <iostream>
#include "gtest/gtest.h"

TEST(suiteA, 1)
{
    int a = 0;
    EXPECT_EQ(a, 1);
}

TEST(suiteA, 2) {
  int a = 0;
  EXPECT_EQ(a, 0);
}

TEST(suiteB, 1) {
  int a = 0;
  EXPECT_EQ(a, 0);
}

using namespace testing;
using namespace std;

class myclass : public EmptyTestEventListener{
	void OnTestIterationEnd(const UnitTest& unit_test, int iteration) override
	{
   
      cout << "suites- tests:" << unit_test.reportable_test_count()
               << "|failures:" << unit_test.failed_test_count() 
               << "|disabled:" << unit_test.reportable_disabled_test_count()
               << "|random_speed:" << unit_test.random_seed()
               << "|timestamp:" << unit_test.start_timestamp()
               << "|time:" << unit_test.elapsed_time() << "|"
               << endl;
      for (int i = 0; i < unit_test.ad_hoc_test_result().test_property_count();
           ++i) {
        const TestProperty& property = unit_test.ad_hoc_test_result().GetTestProperty(i);
         cout<< property.key() << "\": "
                   << property.value() << "\"";
      
      }
	}
};

int main(int argc,char** argv)
{
     InitGoogleTest(&argc, argv);
     UnitTest* ut = UnitTest::GetInstance();
     myclass* mc = new myclass;
     ut->listeners().Append(mc);
     ut->Run();
}

由于XmlUnitTestResultPrinter这个类对用户是不可见的,所以我们无法使用它的格式化方法,不过既然所有的结果信息我们都能拿到,自己来格式化也不是难事,可以按需要格式化为json,xml或者html.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值