基于GoogleTest的测试框架打造

gTest提供了很多功能方便了单元测试,但是有时候我们需要将测试代码和测试数据分离,便于维护测试数据。或者需要用多组用例对同一个测试代码测试,尽管可以用gtest的参数化的方法达到一些效果,但是参数化最多只能提供50组用例,数量有限制,且客户端为每一个参数需要写大量重复代码,服用了极低。所以,有些情况我们需要打造自己的测试框架。为了方便起见(其实也是我偷懒),假定读者已经对GTEST源码有初步了解,这里直接截取相关片段,不做详细代码解读。
首先研究gtest源码

   ::testing::internal::MakeAndRegisterTestInfo(                              \
          #test_suite_name, #test_name, nullptr, nullptr,                     \
          ::testing::internal::CodeLocation(__FILE__, __LINE__), (parent_id), \
          ::testing::internal::SuiteApiResolver<                              \
              parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__),         \
          ::testing::internal::SuiteApiResolver<                              \
              parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__),      \
          new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_(    \
              test_suite_name, test_name)>); 

这是将测试单元名称等地信息进行注册。这里最后一个参数,我们可以传递一个继承父类的自定义子类,这样就可以实现将我们需要的参数都传递进去。比如,最后一个参数我们可以改成如下: new ZcGtestFactory(mytestInfo), mytestInfo是testInfo类型,ZCGtestFactory定义为:

class ZcGtestFactory : public ::testing::internal::TestFactoryBase{
public:
    ZcGtestFactory(testInfo& v):_testRegInfo(v){}
    virtual ::testing::Test* CreateTest(){
        context ctx;
       //some code...
       return _testRegInfo.creator(ctx);
    }
private:
    testInfo _testRegInfo;
}

context定义为:

struct context{
    string testDesc;
    string inputFilePath;  //输入参数的文件的路径
    string outputFilePath;  //输出参数的文件的路径
}

这里的testInfo就是我们自定义的参数结构,可以包含诸如用例ID,模块名等信息。我们这里定义为:


typedef ::testing::Test* (*TestCreator)(context&);
struct testInfo
{
   std::string module;
   unsigned int testNo;
   std::string testDesc;
   bool isSelected;
   TestCreattor creator;
};

creator就是 Test* (*)(context&) 类型的函数指针,我们用这种结构的函数初始化。由于所有测试单元函数都是这种结构,所以可以写一个模板类,模板参数为测试函数。如下:


typedef void*TestBodyFunc)(context&)
template<TestBodyFunc testFunction> 
class ZcTest : public ::testing::Test
{
public:
    ZcTest(context& ctx):_ctx(ctx){}
    void void TestBody(){
        testFunction(_ctx);
    }
     static ::testing::Test* ZcTest_Create(context& ctx)
     {
         return new ZcTest<testFunction>(ctx);
     }
 private:
    context _ctx;
}

假设测试单元函数为:

void TestA(context& ctx)
{
//some code
}

则可以按如下构造testInfo

testInfo myTestInfo;
myTestInfo.creator = ZcTest<TestA>::ZcTest_Create;

testInfo有了,则开头那里注册的地方就可以替换为:

 ::testing::internal::MakeAndRegisterTestInfo(
            testRegInfo.testName.c_str(),
            ("Test" + std::to_string(v)).c_str(),
            nullptr,
            nullptr,
            ::testing::internal::CodeLocation(__FILE__, __LINE__),
            ::testing::internal::GetTestTypeId(),
            ::testing::Test::SetUpTestCase,
            ::testing::Test::TearDownTestCase,
            new ZcGtestFactory(myTestInfo));

这样,我们把自定义的包含测试用例号等信息地testInfo成功地加入到注册函数中,这样,测试用例数据我们可以保存在文件当中,成功地将测试单元代码和测试用例数据分离。 可以将上述代码进一步封装,达到模块解耦地效果,目的都是将测试单元代码和用例数据分离,这里不在赘述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于Google Test单元测试,你可以在C++项目中使用Google Test框架来编写和运行单元测试。 首先,你需要在项目中包含Google Test库。你可以从Google Test的官方GitHub仓库下载最新版本的源代码,并将其添加到你的项目中。 在编写单元测试之前,你需要创建一个测试文件。这个文件应该包含一个或多个测试用例,每个测试用例都是一个函数。你可以使用Google Test提供的宏来定义和运行测试用例。 一个简单的示例代码如下: ```c++ #include <gtest/gtest.h> // 定义一个测试用例 TEST(ExampleTest, Addition) { int a = 2; int b = 3; int result = a + b; EXPECT_EQ(result, 5); } // 定义另一个测试用例 TEST(ExampleTest, Subtraction) { int a = 5; int b = 3; int result = a - b; EXPECT_EQ(result, 2); } int main(int argc, char** argv) { // 初始化 Google Test 框架 ::testing::InitGoogleTest(&argc, argv); // 运行所有的测试用例 return RUN_ALL_TESTS(); } ``` 在这个例子中,我们定义了两个测试用例:Addition和Subtraction。每个测试用例都包含一些断言,用于验证预期结果和实际结果是否相等。在main函数中,我们初始化Google Test框架并运行所有的测试用例。 要编译和运行这个测试文件,你需要将Google Test库链接到你的项目中。具体的编译和链接过程可能因你使用的开发环境而有所不同。 当你运行这个测试文件时,Google Test将会执行所有的测试用例,并输出测试结果。如果所有的断言都通过了,测试将会被标记为通过;否则,测试将会被标记为失败,并显示详细的错误信息。 这只是一个简单的示例,Google Test还提供了很多其他的功能和特性,例如测试夹具、参数化测试测试报告等。你可以查阅Google Test的官方文档以获取更多信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值