googlegtest C++测试框架搭建以及测试用例使用

本文章所有测试都已经在CentOS7.x 版本验证通过, 本文所使用的命令以及安装环境均为CentOS7.x系统。

googlegtest 下载地址:https://github.com/google/googletest

如果已经配置了git,直接git clone https://github.com/google/googletest gtest(本地目录名)

一、编译googletest

0) 拷贝gtest 至 /opt目录下,这个根据个人喜好,随便放在哪都可以

1) 进入gtest(该名字是由我git clone时自己定义的名字,各位根据自己实际情况而定)目录

                 cd gtest

2) 安装googletest  (如果自己想了解官方安装建议过程,参考 官方安装文档(gtest/googletest/README.md))

            mkdir  build

            cd build

            cmake ..  (..表示上层目录,即gtest主目录,   cmake ..  -DBUILD_GMOCK=OFF表示不编译google_mock)

            make

            make install  //default  install in /usr/local

至此googletest已经编译完成,生成的相关头文件放在 /usr/local/include 目录下,生成的库文件放在 /usr/local/lib64目录下,如下图所示:

                                                                                                                                              图1 生成的头文件

                                                                                                                                             图2 生成的gtest库

二、测试Gtest

谷歌官方提供了部分参考示例,示例路径为: /opt/gtest/googletest/samples (下载的googletest源码目录,该路径根据自己的事情情况而定)

根据谷歌官方文档,结合实际情况,编写了一个简单的测试用例框架,供自己学习记录所用,防止后续忘记,毕竟,好记性不如烂笔头,开始:

我的代码目录架构为:

                                                                                                                                              图3 目录架构

sample1目录下代码:

CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 3.0)

PROJECT(sample1)

FILE(GLOB src
"${sample1_dir}/*.cpp"
)

SET(CMAKE_CXX_FLAGS				"${CMAKE_CXX_FLAGS} -std=c++11")

ADD_LIBRARY(${PROJECT_NAME} SHARED ${src})
sample1.h

#ifndef GTEST_SAMPLE1_GOOGLE
#define GTEST_SAMPLE1_GOOGLE

int Factorial(int n);

bool IsPrime(int n);



#endif
sample1.cpp

#include "sample1.h"
#include <iostream>

int Factorial(int n)
{
	int result = 1;
	for (int i = 1; i <= n; ++i)
	{
		result *= i;
	}

	return result;
}

bool IsPrime(int n)
{
	if (n <= 1)
		return false;
	if(n%2 == 0)
		return n == 2;
	for (int i = 3; ; i += 2)
	{
		if(i > n/i)
			break;
		if (n % i == 0)
		{
			return false;
		}
	}

	return true;
}

外层目录代码:

build.sh

#!/bin/bash

if [[ -d "build" ]]; then
	rm -rf "build"
fi

mkdir build
cd build

cmake ..
make -j4
CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.0)

PROJECT(gtest_app)

SET(cur_dir			${CMAKE_CURRENT_SOURCE_DIR})
SET(sample1_dir		"${cur_dir}/sample1")
SET(gtest_root_dir		"/usr/local")

SET(CMAKE_CXX_FLAGS		"${CMAKE_CXX_FLAGS} -std=c++11 -g -w -O2 -pthread")

INCLUDE_DIRECTORIES(
"${gtest_root_dir}/include"
"${sample1_dir}"
)

FILE(GLOB  app
"${cur_dir}/*.cpp"
)

LINK_DIRECTORIES(
"${gtest_root_dir}/lib64"
)

ADD_SUBDIRECTORY(${sample1_dir}	sample1)

ADD_EXECUTABLE(${PROJECT_NAME} ${app})

TARGET_LINK_LIBRARIES(${PROJECT_NAME}  gtest sample1 pthread)
main.cpp

#include <iostream>
#include <algorithm>
#include <thread>
#include <mutex>
#include <string.h>
#include <vector>
#include "gtest/gtest.h"
#include "limits.h"
#include "sample1.h"

using namespace std;

namespace{

	std::vector<int> global_v;

TEST(FactorialTest, Negative)
{
	EXPECT_EQ(1, Factorial(-5));
	EXPECT_EQ(1, Factorial(-1));
	EXPECT_GT(Factorial(-10), 0);
}

TEST(FactorialTest, Zero)
{
	EXPECT_EQ(1, Factorial(0));
}

TEST(FactorialTest, Positive)
{
	EXPECT_EQ(1, Factorial(1));
	EXPECT_EQ(2, Factorial(2));
	EXPECT_EQ(6, Factorial(3));
}

//TEST IsPrime()

TEST(IsPrimeTest, Negative)
{
	EXPECT_FALSE(IsPrime(-1));
	EXPECT_FALSE(IsPrime(-2));
	EXPECT_FALSE(IsPrime(INT_MIN));
}

TEST(IsPrimeTest, Trivial)
{
	EXPECT_FALSE(IsPrime(0));
	EXPECT_FALSE(IsPrime(1));
	EXPECT_TRUE(IsPrime(2));
	EXPECT_TRUE(IsPrime(3));
}

TEST(IsPrimeTest, Positive)
{
	EXPECT_FALSE(IsPrime(4));
	EXPECT_TRUE(IsPrime(5));
	EXPECT_FALSE(IsPrime(6));
	EXPECT_TRUE(IsPrime(23));
}


struct VectorTest : ::testing::Test
{
	void SetUp()
	{
		for (int i = 0; i < 10; ++i)
		{
			global_v.push_back(i);
		}
		cout<<"SetUp ............ "<<endl;
	}

	void TearDown()
	{
		global_v.clear();
		cout<<"TearDown ............ "<<endl;
	}

	static void PushElements(int start_num, int len)
	{
		for (int i = start_num; i < (start_num+len); ++i)
		{
			global_v.push_back(start_num);
		}
	}

	~VectorTest(){}

};

TEST_F(VectorTest, test_init_vector_size)
{
	EXPECT_EQ(10, global_v.size());
	for(auto& ie : global_v)
	{
		cout<<ie<<", ";
	}
	cout<<endl;
}

TEST_F(VectorTest, test_vector_size_when_add_10_elem)
{
	VectorTest::PushElements(25, 10);
	EXPECT_EQ(20, global_v.size());
	
	global_v.clear();
	EXPECT_EQ(0, global_v.size());

	VectorTest::PushElements(30, 15);
	EXPECT_EQ(15, global_v.size());
}


}


int main(int argc, char* argv[])
{
	cout<<"Running main() from "<<__FILE__<<endl;
	testing::InitGoogleTest(&argc, argv);

	return RUN_ALL_TESTS();
}

代码编译结果:

[root@localhost first_unit]# bash build.sh
-- The C compiler identification is GNU 9.3.1
-- The CXX compiler identification is GNU 9.3.1
-- Check for working C compiler: /opt/rh/devtoolset-9/root/usr/bin/cc
-- Check for working C compiler: /opt/rh/devtoolset-9/root/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /opt/rh/devtoolset-9/root/usr/bin/c++
-- Check for working CXX compiler: /opt/rh/devtoolset-9/root/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/lfh/projects/gtest_pro/first_unit/build
Scanning dependencies of target sample1
[ 25%] Building CXX object sample1/CMakeFiles/sample1.dir/sample1.cpp.o
[ 50%] Linking CXX shared library libsample1.so
[ 50%] Built target sample1
Scanning dependencies of target gtest_app
[ 75%] Building CXX object CMakeFiles/gtest_app.dir/main.cpp.o
[100%] Linking CXX executable gtest_app
[100%] Built target gtest_app

运行结果:

图4 运行结果

运行结束,测试不是特别难,当然这只是简单应用,复杂应用估计比较难以及构造复杂场景就是要靠开发者继续努力了。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值