0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式需要单元测试吗?

工程师 来源:嵌入式大杂烩 作者:嵌入式大杂烩 2020-10-23 16:08 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前言

嵌入式行业摸爬滚打这几年,遇见有规范单元测试的项目寥寥无几。归根到底,无非是公司希望快速迭代出产品,有问题等客户反馈再说。当然,也有人认为是嵌入式行业都是小而美的产品居多,没有到一定量级之前,玩不起单元测试这种配置。正如做个蛋炒饭,并不需要安排主厨、二厨一般。

不过出于对代码稳定性的追求,我认为还是应该着手了解一下单元测试的。毕竟,这是有效提高代码说服力的方式之一。

相信没有真正体验过单元测试好处的读者一看到“单元测试”这几个字,可能会出现以下两种反应之一:

由于没有单元测试的经验,因此对采用这一方法去保证软件质量很好奇,也迫切地想要了解这一方法在项目中的实施

曾经使用单元测试但效果不好,因为在嵌入式行业,时常要跟硬件打交道,单元测试很难检测硬件问题,所以往往一看到“单元测试”这几个字的反应就是“没用”

如果读者是第一种反应那很好,本文就是科普单元测试的基本要点。如果读者是第二种反应,那可能是对单元测试存在偏见,本系列文章也会介绍mock测试、错误注入等方式,使单元测试也能合理使用于嵌入式行业。

01

单元测试真的“无用”?

造成“单元测试无用论”的第一个原因是,运用这一方法的时机不恰当。不少项目在一开始真正关心质量的人很少,更谈不上采用一整套的方法论去保证质量了。产品在开发出来后发现到处存在问题,只会拆西墙补东墙根本就不能阻止问题一而再,再而三地出现。于是,开始想起单元测试。一声令下,整个项目开始做单元测试。单元测试以模块为单位,需要先把项目拆分出来。如果你的项目代码整体耦合程度较高的话,单元测试根本无从说起,拆分的工作会让你痛苦不已。

单元测试是一项耗时的工作,但管理者却往往希望在短期内看到效果。或者单元测试还没做到位管理层就等不及了,催你马上开始下一步的开发,结果只能是前功尽弃。正确的做法是:在项目的开始之初就引入单元测试。对于以前没有部署单元测试的项目,先只对新增加的、相对独立的模块做单元测试、并逐渐覆盖老代码。

第二个导致“单元测试无用论”的原因是,方法没有运用到位。要保证单元测试的有效性一定要引入另一个概念--代码覆盖。关于代码覆盖,我以后会另外再写一篇文章介绍。只有将单元测试和代码覆盖结合在一起,综合使用才能保证单元测试的效果。

02

最原始的“单元测试”

这里给读者展示一下,不使用任何单元测试框架时,是怎么做单元测试的。

下面简单以linux内核链表为例:

struct list_head { struct list_head *next, *prev;};/*定义一个结构体,只含有表示前驱和后继的指针,它就是我们的主角了*/#define LIST_HEAD_INIT(name) { &(name), &(name) }/*静态初始化*/#define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name)/*动态初始化*/static inline void INIT_LIST_HEAD(struct list_head *list){ list-》next = list; list-》prev = list;}/*插入操作*//*删除操作*//*合并操作*/。。.

完整代码很长,这里没有必要全部贴出,能起演示作用就足够了。

现在就以INIT_LIST_HEAD函数为例,来考虑如何为这个函数设计测试用例。INIT_LIST_HEAD函数的实现是如此的简单,以至于很容易让人觉得为它设计单元测试是多余的。但是,从单元测试的角度看,只要不存在可行性问题就不应考虑因为简单而不对其进行验证。而且,放弃对之进行验证,以后会降低代码覆盖率。

做单元测试需要通过编写程序的方式来完成,所编写的用于测试的代码又称为单元测试用例。

下面我们来简单实现一个INIT_LIST_HEAD函数的测试用例:

int main(int argc,char **argv){ struct list_head list; /*避免函数没有使用参数而引发waining*/ UNUSED(argc); UNUSED(argv); list.prev = (struct list_head*)0xaaaa; list.next = (struct list_head*)0xbbbb; INIT_LIST_HEAD(list); /*检查前指针*/ if(list.prev != list){ return -1; } /*检查后指针*/ if(list.next != list){ return -1; } return 0;}

这应该是史上最简单的测试用例,功能非常简单,首先是故意将list结构体中的各个指针变量初始化为一个随机值。然后在调用完INIT_LIST_HEAD函数之后,检查各成员是否被初始化为了list,以判断INIT_LIST_HEAD函数是否正常工作了。注意:这个测试程序还有一个约定,返回-1代表测试失败,返回0表示测试成功。

这个测试用例是基于我们对INIT_LIST_HEAD函数有足够的了解之后编写的,这种测试方法在软件测试领域有个正儿八经的名字,叫白盒测试。

相信通过这个NIT_LIST_HEAD函数的测试用例,你已经初步建立起了对单元测试的印象。但是千万不要以为单元测试仅此而已,这是我刻意简化的结果。要完整地掌握单元测试,还要好好学习一段时间。

目前,对于这个小小的单元测试案例,还有很多的不足,下面简单罗列了几项:

如果对于每一次检查都采取直接写if语句的形式,将造成大量的冗余代码,并且测试用例的编写效率也会很低。

通过观察程序是否返回0或者是-1的方式来判断所有的测试是否通过并不直观,一旦出错也无法马上判断是那一步测试出了问题。毫无疑问,我们需要更加直观的方式来展示哪一步成功或者哪一步失败。

一份严谨的测试用例,会有大量的判定。如果一个测试程序存在100次判定,其中出现了3次失败,那最终显示一个百分比的测试通过率会比较直观,比如可以显示97%的测试成功了。

后面会进一步介绍如何自己搭建一个简单实用的单元测试框架,来解决上面这些问题。也会陆续展开介绍mock方法、打桩、错误注入、代码覆盖、动态分析、静态分析、性能优化等内容。

03

总结

正如很多其他技巧,比如打桌球、滑雪一样,测试驱动开发也要花费相当长时间来练习。许多开发者已经接受了这种技术,而且再也不想回到从前“后期调试式编程”的方式去了。

它会使你的代码:

产生的bug更少

调试时间更短

完全可以通过提交你的单元测试案例,来证明你的项目可靠性。

责任编辑:haq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 测试
    +关注

    关注

    8

    文章

    6025

    浏览量

    130694
  • 嵌入式
    +关注

    关注

    5186

    文章

    20143

    浏览量

    328686
  • 代码
    +关注

    关注

    30

    文章

    4940

    浏览量

    73120
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    嵌入软件单元测试的全面研究与实践

    引言 嵌入软件单元测试是确保嵌入式系统质量和可靠性的关键环节。嵌入式系统广泛应用于汽车电子、工业控制、医疗设备等关键领域,其软件直接操控硬件,任何微小的错误都可能导致严重后果。
    的头像 发表于 12-01 14:31 150次阅读

    CW32嵌入式软件开发的必备知识

    设计的原则和方法,能够设计出高效、可维护的软件系统。 了解嵌入式系统的实时性要求,能够设计出满足实时性要求的软件系统。 8、 测试与验证 掌握单元测试、集成测试和系统
    发表于 11-28 07:48

    单元测试专业工具在新能源开发中的作用研究

    单元测试的历史由来与发展 单元测试的概念可以追溯到20世纪60年代,伴随着计算机科学和软件工程学科的发展而逐步形成。早期的计算机科学研究(20世纪60年代)中,程序员意识到仅依靠手工调试和集成测试
    的头像 发表于 11-03 16:03 306次阅读

    嵌入式C/C++回归测试四大最佳实践(附自动化测试工具TESSY使用教程)

    嵌入式开发中,一次微小的代码改动都可能引发“蝴蝶效应”,如何守护系统的稳健?推荐专业的自动化测试工具#TESSY,源自戴姆勒-奔驰,是嵌入式C/C++单元/集成
    的头像 发表于 10-31 14:21 182次阅读
    <b class='flag-5'>嵌入式</b>C/C++回归<b class='flag-5'>测试</b>四大最佳实践(附自动化<b class='flag-5'>测试</b>工具TESSY使用教程)

    嵌入式软件测试与专业测试工具的必要性深度解析

    嵌入式系统作为控制、监视或辅助装置运行的专用计算机系统,其软件测试面临着独特的挑战和严格的要求。专业测试工具在嵌入式软件开发过程中发挥着不可替代的作用,是确保系统可靠性和安全性的关键保
    发表于 09-28 17:42

    边聊安全 | 软件单元测试的设计方法

    上海磐时PANSHI“磐时,做汽车企业的安全智库”软件单元测试的设计方法写在前面:软件单元测试的设计是一个系统化的过程,旨在验证代码的最小可测试部分(通常是函数或方法)是否按预期工作。软件单元
    的头像 发表于 09-05 16:18 4216次阅读
    边聊安全 | 软件<b class='flag-5'>单元测试</b>的设计方法

    HarmonyOSAI编程单元测试用例

    根据选中的ArkTS方法名称,CodeGenie支持自动生成对应单元测试用例,提升测试覆盖率。 在ArkTS文档中,光标放置于方法名称上或框选完整的待测试方法代码块,右键选择CodeGenie
    发表于 08-27 14:33

    单元测试工具TESSY现已支持ABIX HiperSIM,助力MELEXIS MLX16 汽车嵌入式系统的软件验证

    TESSY现已支持ABIX HiperSIM,为基于MELEXIS MLX16架构的汽车嵌入式系统提供高效、可靠的软件验证解决方案。自动化测试+高保真仿真,助力提升软件质量与开发效率。
    的头像 发表于 07-17 13:39 663次阅读
    <b class='flag-5'>单元测试</b>工具TESSY现已支持ABIX HiperSIM,助力MELEXIS MLX16 汽车<b class='flag-5'>嵌入式</b>系统的软件验证

    新能源车软件单元测试深度解析:自动驾驶系统视角

    ‌第一部分:新能源车软件单元测试的战略重要性 ‌汽车电子架构的范式转变‌ 随着新能源车的普及,汽车电子架构从传统的分布ECU(电子控制单元)向集中式域控制器(Domain Controller
    发表于 05-12 15:59

    新能源车背后的隐形守护者:软件单元测试的生死较量‌

    。这个教科书级的避让动作背后,是超过8000万行代码的精密协作,而确保这些代码绝对可靠的秘密武器,正是我们今天要揭秘的软件单元测试。 ‌一、代码世界的显微镜:单元测试为何重要‌ 如果把整车软件比作一座摩天大楼,单元测试就是检查
    的头像 发表于 05-12 11:00 435次阅读

    单元测试嵌入式软件中的关键作用及winAMS工具的卓越贡献

    1. 单元测试概述 ‌定义与核心目标‌ 单元测试是软件开发过程中针对程序模块(如函数、类或组件)的最小可测试单元进行的验证活动。其核心目标在于隔离代码片段,验证其功能是否符合设计预期,
    的头像 发表于 04-11 14:31 751次阅读

    嵌入式软件单元测试的必要性、核心方法及工具深度解析

    一、为什么嵌入式软件必须重视单元测试? ‌嵌入式系统的特殊性‌ 在汽车 ECU、医疗设备控制器等场景中,软件直接操控硬件,‌单比特错误可能导致刹车失灵或呼吸机故障‌。不同于 PC 软件可频繁热更新
    的头像 发表于 03-21 14:53 948次阅读

    如何成为嵌入式开发工程师?

    如何成为嵌入式开发工程师? 成为嵌入式开发工程师通常需要掌握一系列技能和知识,并且在实践中不断积累经验。以下是一些基本步骤和建议: 1. 基础教育:- 获取电子工程、计算机科学或相关领域的学位
    发表于 02-19 10:39

    如何提高嵌入式代码质量?

    技术 现代的嵌入式开发工具和测试技术可以极大地提升代码质量和开发效率: 1. 静态分析工具:如Coverity、Lint等,能够帮助发现潜在的代码缺陷和安全漏洞。 2. 单元测试和集成测试
    发表于 01-15 10:48

    嵌入式系统开发中的测试方法 嵌入式系统开发与AI结合应用

    嵌入式系统开发中的测试方法 嵌入式系统开发是一个复杂的过程,涉及到硬件和软件的紧密结合。测试是确保系统可靠性和性能的关键步骤。以下是一些常用的测试
    的头像 发表于 12-09 10:22 2026次阅读