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

软件单元测试工程模版化

一、简介  

     在汽车领域混了这么多年也做了不少项目,发现很多公司对软件单元测试和代码覆盖率测试根本不重视,或者开发流程就没有单元测试这个流程。但是有的客户需要评审单元测试这个流程,需要有相关的单元测试报告和代码覆盖率统计的报告。如果客户有这个要求就必须把这个开发流程重视起来,但是找了市面上很多工具并没有很满足要求的,既能实现单元测试又能顺便将代码的覆盖率统计出来。之前我写过一篇文章:温故而知新:gtest单元测试工具和lcov覆盖率统计工具的结合使用_gtest 覆盖率-CSDN博客 ,这篇文章主要介绍了如何将这两个工具结合起来作为单元测试工具。但是单元测试的过程中有的分支是没办法跑到的,比如需要依赖外部硬件的条件的情况下执行某个分支。例如有如下代码:

void control_flow(void)
{int a = 10, b = 20;stGPIO_Attrs gpio_attrs;GPIO_Config(1, 0, gpio_attrs);GPIO_OutLevel(1, 0, 0);//gpio为高电平执行乘法运算否则执行加法运算if(GPIO_GetPinLevel(1, 0) != 0) {func_add(a, b);}else {func_muti(a, b);}
}

  以上代码通过获取一个PIN脚的电平是高电平还是低电平执行不同的逻辑。但是单元测试工具一般是运行在windows环境下,硬件相关的代码是需要删除的。因此GPIO_GetPinLevel函数只能返回高电平或者低电平。因此在执行单元测试的时候只能跑一个分支,另一个分支无法被跑到。那么有没有办法让两个分支都跑到呢?答案是肯定的,那么就是对GPIO_GetPinLevel函数进行打桩。

二、函数打桩

函数打桩简单理解就是在实际运行代码的过程中用另一个函数的实现来替换实际函数的实现。比如上述GPIO_GetPinLevel函数就可以用下面的打桩函数来替换:

uint8_t GPIO_GetPinLevel_Stub(uint8_t gpio_port, uint8_t gpio_pin)
{if(s_test_case == 0){return 0;}else if(s_test_case == 1) {return 1;}else {return 2;}
}

这样在程序运行的过程中就可以通过改变s_test_case变量的值来控制GPIO_GetPinLevel的返回值,从而获得高低电平。

三、该模版化工程的亮点

(1)基于gtest和lcov实现的既可以在实现单元测试的同时统计代码行覆盖率,并生成可视化报告。

(2)该工程提供了打桩功能可以方便用户在函数中制造各种异常case,人为制造在实际中跑不出来的情况。

(3)无论是单片机程序还是大型OS的程序都可以很简单的移植到该工程执行测试。

(4)生成的单元测试报告及覆盖率报告都是可视化的,该工程跑在ubuntu linux虚拟机上,环境搭建简单,移植方便,只需要将代码分别放在下图的Src和Inc目录下并编写测试用例即可运行。单元测试用例编写规则和gtest一致。

                ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​        图1    单元测试工程模版主目录
 

                                                        图2   单元测试用例目录

                                                       图3  单元测试运行界面

 

                                                        图4  代码接口和行覆盖率统计结果

                                                             图5  单元测试结果报告 

 

                                                    图6  单元测试用例编写用例 

                                                    图7  具体接口覆盖率情况

注:有单元测试需要该模版的私信了解下

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 英伟达最新论文解析:剪枝与知识蒸馏 —— 可穿戴AI时代即将到来
  • HarmonyOS ArkUI工程框架解析
  • PHP软件下载-安装-环境配置
  • Unet改进15:添加TripletAttention||减少冗余计算和同时存储访问
  • 如何安装Docker
  • 抽象代数精解【12】
  • C++预处理定义
  • C++中不定参数函数的实现方法
  • AI技术在巴黎奥运会中有哪些应用?
  • 汽车免拆诊断案例 | 2012 款大众速腾车发动机偶尔抖动
  • 【R语言速通】1.数据类型
  • 【Spring Boot 3】【Web】ProblemDetail
  • 前端开发学习Docker记录02容器操作
  • 不平衡分类的成本敏感学习
  • cuda,torch,paddle向下兼容
  • #Java异常处理
  • 【Linux系统编程】快速查找errno错误码信息
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Apache Pulsar 2.1 重磅发布
  • Asm.js的简单介绍
  • extjs4学习之配置
  • Gradle 5.0 正式版发布
  • gulp 教程
  • java2019面试题北京
  • Java基本数据类型之Number
  • js操作时间(持续更新)
  • laravel5.5 视图共享数据
  • mysql innodb 索引使用指南
  • ReactNativeweexDeviceOne对比
  • uni-app项目数字滚动
  • Vue2 SSR 的优化之旅
  • 第2章 网络文档
  • 电商搜索引擎的架构设计和性能优化
  • 后端_MYSQL
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 前言-如何学习区块链
  • 腾讯优测优分享 | Android碎片化问题小结——关于闪光灯的那些事儿
  • 微信支付JSAPI,实测!终极方案
  • 与 ConTeXt MkIV 官方文档的接驳
  • 你对linux中grep命令知道多少?
  • 【云吞铺子】性能抖动剖析(二)
  • 如何在招聘中考核.NET架构师
  • #if和#ifdef区别
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (void) (_x == _y)的作用
  • (ZT)出版业改革:该死的死,该生的生
  • (第61天)多租户架构(CDB/PDB)
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (力扣)循环队列的实现与详解(C语言)
  • (六)库存超卖案例实战——使用mysql分布式锁解决“超卖”问题
  • (数据大屏)(Hadoop)基于SSM框架的学院校友管理系统的设计与实现+文档
  • (四) 虚拟摄像头vivi体验
  • (四)进入MySQL 【事务】