上次我介绍的一个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.