当前位置: 首页 > news >正文

软件测试:C++ Google Test单元测试框架GTest

目录

        • 编译和安装
        • 框架使用
          • Assertions
          • Google Testing
          • Google Mocking
          • Matchers
          • Actions
        • 运行结果

最近在写项目的时候,学到了许多关于软件测试的知识,也不断的使用新的测试框架和测试工具,每次总是机械式的拼接其他人的代码,代码发生错误也不知道怎么解决,因此我打算直接将其学一遍,以便为了更灵活的写测试代码

编译和安装

下载地址:Google Test Github网站

然后直接在CMakeLists.txt引入就好了

include_directories(include) # 设置include路径set(CXXFLAGS -std=c++11 -lgtest -lpthread)
add_compile_options(${CXXFLAGS})target_link_libraries(test gtest pthread) # 链接gtest静态库
框架使用

框架的使用主要分为几个模块:AssertionsGoogle TestingGoogle MockingMatchersActions

Assertions

这一部分主要是一些断言和比较宏定义,内容较多,以下是一部分,想看全部的可以去看源码

这一部分理解比较简单,不做概述

#define EXPECT_THROW(statement, expected_exception) \GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
#define EXPECT_NO_THROW(statement) \GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
#define EXPECT_ANY_THROW(statement) \GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_)
#define ASSERT_THROW(statement, expected_exception) \GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
#define ASSERT_NO_THROW(statement) \GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
#define ASSERT_ANY_THROW(statement) \GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_)
Google Testing

这部分是框架的主要部分,也是开发人员接触最多的地方

首先来介绍三个常用的宏:TESTTEST_FTEST_P

TEST:一般测试,在其内部设置断言

TestSuiteName定义了测试套件名称,TestName定义了自定义测试名

  • 注意这两个的命名不要包括下划线_
TEST(TestSuiteName, TestName) 
{// statements
}

TEST_F:多样测试,就是多种不同情况的测试中都会使用相同一份的测试数据的情况

TEST_P(TestFixtureName, TestName) 
{// statements
}

TEST_P:值参数化测试,自动化产生输入参数进行测试

TEST_P(TestFixtureName, TestName) 
{// statements
}

TEST_P为例写一个小demo

首先定义一个测试套件类,在其中定义要产生测试输入参数的类型

// 其中TestWithParam从Test类和WithParamInterface类派生来的,这两个类是必要的
class FooTest : public ::testing::TestWithParam<int> {};

产生自动化输入参数结构

INSTANTIATE_TEST_CASE_P(InstantiationName, // 此处自定义名称FooTest, // 测试套件类::testing::Values(1, 2, 3));

第三个参数是可更改的,比如RangeBoolValuesInValues

INSTANTIATE_TEST_SUITE_P(MyInstantiation, MyTestSuite,testing::Values(...),[](const testing::TestParamInfo<MyTestSuite::ParamType>& info) {// Can use info.param here to generate the test suffixstd::string name = ...return name;});

要注意的是Combine,它会把其中的变量组成一个联合排列输入参数(确保支持tr/tuple<T>特性)


class Bis {bool Even(int dd) {}bool Suc(bool dc) {}
};class CombineTest : public ::testing::TestWithParam< ::testing::tuple<bool, int> > {
protected:bool CheckData() {bool dc = ::testing::get<0>(GetParam());int dd = ::testing::get<1>(GetParam());return bis.Suc(dc) && bis.Even(dd);}
private:Bis bis;
}TEST_P(MyCombineTest, CombineTestUnit)
{EXPECT_TRUE(CheckData());
}INSTANTIATE_TEST_CASE_P(TestBisValuesCombine, CombineTest, ::testing::Combine(::testing::Bool(), ::testing::Values(3, 4)));

最后在TEST_P中写测试代码

bool IsPrime(int n)
{return n > 0;
}TEST_P(FooTest, DoesBlah) 
{// Inside a test, access the test parameter with the GetParam() method// of the TestWithParam<T> class://在测试中,使用TestWithParam <T>类的GetParam()方法访问测试参数:int n =  GetParam();EXPECT_TRUE(IsPrime(n));// ...
}

其他部分API用的时候直接看官网就好了,主体是这三个API,其他基本上都是辅助宏

Google Mocking

有点类似于伪装接口,一般情况下用不着,不做概述

Matchers

有点类似于前面的断言,直接看部分源码(在gmok-matchers.h文件中)

inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrEq(const std::wstring& str) {return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::wstring>(str, true, true));
}// Matches a string not equal to str.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrNe(const std::wstring& str) {return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::wstring>(str, false, true));
}// Matches a string equal to str, ignoring case.
inline PolymorphicMatcher<internal::StrEqualityMatcher<std::wstring>> StrCaseEq(const std::wstring& str) {return MakePolymorphicMatcher(internal::StrEqualityMatcher<std::wstring>(str, true, false));
}
Actions

这玩意也是一个和断言差不多的东西,看部分源码

template <size_t k, typename Ptr>
struct SaveArgAction {Ptr pointer;template <typename... Args>void operator()(const Args&... args) const {*pointer = std::get<k>(std::tie(args...));}
};template <size_t k, typename Ptr>
struct SaveArgPointeeAction {Ptr pointer;template <typename... Args>void operator()(const Args&... args) const {*pointer = *std::get<k>(std::tie(args...));}
};
运行结果

下面来看看一个普通测试套件的运行结果

#include <gtest/gtest.h>
#include <stdint.h>
#include <stdio.h>int Add(uint32_t a, uint32_t b)
{return a + b;
}TEST(LLT, MAIN)
{EXPECT_EQ(Add(1U, 1U), 1U);
}int main(int argc, char **argv)
{testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();
}
ubuntu@VM-8-16-ubuntu:~/finale/llt/build$ ./test 
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from LLT
[ RUN      ] LLT.MAIN
/home/ubuntu/finale/llt/src/test_main.cc:17: Failure
Expected equality of these values:add(1U, 1U)Which is: 21UWhich is: 1
[  FAILED  ] LLT.MAIN (0 ms)
[----------] 1 test from LLT (0 ms total)[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] LLT.MAIN1 FAILED TEST

这个框架自定义的界面还是很好看的!

http://www.lryc.cn/news/321420.html

相关文章:

  • 大数据面试题 —— HBase
  • SCI一区 | Matlab实现GWO-TCN-BiGRU-Attention灰狼算法优化时间卷积双向门控循环单元融合注意力机制多变量时间序列预测
  • SpringMVC的执行原理
  • Qt + HTTP 线程交互类封装
  • GitHub Copilot+ESP开发实战-串口
  • C# 使用ffmpeg将图片保存为mp4视频
  • Java安全技术及代码审计技巧
  • C# 使用OpenCvSharp4将Bitmap合成为MP4视频的环境
  • [游戏开发][Unity] 导出Xcode工程,完成调试与发布
  • JSONP 实现跨域请求案例
  • 2024年智慧城市、人文发展与区域经济国际会议(ICSCCDRE 2024)
  • 目标检测——PP-YOLO算法解读
  • 多特征变量序列预测(11) 基于Pytorch的TCN-GRU预测模型
  • Lvs+keepalived+nginx搭建高可用负载均衡集群
  • WPF —— 控件模版和数据模版
  • 如何动态修改spring中定时任务的调度策略(1)
  • idea import的maven类报红
  • React——class组件中setState修改state
  • 搭建基于 Snowflake 的 CI/CD 最佳实践!
  • 数据结构(五)——树的基本概念
  • 2.28CACHE,虚拟存储器
  • 深入理解栈和队列(一):栈
  • electron-builder 打包问题,下载慢解决方案
  • (简单成功)Mac:命令设置别名
  • Grok-1:参数量最大的开源大语言模型
  • Python 自然语言处理库之stanza使用详解
  • 计算机网络:数据交换方式
  • 万用表革新升级,WT588F02BP-14S语音芯片助力智能测量新体验v
  • Day61:WEB攻防-PHP反序列化原生类TIPSCVE绕过漏洞属性类型特征
  • 【开源】SpringBoot框架开发不良邮件过滤系统