一个google Test文件C++语言案例

admin 2024年7月2日17:03:34评论4 views字数 7987阅读26分37秒阅读模式

上次我介绍的一个google Test文件案例本质还是C语言,不是C++语言。这篇文章我们来介绍一下真正的C++语言如何用GTest来实现单元测试。

1, 建立头文件calculator.h

// Calculator.h  #ifndef CALCULATOR_H  #define CALCULATOR_H  class Calculator {  public:      double result;    Calculator();    void add(double a);      void subtract(double a);      void multiply(double a);      void divide(double a);    double getresult();};  #endif

注意 class Calculator在头文件中定义

2 建立被测文件calculator.cpp

// Calculator.cpp  #include "calculator.h"  double result;Calculator::Calculator(){    Calculator::result = 0;}void Calculator::add(double a) {      Calculator::result = a + Calculator::result;  }  void Calculator::subtract(double a) {      Calculator::result = a - Calculator::result;;  }  void Calculator::multiply(double a) {      Calculator::result = a * Calculator::result;;  }  void Calculator::divide(double a) {      if (Calculator::result == 0) throw "Division by zero";      Calculator::result = a / Calculator::result;}        double Calculator::getresult() {      return Calculator::result;}

3 建立测试文件calculatorTest.cpp

// CalculatorTest.cpp  #include "calculator.h"  #include  TEST(CalculatorTest, AddTest) {      Calculator calc;    calc.add(1);     calc.add(1);      EXPECT_EQ(calc.getresult(), 2);    }    TEST(CalculatorTest, SubtractTest) {      Calculator calc;      calc.add(3);    calc.subtract(7);    EXPECT_EQ(calc.getresult(), 4);   }    TEST(CalculatorTest, MultiplyTest) {      Calculator calc;      calc.add(3);    calc.multiply(4);    EXPECT_EQ(calc.getresult(), 12);   }    TEST(CalculatorTest, DivideTest) {      Calculator calc;    calc.add(3);      calc.divide(9);    EXPECT_EQ(calc.getresult(), 3);}    TEST(CalculatorTest, DivideTestByZero) {    Calculator calc;    calc.add(0);      EXPECT_THROW({calc.divide(1);}, const char*);}

4 建立总测试文件TestAll.cpp

int main(int argc,char* argv[]){        testing::GTEST_FLAG(output) = "xml:"; //若要生成xml结果文件        testing::InitGoogleTest(&argc,argv); //初始化            return RUN_ALL_TESTS();              //跑单元测试}

在GTestApp目录下新建lib目录,并复制libgtest.a到其中

mkdir libcp /home/jerery/googletest-main/lib/*.a ./lib

g++ -std=c++14 calculator.cpp calculatorTest.cpp calculator.h TestAll.cpp -lgtest -lgtest_main -pthread -o test 

运行测试

./test --gtest_output=xml# ./test --gtest_output=xml[==========] Running 4 tests from 1 test suite.[----------] Global test environment set-up.[----------] 4 tests from CalculatorTest[ RUN      ] CalculatorTest.AddTest[       OK ] CalculatorTest.AddTest (0 ms)[ RUN      ] CalculatorTest.SubtractTest[       OK ] CalculatorTest.SubtractTest (0 ms)[ RUN      ] CalculatorTest.MultiplyTest[       OK ] CalculatorTest.MultiplyTest (0 ms)[ RUN      ] CalculatorTest.DivideTest[       OK ] CalculatorTest.DivideTest (0 ms)[----------] 4 tests from CalculatorTest (0 ms total)[----------] Global test environment tear-down[==========] 4 tests from 1 test suite ran. (0 ms total)[  PASSED  ] 4 tests.
<?xml version="1.0" encoding="UTF-8"?><testsuites tests="5" failures="0" disabled="0" errors="0" time="0." timestamp="2024-07-01T17:04:42.890" name="AllTests">  <testsuite name="CalculatorTest" tests="5" failures="0" disabled="0" skipped="0" errors="0" time="0." timestamp="2024-07-01T17:04:42.890">    <testcase name="AddTest" file="calculatorTest.cpp" line="5" status="run" result="completed" time="0." timestamp="2024-07-01T17:04:42.890" classname="CalculatorTest" />    <testcase name="SubtractTest" file="calculatorTest.cpp" line="12" status="run" result="completed" time="0." timestamp="2024-07-01T17:04:42.890" classname="CalculatorTest" />    <testcase name="MultiplyTest" file="calculatorTest.cpp" line="19" status="run" result="completed" time="0." timestamp="2024-07-01T17:04:42.890" classname="CalculatorTest" />    <testcase name="DivideTest" file="calculatorTest.cpp" line="26" status="run" result="completed" time="0." timestamp="2024-07-01T17:04:42.890" classname="CalculatorTest" />    <testcase name="DivideTestByZero" file="calculatorTest.cpp" line="33" status="run" result="completed" time="0." timestamp="2024-07-01T17:04:42.890" classname="CalculatorTest" />  </testsuite></testsuites>

TEST 运行是普通的运行宏,当多个测试用例使用一组测试数据,可以使用TEST_F,修改测试代码calculatorTest.cpp :

// CalculatorTest.cpp  #include "calculator.h"  #include <gtest/gtest.h> double a_;double b_;class CalculatorTestWithFixture : public ::testing::Test {protected:  void SetUp() override {    a_= 3;    b_= 9;  }};TEST_F(CalculatorTestWithFixture, AddTest) {      Calculator calc;    calc.add(a_);     calc.add(b_);      EXPECT_EQ(calc.getresult(), 12);    }  TEST_F(CalculatorTestWithFixture, SubtractTest) {      Calculator calc;      calc.add(a_);    calc.subtract(b_);    EXPECT_EQ(calc.getresult(), 6);   }  TEST_F(CalculatorTestWithFixture, MultiplyTest) {      Calculator calc;      calc.add(a_);    calc.multiply(b_);    EXPECT_EQ(calc.getresult(), 27);   }  TEST_F(CalculatorTestWithFixture, DivideTest) {      Calculator calc;    calc.add(a_);      calc.divide(b_);    EXPECT_EQ(calc.getresult(), 3); }TEST_F(CalculatorTestWithFixture, DivideTestByZero) {     Calculator calc;    calc.add(0);      EXPECT_THROW({calc.divide(1);}, const char*);}

重新进行编译,运行过。

./test[==========] Running 5 tests from 1 test suite.[----------] Global test environment set-up.[----------] 5 tests from CalculatorTestWithFixture[ RUN      ] CalculatorTestWithFixture.AddTest[       OK ] CalculatorTestWithFixture.AddTest (0 ms)[ RUN      ] CalculatorTestWithFixture.SubtractTest[       OK ] CalculatorTestWithFixture.SubtractTest (0 ms)[ RUN      ] CalculatorTestWithFixture.MultiplyTest[       OK ] CalculatorTestWithFixture.MultiplyTest (0 ms)[ RUN      ] CalculatorTestWithFixture.DivideTest[       OK ] CalculatorTestWithFixture.DivideTest (0 ms)[ RUN      ] CalculatorTestWithFixture.DivideTestByZero[       OK ] CalculatorTestWithFixture.DivideTestByZero (0 ms)[----------] 5 tests from CalculatorTestWithFixture (0 ms total)[----------] Global test environment tear-down[==========] 5 tests from 1 test suite ran. (0 ms total)[  PASSED  ] 5 tests.

接下来,看一下TEST_P如何使用,修改代码calculatorTest.cpp

// CalculatorTest.cpp  #include "calculator.h"  #include <gtest/gtest.h> //Step1:申明一个呼叫参数类,该类主要用于TEST_P宏中实现的测试逻辑使用class CallArgs{public:  CallArgs(double hasprama,double haspramb, double hasresult):    _hasPrama(hasprama),_hasPramb(haspramb),_hasResult(hasresult){}  double prama(){ return _hasPrama;} //_hasprama是减数  double pramb()return _hasPramb;} //_haspramb是被减数,实现pramb - pram  double result(){return _hasResult;} //_hasresult是期待结果private:  double _hasPrama;  double _hasPramb;  double _hasResult;};//Step2:申明一个呼叫类,该类同时也是TEST_P宏的第一个参数test_case_name//该类继承了TestWithParam<CallArgs>模版类,从而使得CallArgs类与Call类进行了关联。class CalculatorTestWithTestP:public ::testing::TestWithParam<CallArgs>{};//Step3: 使用INSTANTIATE_TEST_CASE_P宏,对Call类进行类相关多个的参数设置//这里使用参数生成器::testing::Values,GTest定义了了很多参数生成器。//可以添加多大50个参数。INSTANTIATE_TEST_CASE_P(VOIP, CalculatorTestWithTestP, ::testing::Values(    CallArgs{7,5,2},     CallArgs{5,7,-2},    CallArgs{5,5,0}));//Step4: 编写了使用TEST_P宏实现的测试用例//使用了TestWithParam<CallArgs>类的GetParam()接口获取参数CallArgs//实际上这是三个测试用例,即该代码段会执行两个,参数分别为 :CallArgs{7,5,2}, CallArgs{5,7,-2},CallArgs{5,5,0}TEST_P(CalculatorTestWithTestP,BasicTest){   CallArgs args = GetParam();   Calculator calc;   calc.add(args.pramb());    calc.subtract(args.prama());     EXPECT_EQ(calc.getresult(), args.result());}  

编译运行

root@jerery-virtual-machine:/home/jerery/googletest-main/googletest/myworkspace/calculator_TEST_P# ./test[==========] Running 3 tests from 1 test suite.[----------] Global test environment set-up.[----------] 3 tests from VOIP/CalculatorTestWithTestP[ RUN      ] VOIP/CalculatorTestWithTestP.BasicTest/0[       OK ] VOIP/CalculatorTestWithTestP.BasicTest/0 (0 ms)[ RUN      ] VOIP/CalculatorTestWithTestP.BasicTest/1[       OK ] VOIP/CalculatorTestWithTestP.BasicTest/1 (0 ms)[ RUN      ] VOIP/CalculatorTestWithTestP.BasicTest/2[       OK ] VOIP/CalculatorTestWithTestP.BasicTest/2 (0 ms)[----------] 3 tests from VOIP/CalculatorTestWithTestP (0 ms total)[----------] Global test environment tear-down[==========] 3 tests from 1 test suite ran. (0 ms total)[  PASSED  ] 3 tests.

一个google Test文件C++语言案例

本书第1章与第2章介绍软件单元测试的概念和基础知识。

  • 第1章简单介绍软件单元测试所包含的概念,包括桩对象和测试驱动函数、测试驱动开发、软件测试贯彻始终、软件测试金字塔、单元测试在传统/敏捷开发模式中的地位、精准测试、单元测试和白盒测试,以及单元测试的FIRST原则和AIR原则。

  • 第2章介绍软件单元测试基础知识,包括动态自动化/手工单元测试、静态自动化/手工单元测试。在动态自动化单元测试中介绍了语句覆盖、分支覆盖、条件覆盖、条件/分支覆盖、MC/DC、路径覆盖和控制流覆盖。

第3章到第5章介绍C语言、Java语言和Python语言的单元测试框架。

  • 第3章介绍C语言动态自动化单元测试框架,包括在Windows下安装C语言运行环境、在Windows和Linux下安装编译CUnit、查看测试报告、CUnit介绍和案例。

  • 第4章介绍Java语言动态自动化单元测试框架,包括在Eclipse中创建Maven项目和配置JUnit与TestNG运行环境、JUnit 4测试框架、JUnit 5测试框架、TestNG测试框架、测试替身、变异测试、利用EvoSuite自动生成测试用例,以及在Jenkins中配置JUnit 4、JUnit 5、TestNG和Allure。

  • 第5章介绍Python语言动态自动化单元测试框架,包括unittest、Pytest及Python的模拟对象和变异测试工具mutpy。

第6章与第7章介绍代码覆盖率工具和代码语法规范检查工具。

  • 第6章介绍代码覆盖率工具,包括C语言覆盖率工具gcov和lcov、Java语言覆盖率工具JaCoCo,以及Python语言覆盖率工具Coverage和pytest-cov。

  • 第7章介绍代码语法规范检查工具,包括Java语言静态分析工具PMD、Python语言静态分析工具flake8和pylint,以及多代码语法规范检查平台SonarQube。

  • 第8章通过两个案例详细介绍TDD。

    读者可以根据自己的需求对以上内容进行选择性阅读或者全部阅读。另外,为了巩固大家的学习效果,每一章结尾都有相应的习题。

顾翔凡言:整个IT都在放缓,近十年来主旋律就一个——人工智能。一个google Test文件C++语言案例

原文始发于微信公众号(啄木鸟软件测试):一个google Test文件C++语言案例

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月2日17:03:34
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   一个google Test文件C++语言案例https://cn-sec.com/archives/2910311.html

发表评论

匿名网友 填写信息