首页 > 其他分享 >gtest测试用例打印台内容重定向

gtest测试用例打印台内容重定向

时间:2023-01-23 12:31:25浏览次数:34  
标签:case const name 打印台 GTEST TEST gtest 测试用例 test

需求描述

在使用 ​​gtest​​ 做测试时,有时候需要记录测试过程中,测试对象运行时打印在控制台的相关内容,并根据打印的内容做校验,判断用例是否通过。

由于测试用例很多,我们希望能够根据测试集合和测试用例,自行建立具有层级关系的目录文件夹,将打印的内容以 txt 文档格式保存起来,便于后期整理测试报告。

需求分析

为解决上述需求,拆解出两个待实现功能:

  1. 打印内容重定向
  2. 测试集合和测试用例的名字获取

功能1:打印台内容重定向。

使用 ​​freopen​​来实现。以下是一个小 demo。

int conSoleId; 
char logSaveFile[50] = "log.txt";
// [1]. 记录打印台id
conSoleId = dup(1);
// [2]. 控制台信息重定向到文本
FILE* fp = freopen(logSaveFile, "w", stdout);
// [3]. 测试代码
// your test code here
// [4]. 重新定向到控制台
dup2(conSoleId, 1);

功能2:测试集合和测试用例的名字获取。

gtest 的 TEST_F 是预处理宏定义,通过一层层的分析代码调用关系,可以发现,我们使用该宏时,实际上是先根据输入的测试集合和测试用例名字构建类,使之构成继承关系。接着注册用例信息,最后再把类中的测试内容函数​​TestBody()​​留给我们自己来写测试内容。

  • 首先 TEST_F 的内容实际由 GTEST_TEST_ 来实现
#define TEST_F(test_fixture, test_name)\
GTEST_TEST_(test_fixture, test_name, test_fixture, \
::testing::internal::GetTypeId<test_fixture>())
  • 然后 GTEST_TEST_ 组织代码,实现了类的继承,和类内成员变量、函数的构建,最后将 ​​TestBody()​​ 函数体的具体内容交给使用者去定义。
// Helper macro for defining tests.
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
public:\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
};\
\
::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\
::test_info_ =\
::testing::internal::MakeAndRegisterTestInfo(\
#test_case_name, #test_name, NULL, NULL, \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
(parent_id), \
parent_class::SetUpTestCase, \
parent_class::TearDownTestCase, \
new ::testing::internal::TestFactoryImpl<\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\
void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody()

在该类中的成员变量类型 TestInfo,定义如下:

class GTEST_API_ TestInfo {
public:
// Destructs a TestInfo object. This function is not virtual, so
// don't inherit from TestInfo.
~TestInfo();

// Returns the test case name.
const char* test_case_name() const { return test_case_name_.c_str(); }

// Returns the test name.
const char* name() const { return name_.c_str(); }

// Returns the name of the parameter type, or NULL if this is not a typed
// or a type-parameterized test.
const char* type_param() const {
if (type_param_.get() != NULL)
return type_param_->c_str();
return NULL;
}

其中的 ​​test_case_name()​​​ 可获取测试集合名,​​name()​​ 可获取测试用例名。

因此在测试内容部分,我们可这样获取测试集合名和测试用例名:

TEST_F(PROCUT_TEST_EXAMPLE, say_hello)
{
char test_case_name[50] = this->test_info_->test_case_name();
char test_name[50] = this->test_info_->name();
}

需求实现

为了便于使用,将以上代码整合成一组宏:

// 测试结果存放的目录路径
std::string rootPath = "..\\..\\..\\data\\sit_test";

#define CONSOLE_TO_TXT_START \
int conSoleId;\
char logSavePath[100],mkDirCmd[100],nowTime[100],logSaveFile[100];\
sprintf(logSavePath,"%s\\%s\\%s",rootPath.c_str(),this->test_info_->test_case_name(),test_info_->name());\
sprintf(mkDirCmd,"if not exist \"%s\" (mkdir \"%s\")",logSavePath,logSavePath);\
system(mkDirCmd);\
time_t t = time(nullptr);\
struct tm* now = localtime(&t);\
strftime(nowTime, sizeof(nowTime), "%Y_%m_%d@%H_%M_%S", now);\
sprintf(logSaveFile,"%s\\log_%s.txt",logSavePath,nowTime);\
conSoleId = dup(1);\
FILE* fp = freopen(logSaveFile, "w", stdout);\
fflush(fp);\

#define CONSOLE_TO_TXT_END \
dup2(conSoleId, 1);\

在使用时可以这样调用:

TEST_F(PROCUT_TEST_EXAMPLE, say_hello)
{
CONSOLE_TO_TXT_START
// your test code here
CONSOLE_TO_TXT_END
SUCCEED();
}

这样我们在运行完该用例后,可以在 "..\..\..\data\sit_test\PROCUT_TEST_EXAMPLE\say_hello"路径下获得一份名字形如 ​​log_2023_01_15@13_21_49.txt​​ 的文档。

参考资料

  • ​​linux c 重定向流后的恢复 freopen后的恢复_whatday的博客

未经作者授权,禁止转载

THE END



标签:case,const,name,打印台,GTEST,TEST,gtest,测试用例,test
From: https://blog.51cto.com/gshang/6021878

相关文章

  • Pytest - 测试用例管理及运行管理
    目录跳过测试用例@pytest.mark.skip装饰器跳过测试用例常用的标记有以下几种:skip:只有当某些条件满足时,才执行测试用例,否则跳过整个测试用例的执行xfail:因为一个确切......
  • 8. Pytest跳过某个测试用例:skip和skipif
    一、前言skip和skipif,看名字就是跳过测试的意思,主要用于不想执行的代码,标记后,标记的代码不执行。希望满足某些条件才执行某些测试用例,否则pytest会跳过运行该测试用例......
  • 软件测试用例设计方法及设计规范
      第三章软件测试用例设计方法及设计规范1.测试用例的定义 测试用例(Testcase)是为了实施测试而向被测试的系统提供的一组合集 测试点测试场景 集合包括: 测试环境/......
  • gtest测试用例打印台内容重定向
    需求描述在使用gtest做测试时,有时候需要记录测试过程中,测试对象运行时打印在控制台的相关内容,并根据打印的内容做校验,判断用例是否通过。由于测试用例很多,我们希望能够......
  • c++ unit test via gtest
    //model/book.h#pragmaonce#include<iostream>usingnamespacestd;classbook{public:book()=default;~book()=default;book(constbook&......
  • gtest
    提供两种判断的宏EXPECT_XXX()(推荐使用) ASSERT_XXX()(出错直接crash)分组测试#include<gtest/gtest.h>intFactorial(intn){intresult=1;for(inti=1......
  • Selenium 测试用例编写
    ​​原文链接​​编写Selenium测试用例就是模拟用户在浏览器上的一系列操作,通过脚本来完成自动化测试。编写测试用例的优势:开源,免费。支持多种浏览器IE,Firefox,Chrome,Safar......
  • Docker搭建测试用例平台 TestLink
    Testlink是基于WEB的测试用例管理系统,主要功能是:测试项目管理、产品需求管理、测试用例管理、测试计划管理、测试用例的创建、管理和执行,并且还提供了统计功能。Testlink......
  • Selenium62-使用POM的测试用例
    添加赛区脚本test_后台_双创_基础设置_赛区管理_添加赛区_case_v7.py导入各个网页对象改造to_division_manager导入各个网页对象导入各个网页对象:frompage.后台_主页_page......
  • 5.测试用例
    测试用例TestCase作用:为特定的目的而设计的一组测试输入、执行条件和预期结果的文档  测试用例八大要素用例编号用例标题所属项目用例级别预置条件测试......