C++|客户端单元测试实践—C++篇

【C++|客户端单元测试实践—C++篇】C++|客户端单元测试实践—C++篇

文章图片

C++|客户端单元测试实践—C++篇

文章图片

C++|客户端单元测试实践—C++篇

文章图片

C++|客户端单元测试实践—C++篇

文章图片



背景 我们团队在手淘中主要负责BehaviX模块 , 代码主要是一些逻辑功能 , 很少涉及到UI , 为了减少双端不一致问题、提高性能 , 我们采用了将核心代码C++化的策略 。
由于团队项目偏底层 , 测试同学难以完全覆盖 , 回归成本较高 , 部分功能依赖研发同学自测 , 为了提高系统的稳定性 , 我们在团队中实行了单元测试 , 同时由于集团客户端C++单元测试相关经验沉淀较少 , 所以在此分享下团队在做单元测试中遇到的问题与解决思路 , 希望能对大家所有帮助 。
为什么要使用单元测试
1、运行快
如果由测试同学手工测试 , 可能测试周期很长 , 对于功能比较复杂的功能 , 测试同学可能并不能完整覆盖所有预期链路 , 也可能由于某些操作而错过一些关键性步骤 。
2、减少回归成本
使用单元测试 , 可以在每次修改代码后重新运行整套测试 , 尽可能保证新代码不会破坏现有功能 。
3、优化代码结构
当代码耦合度非常大时 , 可能很难进行单元测试 。 为代码编写测试将自然地按照预期功能分离你的类 。
单测工程搭建历程 单测环境搭建
运行环境的选择
C++工程由于一些三方库的依赖(需要准备多个平台的链接库) , 同一份代码想要在不同操作系统上运行稍微有点困难 。
为了能够让单测工程快速运行起来 , 同时也方便开发同学调试 , 兼顾Android/iOS同学的开发习惯 , 在运行环境上支持单测支持在MacOS和Linux下运行 。
依赖剥除
由于单测环境是运行在电脑环境的 , 所以必须要把一些外部依赖去除 。
Java/OC的API依赖
涉及到跨语言通信时 , 通过NativeBridge封装 , 内部通过宏或cpp文件链接区分Android和iOS环境

外部库的依赖
一般采取源码依赖或打出多平台链接库(需要MacOS和Linux版本的依赖)的依赖方式解决 。
单测框架
目前业内C++主流单测框架为google的gtest + gmock 。
gtest提供了一些单元测试中的断言工具 , gmock提供了一些mock功能 , 但是功能比较弱 。
MOCK工具
gtest提供的gmock工具功能比较弱 , 只能通过继承的方式mock虚函数 , 对于C++来说是极其不方便的 。
在Java中 , 成员方法是默认可以被派生类重写的 , java主流mock工具mockito正是利用了这一特性来完成mock操作 。 在C++中 , 所有函数默认是不能被重写的 , 而且存在一些静态函数和工具函数 , 无法通过继承重写的方式完成mock 。
最终我们基于开源的hook工具 frida 进行封装 , 实现了自己的mock工具 。

部署到服务器运行
依赖安装
为了使单测工程和其他系统打通(如:钉钉群、Aone) , 单测工程同时也支持在Linux环境中运行 。
因为C++语言的特殊性 , 从本机环境(MacOS)迁移到Linux并不是一帆风顺的 。
集团的服务端机器使用的是CentOS , 而且只能下载内网环境中已有的软件 , 版本也比较老 , 而且集团机器对C++的环境支持稍弱 , 如:编译器不支持C++11语法 , CMake版本低 , 没有Clang编译器等 。