一个单元测试是一段自动化的代码,这段代码调用被测试的工作单元,之后对这个单元的单个最终结果的某些假设进行验证。
google提供的开源单元测试框架,支持c/c++等。本示例从多目录cmake着手,说明如何实现单元测试,代码亲测可行。
一.google test安装方法
$gitclonehttps://github.com/google/googletest.git
$cd googletest
$mkdirbuild
$cd build
$cmake…
$make
$sudomake install
二.示例代码的文件结构
├──CMakeLists.txt //工程顶层
├──inlude
│ ├── func.h
├──src
│ ├── CMakeLists.txt
│ └── main.c //实际使用时调用所测试函数的地方
├──lib
│ ├── CMakeLists.txt
│ └── func.c //所测试的函数定义的地方
└──tests
├── CMakeLists.txt
└── funcTest.cc //对所测试的函数进行单元测试的地方
三.各层CMakeLists.txt编写
1.顶层CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
#for googletest
option(BUILD_TESTING “build google test” OFF)
if(BUILD_TESTING)
enable_testing() //单开单元测试开关
endif(BUILD_TESTING)
project(unitTest) //unitTest为工程名字,名字可随意
add_subdirectory(src bin) //cmake和make时src文件夹的生成物会放到build/bin下面
add_subdirectory(lib) //lib文件夹的生成物会放到build/lib
if(BUILD_TESTING)
add_subdirectory(tests) //tests文件夹的生成物会放到build/tests
endif()
2. src文件夹下的CMakeLists.txt
include_directories(…/include) //包含头文件,否则make的时候会找不到所调函数
add_executable(main main.c) //生成可执行二进制文件main
LINK_DIRECTORIES(lib) //链接库文件的目录
TARGET_LINK_LIBRARIES(main func) //链接库文件,相当于-lfunc
3. lib文件夹下的CMakeLists.txt
include_directories(…/include) //包含头文件,否则make的时候会找不到所调函数
add_library(func func.c) //生成静态库libfunc.a
install(TARGETS func ARCHIVE DESTINATION lib) //将库文件libfunc.a安装到build/lib
4. tests文件下的CMakeLists.txt
include_directories(…/include)
set(CMAKE_CXX_FLAGS “${CMAKE_CXX_FLAGS} -std=c++14”)
set(LIBS ${LIBS} func gtest gtest_main pthread) //此处是调用的库名,一个也别丢,否则就会make出错
add_executable(funcTest funcTest.cc)
target_link_libraries(funcTest ${LIBS})
add_test(funcTest
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/funcTest)
四.源代码编写
1.lib文件夹下的func.c
#include <stdio.h>
#include <math.h>
#include “func.h”
int addFunc() //函数定义实现
{
int a, b, sum;
a = 4;
b = 6;
sum = a + b;
return sum;
}
int minusFunc()
{
int a, b, minus;
a = 12;
b = 3;
minus = a - b;
return minus;
}
2. src文件夹下main.c
#include <stdio.h>
#include <math.h>
#include “func.h”
void main()
{
printf(“I want to run google unit test!==========\n”);
printf(“SUM = %d\n”, addFunc());
printf(“MINUS = %d\n”, minusFunc());
}
3. include头文件func.h
#ifndef FUNC_H
#define FUNC_H
int addFunc(); //函数说明
int minusFunc();
#endif
4. tests文件夹下的funcTest.cc编写
#include <gtest/gtest.h>
extern “C”{ //此处很关键,因为单元测试是C++,调用所测试函数时候要包含C头文件
#include “func.h”
}
TEST(funcTest, addRight)
{
EXPECT_EQ(10, addFunc());
}
TEST(funcTest, addError)
{
EXPECT_NE(11, addFunc());
}
TEST(funcTest, minusRight)
{
EXPECT_EQ(9, minusFunc());
}
TEST(funcTest, minusError)
{
EXPECT_NE(1, minusFunc());
}
五.编译运行测试
在顶层目录下,创建bulid目录
mkdir build
cd build
cmake -DBUILD_TESTING=TRUE … //打开单元测试开关
make //编译时候会有ld链接问题,一定要在CMakeLists.txt文件里写好头文件路径
(此时build文件下会生成lib , bin , tests三个文件夹以及Cmake产物,只关心lib/libfunc.a, bin/main)
make test //成功执行单元测试
./bin/main