google test 是一个开源代码测试框架,主要用于单元测试。代码可以从
GitHub - google/googletest: GoogleTest - Google Testing and Mocking Framework
获得。
下面以一个简单的例子来说明如何使用google test.
1. 编译源代码:
cmake -DCMAKE_INSTALL_PREFIX=$HOME/install/gtest/ ..
make
make install
2. 编写待测试的代码:
~/code/gtest_example/example$ tree src/
src/
├── Addition.cpp
├── Addition.hpp
├── ExampleApp.cpp
├── Makefile
├── Multiply.cpp
└── Multiply.hpp
0 directories, 6 files
$ cat Addition.hpp
#ifndef _ADDITION_HPP_
#define _ADDITION_HPP_
class Addition
{
public:
static int twoValues(const int x, const int y);
};
#endif
$ cat Addition.hpp
#ifndef _ADDITION_HPP_
#define _ADDITION_HPP_
class Addition
{
public:
static int twoValues(const int x, const int y);
};
#endif
charles@xiaotao:~/code/gtest_example/example/src$ cat Addition.cpp
#include "Addition.hpp"
int
Addition::twoValues(const int x, const int y)
{
return x + y;
}
$ cat Multiply.hpp
#ifndef _MULTIPLY_HPP_
#define _MULTIPLY_HPP_
class Multiply
{
public:
static int twoValues(const int x, const int y);
};
#endif
$ cat Multiply.cpp
#include "Multiply.hpp"
int
Multiply::twoValues(const int x, const int y)
{
return x * y;
}
$ cat ExampleApp.cpp
#include "Addition.hpp"
#include "Multiply.hpp"
#include <stdio.h>
int main()
{
int x = 4;
int y = 5;
int z1 = Addition::twoValues(x,y);
printf("\nAddition Result: %d\n", z1);
int z2 = Multiply::twoValues(x,y);
printf("Multiply Result: %d\n", z2);
return 0;
}
c$ cat Makefile
CXX = arm-linux-gnueabi-g++
CXXFLAGS = -g
INCS = -I./
OBJS = Addition.o Multiply.o
exampleapp: ExampleApp.cpp $(OBJS)
$(CXX) $(CXXFLAGS) -o exampleapp ExampleApp.cpp $(OBJS)
.cpp.o:
$(CXX) $(CXXFLAGS) -c $< -o $@ $(INCS)
clean:
rm *.o exampleapp gmon.out
3. 编写测试代码:
:~/code/gtest_example/example/test$ tree src/
src/
├── Addition_Test.cpp
├── Addition_Test.o
├── Main_TestAll.cpp
├── Makefile
├── Multiply_Test.cpp
├── Multiply_Test.o
└── testAll
0 directories, 7 files
$ cat Multiply_Test.cpp
#include <limits.h>
#include "gtest/gtest.h"
#include "Multiply.hpp"
class MultiplyTest : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
}
};
TEST_F(MultiplyTest,twoValues){
const int x = 4;
const int y = 5;
Multiply multiply;
EXPECT_EQ(20,multiply.twoValues(x,y));
EXPECT_EQ(6,multiply.twoValues(2,3));
}
$ cat Addition_Test.cpp
#include <limits.h>
#include "gtest/gtest.h"
#include "Addition.hpp"
class AdditionTest : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
// Code here will be called immediately after each test
// (right before the destructor).
}
};
TEST_F(AdditionTest,twoValues){
const int x = 4;
const int y = 5;
Addition addition;
EXPECT_EQ(9,addition.twoValues(x,y));
EXPECT_EQ(5,addition.twoValues(2,3));
}
$ cat Addition_Test.cpp
#include <limits.h>
#include "gtest/gtest.h"
#include "Addition.hpp"
class AdditionTest : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
// Code here will be called immediately after each test
// (right before the destructor).
}
};
TEST_F(AdditionTest,twoValues){
const int x = 4;
const int y = 5;
Addition addition;
EXPECT_EQ(9,addition.twoValues(x,y));
EXPECT_EQ(5,addition.twoValues(2,3));
}
$ cat Main_TestAll.cpp
#include <limits.h>
#include "gtest/gtest.h"
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
$ cat Makefile
CXX = arm-linux-gnueabi-g++
CXXFLAGS = -g -L/home/charles/code/googletest/googlemock/cmake -L/home/charles/code/googletest/googlemock/cmake/gtest -lgtest -lgtest_main -lpthread
INCS = -I../../src -I/home/charles/code/googletest/googletest/include
OBJS = ../../src/Addition.o Addition_Test.o ../../src/Multiply.o Multiply_Test.o
testAll: $(OBJS)
$(CXX) $(INCS) -o testAll Main_TestAll.cpp $(OBJS) $(CXXFLAGS)
.cpp.o:
$(CXX) $(CXXFLAGS) -c $< -o $@ $(INCS)
clean:
rm testAll *.o testAll.xml
运行结果:
#./testAll
[==========] Running 2 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 1 test from AdditionTest
[ RUN ] AdditionTest.twoValues
[ OK ] AdditionTest.twoValues (7 ms)
[----------] 1 test from AdditionTest (11 ms total)
[----------] 1 test from MultiplyTest
[ RUN ] MultiplyTest.twoValues
[ OK ] MultiplyTest.twoValues (1 ms)
[----------] 1 test from MultiplyTest (2 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 2 test cases ran. (46 ms total)
[ PASSED ] 2 tests.
按照下面的方式执行,会产生一个包含测试结果的xml文件:
testAll --gtest_output="xml:./testAll.xml"
googletest 支持 TEST(class,test_name) 和 TEST_F(class,test_name). 后一种方式是测试框架方式。
代码覆盖率统计:
gcc 加上 编译参数 fprofile-arcs -ftest-coverage -lgcov
编译后生成 gcno文件,可执行文件执行后生成gcda文件。
之后执行命令:
lcov -d . -c -o test.info -b .
genhtml -o result test.info
在 result 目录下生成 index.html.
用浏览器打开就能看到可视化的测试结果
References: