算法工程师的加分技能,使用GTest维护自己的代码

来自百度百科的介绍:
gtest,测试框架,是在不同平台上(Linux,Mac OS X,Windows,Cygwin,Windows CE和Symbian)为编写C++测试而生成的。
它是基于xUnit架构的测试框架,支持自动发现测试,丰富的断言集,用户定义的断言,death测试,致命与非致命的失败,类型参数化测试,各类运行测试的选项和XML的测试报告。

现在对于工程师的要求,不仅仅是写代码,自己还要兼顾单元测试,猝!博主也是现学现卖,算是记录一下小白的学习过程吧~

GTest可以对业务代码直接测试,而有不会使原有的代码变得繁琐,因为在Cmake工程中,GTest只是作为其一个子工程,不会影响原有的代码结构。那么第一步就是需要,在原有的工程里,添加一个子工程!

add_subdirectory(test)

具体的资料可参考:cmake(六)Cmake添加工程子目录,当然在test工程里也需要写一个自己的 CMakeLists。

enable_testing()

随后项目的cmake配置文件中可以添加add_test指令

add_test(NAME <name> [CONFIGURATIONS [Debug|Release|...]]
           [WORKING_DIRECTORY dir]
           COMMAND <command> [arg1 [arg2 ...]])

为当前及其下级目录打开测试功能。也可参见add_test命令

关于 CMakeLists 特殊的部分已经介绍完了,还有一些要注意的地方,我在使用GTest时,是把要测试的代码编写成一个共享库,这样就不需要链接太多的源代码文件,也就是在外层的 CMakeLists 中,把需要测试的源代码编进去。

add_library(${PROJECT_NAME} SHARED
  src/XXX.cpp
)
target_link_libraries(test_label XXX.so)

然后在Test工程中,把该库链接进去就行了,除此之外,我也把 相关的文件链接进去。虽然现在用不上,慢慢摸索了!

# gtest依赖库
target_link_libraries(test gtest)
target_link_libraries(test gtest_main)
# gmock依赖库
target_link_libraries(test gmock)
target_link_libraries(test gmock_main)
# mockcpp依赖库
target_link_libraries(test mockcpp)

使用 GTest 库,所以 继承了其中的基类,我们只需要在里面调用我们想测试的函数,TestSomeThing 用于区分不同的 测试用例。

class Test:public testing::Test
{
    
    
protected:
    /* TestSuite级别的,在某一批案例中第一个案例前,最后一个案例执行后。 */
    static void SetUpTestCase()
    {
    
    
    }
    static void TearDownTestCase()
    {
    
    
    }
    /* TestCase级别的,每个TestCase前后 */
    virtual void SetUp()
    {
    
    
    }
    virtual void TearDown()
    {
    
    
    }
};

TEST(Test, TestSomeThing){
    
    
	//Test....
}

然后就是GTest中常用方法:

EXPECT_EQ (X,Y) 判断是否相等
EXPECT_NEAR(deltaX, 0 ,0.15);	判断是否在一定范围内

那么如果,我们想改变原有函数的方法,让其返回值是我们想要的返回值,就需要用到 gmock 或者 mockcpp 工具,以 mockcpp 为例:

首先,我们需要定义一个相同的函数,相同的函数名和相同的参数列表,详细可参考MockCpp介绍与应用实例,那么就写一个简单的小例子:

int add(int x,int y){
    
    
	 return x+y;
}

MOCKER(add)
  .stubs()
  .with(eq(1), eq(2))
  .id("first");
  .will(returnValue(30));

意思就是,传入参数为 12 时,让其返回值为 30,这样可以改变原有函数的逻辑,按照我们制定的路径去测试代码。定义 id 便可以规定其每次返回的返回值,比如第一次为30,第二次为20,那么可以再定义一个MOCKER,就可以把第三行改为 .after("first") 。如果没有返回值的话,也就不需要加第三行了。

该做法也有一个更为生动的称号,打桩!打桩就不会运行原函数,而是运行我们定义的 MOCKER 的规则,达到可以随意改变返回值的目的,控制测试的路线。


目前就用到了这些基础知识,边学边记录,如有问题欢迎大佬指正!

猜你喜欢

转载自blog.csdn.net/qq_39266065/article/details/123562144