上次我介绍的一个google Test文件案例本质还是C语言,不是C++语言。这篇文章我们来介绍一下真正的C++语言如何用GTest来实现单元测试。
1, 建立头文件calculator.h
代码语言:javascript
复制
// 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
代码语言:javascript
复制
// 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
代码语言:javascript
复制
// 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
代码语言:javascript
复制
int main(int argc,char* argv[]) { testing::GTEST_FLAG(output) = "xml:"; //若要生成xml结果文件 testing::InitGoogleTest(&argc,argv); //初始化 return RUN_ALL_TESTS(); //跑单元测试 }
在GTestApp目录下新建lib目录,并复制libgtest.a到其中
代码语言:javascript
复制
mkdir lib cp /home/jerery/googletest-main/lib/*.a ./lib
编译
代码语言:javascript
复制
g++ -std=c++14 calculator.cpp calculatorTest.cpp calculator.h TestAll.cpp -lgtest -lgtest_main -pthread -o test
运行测试
代码语言:javascript
复制
./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.
代码语言:javascript
复制
<?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 :
代码语言:javascript
复制
// 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*); }
重新进行编译,运行过。
代码语言:javascript
复制
./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
代码语言:javascript
复制
// 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()); }
编译运行
代码语言:javascript
复制
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.