[单元测试]_[Gtest中级使用教程]


场景:

1. 单元测试在开发中保证程序质量是必修课,快速编写单元测试是能节约不少时间。

2. C++的单元测试框架gtest是测试的首选,简单,轻量,快速。

3. 开发时,对项目源码进行测试需要新建分离的单元测试项目,以下就是用python脚本直接创建单元测试项目的模板,模板里包括常用的单元测试断言和辅助类,这个是使用Makefile做编译配置的,如果需要生成vs的项目,建议使用google的gyp.


说明: 运行Init.py会在当前文件夹生成模板Makefile文件,include目录生成main.h文件,src目录生成main.cpp和test_xx.cpp模版测试文件.在windows上,我用的MinGW的gcc编译器和msys的makefile.




文件 Init.py

#! encoding=utf-8

import re
import os
import sys

kMakefile = '''
#Makefile template

OBJECTDIR=build/Debug

objects = \\
    ${OBJECTDIR}/src/main.o \\
    ${OBJECTDIR}/src/test_xx.o

# CC Compiler Flags
CXXFLAGS=-m32 -g -Wall -MMD -MP -MF $@.d
CPPFLAGS=-Iinclude \\
-I../../include \\
-I/E/software/Lib/tests/gtest-1.5.0/win32/release/static/include-compile \\
-I/E/software/Lib/tests/gtest-1.5.0/win32/release/static/include

# Link Libraries and Options
LDLIBSOPTIONS=-L/E/software/Lib/tests/gtest-1.5.0/win32/release/static -lgtest \\
-static-libgcc

all: ${objects}
    mkdir -p dist
    ${CXX} -m32 -o dist/app ${objects} ${LDLIBSOPTIONS}

${objects}: ${OBJECTDIR}/%.o: %.cpp
    mkdir -p $(dir $@)
    rm -fr $@.d
    $(COMPILE.cc) $< -o $@

clean:
    rm -fr build
    rm -fr dist
'''

kMainHeader = '''
#ifndef MAIN_H
#define    MAIN_H

extern int kArgc;
extern char** kArgv;

#endif    /* MAIN_H */
'''

kMainSrc = '''

#include "main.h"

#include <stdio.h>
#include <assert.h>
#include <string>
#include "gtest/gtest.h"


int kArgc;
char** kArgv;


int main(int argc, char **argv)
{
    setbuf(stdout,(char*)0);
    setbuf(stderr,(char*)0);
    kArgc = argc;
    kArgv = argv;
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

// 在 googletest 中实现单元测试,可通过 ASSERT_* 和 EXPECT_* 
// 断言来对程序运行结果进行检查。 ASSERT_* 版本的断言失败时会产生致命失败,
// 并结束当前函数; EXPECT_* 版本的断言失败时产生非致命失败,但不会中止当前函数。
// 因此, ASSERT_* 常常被用于后续测试逻辑强制依赖的处理结果的断言,
// 如创建对象后检查指针是否为空,若为空,则后续对象方法调用会失败;
// 而 EXPECT_* 则用于即使失败也不会影响后续测试逻辑的处理结果的断言,
// 如某个方法返回结果的多个属性的检查。
TEST(test_main,TestBaseAssert)
{
    ASSERT_TRUE(__LINE__);
    EXPECT_TRUE(__LINE__);

    ASSERT_FALSE(false);
    EXPECT_FALSE(false);
}

TEST(test_main,TestBinaryAssert)
{
    const char* str = "11";

    ASSERT_EQ(str,str);
    EXPECT_EQ(false,0);

    ASSERT_NE(str,str+1);
    EXPECT_NE(false,1);

    ASSERT_LT(str,str+1);
    EXPECT_LT(0x1,0x2);

    ASSERT_LE(0x1,0x2);
    EXPECT_LE(0x1,0x2);

    ASSERT_GT(0x2,0x1);
    EXPECT_GT(0x2,0x1);

    ASSERT_GE(0x2,0x1);
    EXPECT_GE(0x2,0x1);
}

TEST(test_main,TestStrAssert)
{
    const char* str = "11ab";
    std::string str2("11ab");
    std::string str21("11aB");

    ASSERT_STREQ(str,str2.c_str());
    EXPECT_STREQ(str,str2.c_str());

    ASSERT_STRNE(str,str21.c_str());
    EXPECT_STRNE(str,str21.c_str());

    ASSERT_STRCASEEQ(str,str21.c_str());
    EXPECT_STRCASEEQ(str,str21.c_str());

    str21.append("!");
    ASSERT_STRCASENE(str,str21.c_str());
    EXPECT_STRCASENE(str,str21.c_str());
}
'''

kTestXXSrc = '''
#include "main.h"

#include <stdio.h>
#include <assert.h>
#include <string>
#include "gtest/gtest.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-port.h"

using std::string;
using ::testing::internal::FilePath;
using ::testing::Message;

TEST(test_xx,XX)
{
    FilePath path(kArgv[0]);
    FilePath currentDir = path.GetCurrentDir();
    Message message("currentDir is: ");
    message << currentDir.ToString();
    GTEST_LOG_(INFO) << message ;
    GTEST_LOG_(INFO) << ".............." ;
}
'''

if __name__=='__main__':
    
    # makefile
    global kMakefile
    global kMainHeader
    global kMainSrc
    global kTestXXSrc

    file = open("Makefile","w")
    file.write(kMakefile)
    file.close()

    # dirs
    try:
        os.mkdir("include")
        os.mkdir("src")
    except Exception, e:
        pass

    # sample code
    file = open("./src/main.cpp","w")
    file.write(kMainSrc)
    file.close()

    file = open("./src/test_xx.cpp","w")
    file.write(kTestXXSrc)
    file.close()

    file = open("./include/main.h","w")
    file.write(kMainHeader)
    file.close()




运行模版代码的单元测试输出:




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Peter(阿斯拉达)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值