相关文章推荐
欢乐的黄豆  ·  android - Flutter ...·  1 年前    · 

单元测试在函数在整个工程运行起来之前,对该函数进行测试,来判断当前函数能否达到预期的效果。

使用GoogleTest:

1.将GoogleTest编译为库;
2.在代码中链接这个库。

二、GTest编译安装

1.源代码编译:
#下载gtest,release-1.8.0
git clone https://github.com/google/googletest
# gtest编译
cd googletest
#生成Makefile文件(先安装cmake,brew install cmake),继续输入命令编译:
cmake CMakeLists.txt
#执行make,生成两个静态库:libgtest.a libgtest_main.a
#拷贝到系统目录,注意,如果下诉目录位置在不同版本位置有变动,用find . -name "libgtest*.a" 找到位置
sudo cp libgtest*.a  /usr/lib
sudo cp –a include/gtest/ /usr/include
2.检查是否安装成功

可以写一个简单的测试代码gtest.cpp,如下:

#include<gtest/gtest.h>
int add(int a,int b){
    return a+b;
TEST(testCase,test0){
    EXPECT_EQ(add(2,3),5);
int main(int argc,char **argv){
  testing::InitGoogleTest(&argc,argv);
  return RUN_ALL_TESTS();

在终端中编译该文件,并运行:

g++ -std=c++11 gtest.cpp -lgtest -lpthread -o gtest.out
./gtest.out

三、GTest使用

单元测试(Unit Test)是对软件基本组成单元(如函数或是一个类的方法)进行的测试,是开发者编写的一小段代码,用于检验被测试代码一个很小的、很明确的功能是否正确。
在gtest中,一个测试用例(test case)可以包含一个或多个测试。一个测试程序可以包含多个测试用例。

可以通过操作符”<<”将一些自定义的信息输出,如:

ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
for (int i = 0; i < x.size(); ++i) {
  EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;

1.定义测试函数

应用 googletest 编写单元测试时,使用 TEST() 宏来声明测试函数:

TEST(GlobalConfigurationTest, configurationDataTest) 

2.断言/宏测试

gtest中,断言是用以检查条件是否为真。

ASSERT_* 版本的断言失败时会产生致命失败,并结束当前函数;
EXPECT_* 版本的断言失败时产生非致命失败,但不会中止当前函数。

3.事件机制

要实现全局事件,必须写一个类,继承testing::Environment类,实现里面的SetUp和TearDown方法。

  1. SetUp()方法在所有案例执行前执行

  2. TearDown()方法在所有案例执行后执行

还需要告诉gtest添加这个全局事件,我们需要在main函数中通过testing::AddGlobalTestEnvironment方法将事件挂进来,也就是说,我们可以写很多个这样的类,然后将他们的事件都挂上去。

TestSuite事件

我们需要写一个类,继承testing::Test,然后实现两个静态方法

  1. SetUpTestCase() 方法在第一个TestCase之前执行

  2. TearDownTestCase() 方法在最后一个TestCase之后执行

在编写测试案例时,我们需要使用TEST_F这个宏,第一个参数必须是我们上面类的名字,代表一个TestSuite。

TestCase事件

TestCase事件是挂在每个案例执行前后的,实现方式和上面的几乎一样,不过需要实现的是SetUp方法和TearDown方法:

  1. SetUp()方法在每个TestCase之前执行

  2. TearDown()方法在每个TestCase之后执行

1.一个超简单的 googletest 单元测试实例
#include<gtest/gtest.h>
int add(int a,int b){
    return a+b;
TEST(testCase,test0){
    EXPECT_EQ(add(2,3),5);
int main(int argc,char **argv){
    testing::InitGoogleTest(&argc,argv);
    return RUN_ALL_TESTS();
2.一个较完整的 googletest 单元测试实例
// Configure.h 
 #pragma once 
 #include <string> 
 #include <vector> 
 class Configure 
 private: 
    std::vector<std::string> vItems; 
 public: 
    int addItem(std::string str); 
    std::string getItem(int index); 
    int getSize(); 
 // Configure.cpp 
 #include "Configure.h" 
 #include <algorithm> 
 * @brief Add an item to configuration store. Duplicate item will be ignored 
 * @param str item to be stored 
 * @return the index of added configuration item 
 int Configure::addItem(std::string str) 
std::vector<std::string>::const_iterator vi=std::find(vItems.begin(), vItems.end(), str); 
    if (vi != vItems.end()) 
        return vi - vItems.begin(); 
    vItems.push_back(str); 
    return vItems.size() - 1; 
 * @brief Return the configure item at specified index. 
 * If the index is out of range, "" will be returned 
 * @param index the index of item 
 * @return the item at specified index 
 std::string Configure::getItem(int index) 
    if (index >= vItems.size()) 
        return ""; 
        return vItems.at(index); 
 /// Retrieve the information about how many configuration items we have had 
 int Configure::getSize() 
    return vItems.size(); 
 // ConfigureTest.cpp 
 #include <gtest/gtest.h> 
 #include "Configure.h" 
 TEST(ConfigureTest, addItem) 
    // do some initialization 
    Configure* pc = new Configure(); 
    // validate the pointer is not null 
    ASSERT_TRUE(pc != NULL); 
    // call the method we want to test 
    pc->addItem("A"); 
    pc->addItem("B"); 
    pc->addItem("A"); 
    // validate the result after operation 
    EXPECT_EQ(pc->getSize(), 2); 
    EXPECT_STREQ(pc->getItem(0).c_str(), "A"); 
    EXPECT_STREQ(pc->getItem(1).c_str(), "B"); 
    EXPECT_STREQ(pc->getItem(10).c_str(), ""); 
    delete pc; 

main()函数:

#include <gtest/gtest.h> 
 int main(int argc, char** argv) { 
    testing::InitGoogleTest(&argc, argv); 
    // Runs all tests using Google Test. 
    return RUN_ALL_TESTS(); 

最后,将所有测试代码及main.cpp编译并链接到目标程序中。

此外,在运行可执行目标程序时,可以使用 --gtest_filter 来指定要执行的测试用例,如:

./foo_test 没有指定filter,运行所有测试;
./foo_test --gtest_filter=* 指定filter为*,运行所有测试;
./foo_test --gtest_filter=FooTest.* 运行测试用例FooTest的所有测试;
./foo_test --gtest_filter=*Null*:*Constructor* 运行所有全名(即测试用例名 + “ . ” + 测试名,如 GlobalConfigurationTest.noConfigureFileTest)含有"Null""Constructor"的测试;
./foo_test --gtest_filter=FooTest.*-FooTest.Bar 运行测试用例FooTest的所有测试,但不包括FooTest.Bar。

五、我自己学习 googletest 单元测试时写的例程:

// Created by toson on 19-3-8. #include <gtest/gtest.h> #include "shtf_sdk_interface.h" //第一个参数是测试用例名,第二个参数是测试名:随后的测试结果将以"测试用例名.测试名"的形式给出 TEST(FaceImageInit_testCase, FaceImageInit_test){ //test data FaceImage* image = new FaceImage; char errorinfo[256]; //生成随机数用于测试 srand((unsigned)time(NULL)); //测试正数 image->width = rand(); image->height = rand(); image->size = rand(); image->bgr = (unsigned char*)rand(); cout << "image->width :" << image->width << endl; cout << "image->height:" << image->height << endl; cout << "image->size :" << image->size << endl; FaceImageInit(image,errorinfo); //断言是否完成程序该完成的功能 EXPECT_EQ(image->width, 0); EXPECT_EQ(image->height, 0); EXPECT_EQ(image->size, 0); EXPECT_EQ(image->bgr, nullptr); //测试负数 image->width = -rand(); image->height = -rand(); image->size = -rand(); image->bgr = (unsigned char*)-rand(); cout << "image->width :" << image->width << endl; cout << "image->height:" << image->height << endl; cout << "image->size :" << image->size << endl; FaceImageInit(image,errorinfo); EXPECT_EQ(image->width, 0); EXPECT_EQ(image->height, 0); EXPECT_EQ(image->size, 0); EXPECT_EQ(image->bgr, nullptr); delete image; int main(int argc,char **argv){ testing::InitGoogleTest(&argc,argv); //用来处理Test相关的命令行开关,如果不关注也可不加 return RUN_ALL_TESTS(); /*----------------------------------------------------------*/ 在测试执行之前,系统会先执行TestEnvironment的SetUp()方法; 在所有测试用例执行完之后,系统会执行TestEnvironment的TearDown()方法。 另外,我们可以定义任意多个继承自testing::Environment的子类,以实现不同的全局事件。 所有的子类的SetUp()按照我们调用testing::AddGlobalTestEnvironment添加它们的先后顺序执行,而TearDown()的执行顺序则与添加顺序相反。 //class ShtfSdkTnterfaceTestEnvironment : public testing::Environment{ //我的全局环境设置 //public: // virtual void SetUp() //在所有测试启动之前需要做的操作 // { // ;//std::cout << "Foo FooEnvironment SetUP" << std::endl; // } // virtual void TearDown() //在所有测试运行结束后需要做的操作 // { // ;//std::cout << "Foo FooEnvironment TearDown" << std::endl; // } TestEnvironment(){ //在SetUp()之前 cout<<"TestEnvironment()"<<endl; ~TestEnvironment(){ //在TearDown()之后 cout<<"~TestEnvironment()"<<endl; 在测试套件的第一个测试用例开始前,SetUpTestCase()函数会被调用, 而在测试套件中的最后一个测试用例运行结束后,TearDownTestCase()函数会被调用。 //class TestMap:public testing::Test //套装例子 //public: // static void SetUpTestCase() //测试套件的第一个测试用例开始前,SetUpTestCase()函数会被调用 // { // ;//cout<<"SetUpTestCase()"<<endl; // s=new Student(23); // } // static void TearDownTestCase() //在测试套件中的最后一个测试用例运行结束后,TearDownTestCase()函数会被调用 // { // delete s; // ;//cout<<"TearDownTestCase()"<<endl; // } // void SetUp() //测试套件的每次测试用例开始前,SetUp()函数会被调用 // { // ;//cout<<"SetUp(), running"<<endl; // } // void TearDown() //测试套件的每次测试用例运行结束后,TearDown()函数会被调用 // { // ;//cout<<"TearDown(), stopping"<<endl; // } TestMap(){ //在SetUpTestCase()之后,在SetUp()之前 cout<<"TestMap()"<<endl; ~TestMap(){ //在TearDown()之后,在SetUpTestCase()之前 cout<<"~TestMap()"<<endl; 第一个参数是测试用例名,第二个参数是测试名:随后的测试结果将以"测试用例名.测试名"的形式给出 //TEST_F(TestMap, Test1) //对TestMap进行测试,test1 // s->print(); // Student s1(18); // s1.print(); ASSERT_EQ(s1, (Student *)NULL); ASSERT_NE(s1, (Student )NULL); //TEST_F(TestMap, Test2) //对TestMap进行测试,test2 Student *s1; // s->print(); ASSERT_NE(Student(23), NULL); ASSERT_NE(s1, (Student *)NULL); // ASSERT_EQ(0, 0); //int main(int argc, char** argv) // //在RUN_ALL_TESTS()之前,我们调用如下语句: // // testing::AddGlobalTestEnvironment(new GlobalEnvent); // // 将这个测试层面的的事件添加到事件列表即可。 // testing::AddGlobalTestEnvironment(new ShtfSdkTnterfaceTestEnvironment); // testing::InitGoogleTest(&argc, argv); //用来处理Test相关的命令行开关,如果不关注也可不加 // return RUN_ALL_TESTS(); 一、定义单元测试应用 googletest 编写单元测试时,使用 TEST() 宏来声明测试函数:TEST(GlobalConfigurationTest, configurationDataTest) 二、实现单元测试ASSERT_* 版本的断言失败时会产生致命失败,并结束当前函数;EXPECT_* 版本的断言失败时产生非致命失败,但不会中止当前函数。三、一个较完整的 goog...
本文来自博客园,本文主要简单介绍了Google测试基础知识以及编写和运行Google Test测试,希望对您的学习有所帮助。 在用googletest测试项目之前,需要先编译gtest到library库并将测试与其链接。我们为一些流行的构建系统提供了构建文件: msvc/forVisualStudio,xcode/forMacXcode,make/
项目管理和技术管理中做单元测试,衡量一个软件是否正常的标准,良好的单元测试以及足够多的覆盖率,至少保证关键功能,关键业务的覆盖率接近100%。 gtest是谷歌公司发布的一个跨平台(Linux、Mac OS、Windows等)的C++单元测试框架,它提供了丰富的断言、致命和非致命判断、参数化、死亡测试等等。 两种断言: ASSERT_*:当断言失败时,产生致命错误、并终止当前函数。 EXPECT_*:当断言失败时,产生非致命错误,并且不会终止当前函数。 通常都会用EXPECT_*,因为能在一
安装首先依然是官方地址https://github.com/google/googletest 本文采用的版本https://github.com/google/googletest/archive/release-1.8.0.zip 本文采用的是Visual Studio Community 2017(微软官方可以免费下载,无需CDKEY,也没有任何功能限制) googletest已经弄好了
Googletest 初级教程 本文翻译自官方文档,官方原文请见Googletest Primer 为了保证阅读的质量,本文部分内容并非直译,而是加入的译者的理解的意译。若有不足之处,还请斧正。 以下为翻译正文… … 简介:为什么选择googletestgoogletest可以帮助你更好地编写C++的测试用例。 googletest是由谷歌的测试技术团队根据Google的特定要求和约束开发的测试框架。无论你是在Linux操作系统、Windows操作系统或者Mac操作系统上工作,如果你在编写C++的代码
前段时间学习和了解了下Google的开源C++单元测试框架Google Test,简称gtest,非常的不错。 我们原来使用的是自己实现的一套单元测试框架,在使用过程中,发现越来越多使用不便之处,而这样不便之处,gtest恰恰很好的解决了。 其实gtest本身的实现并不复杂,我们完全可以模仿gtest,不断的完善我们的测试框架, 但最后我们还是决定使用gtest取代掉原来的自己的测试框架,原因是: 1.不断完善我们的测试框架之后就会发觉相当于把gtest重新做了一遍,虽然轮子造的很爽,但是不是必要的。 2.使用gtest可以免去维护测试框架的麻烦,让我们有更多精力投入到案例设计上。 3.gtest提高了非常完善的功能,并且简单易用,极大的提高了编写测试案例的效率。
角度单元测试研讨会 研讨会材料: : 您的任务是提供一个经过测试的高质量,高质量的仪表板,以跟踪Grid的最杰出黑客! 我们将学习有关Angular应用程序单元测试的所有信息。 细节该项目是使用版本10.0.7生成的。 节点(12.x) npm(6.x) Angular CLI: npm install -g @angular/cli 最新的Google Chrome浏览器 GitHub帐户 强烈建议下载Visual Studio代码: : *安装以下扩展:* * * * 您将需要执行以下操作: 将此仓库分叉到您的GitHub帐户 在本地克隆你的叉子 全局安装Angular CLI: npm install -g @angular/cli 在angular-testing-workshop ,安装依赖项: npm install 以下命令应该起作用: npm start :应打开浏览器并显示我们将使用的应用程序: npm test :应该产生与此类似的输出(无错误): git checkout -b sol
该资源包含catch框架和博主自写的一个自动生成简单测试用例的工具,用起来简单,大家可以下载来学习使用,自写自动生成简单测试用例的工具包含有源码,可以根据此源码在添加自己的需求。 catch框架简介: 在catch的文档指出,对于C++单元测试框架,目前已经有 Google Test, Boost.Test, CppUnit, Cute, 以及其它的一些,那么catch有什么优势呢,文档主要列举了以下这些优势: ①简单易用:只需要下载catch.hpp,包含到你的工程就可以了; ②不依赖外部库:只要你可以编译C++11,有C++的标准库就可以了; ③测试case可以分割为sections: 每个setcion都是独立的运行单元; ③提供了BDD式的测试模式:可以使用Given-When-Then section来做BDD测试; ④只用一个核心的assertion宏来做比较。用标准的C++运算符来做比较,但是可以分解表达式,记录表达式等号左侧和右侧的值; ⑤可以用任何形式的字符串给测试命名,不用担心名字是否合法。
googletest一个用来写C++单元测试的框架,它是跨平台的,可应用在windows、linux、Mac等OS平台上。下面,我来说明如何使用最新的1.6版本gtest写自己的单元测试。 本文包括以下几部分:1、获取并编译googletest(以下简称为gtest);2、如何编写单元测试用例;3、如何执行单元测试。4、google test内部是如何执行我们的单元测试用例的。 1. 获...
1、测试概述 测试并不只是测试工程师的责任,对于开发工程师,为了保证发布给测试环节的代码具有足够好的质量( Quality ),为所编写的功能代码编写适量的单元测试是十分必要的。 2、测试之间的关系 白盒测试:全面了解程序内部逻辑结构,对所有逻辑路径进行测试单元测试:对软件基本组成单元进行的测试,这里的单元是软件设计的最小单位,单元测试属于白盒测试范畴。 打桩:在做单元测试或者集成测试时,如果某个程序单元的某条语句需要调用的一个外部函数还没有完成的话,可以简单让它返回几个支持测...