嵌入式软件测试

article/2025/10/26 9:51:02

如何在目标板上实时测试应用程序

为什么嵌入式系统测试困难?
 


在目标板上测试面临的系列问题:

1、如何下载测试到板子上,然后如何收集测试结果

2、如何累积可重复自动执行的测试

3、如何尽可能减少人工工作

4、如何减少内存不够的问题

       这些都是经常碰到但难以解决的问题。随着项目代码越来越大,开发人员数量和代码数量都变多,完全懂得目标硬件和软件工作原理的可能仅限于少数工程师。大多数项目中的工程师面对复杂的系统甚至不知如何在目标设备上执行测试。

测试什么代码?

       解决问题的一种方案是在主机端进行软件测试。对于那些跟硬件或者交叉编译无关的代码,使用主机平台的编译器构建可执行测试程序然后执行是可行的,这可以一定程度找到一些逻辑错误,但对有些与硬件相关的问题却无能为力。不同的编译器,不同的处理器,代码执行表现可能存在某些差异,实际上,这也是为什么对于高安全性软件的测试需要尽可能在最终环境上进行测试。这意味着在你的测试环境中应该使用与软件产品环境一致的构建工具和处理器。

       除非你直接测试配置到嵌入式设备上的目标代码(Object Code),你不能确保不会引入诸如编译器漏洞,数据对齐以及大小端问题。


1.单元测试的必要性

单元测试是软件开发的重要一环,尤其对嵌入式开发。因为嵌入式开发受限于开发环境、调试工具等因素,不能和纯PC软件开发一样使用很多先进的工具。这就需要开发者在开发过程中,进行更细的模块划分,更明确的接口,更详尽的测试。

传统的开发先出设计方案,然后跟着写出代码,最后在做测试---常被叫做bug调试,所以在代码“写完”之后,还有一半左右的开发量。人都会犯错,在设计和编码中也会犯错,如果后期调试编程去解决设计和编码中引入的错误,那么可能已经过了几天几周几个月,反馈如此只晚,已经不能从错误中吸取经验了,下次还会犯同样的错误。此外根据软件工程理论,1个bug越是在后期越是花费巨大的成本去修复,并且随着系统复杂度的增长,在一个大的系统中去查找某一个细节具体的问题,相比于在小的模块中去查找问题会花费多倍的时间成本。

2.单元测试框架解剖

一般地单元测试需要实现以下几个基本功能:
1. assert
各种assert,比如AssertTrue、比如AssertFail、AssertStrEquals、AssertIntEquals......
条条大路通罗马,这些Assert有各种功能,其实就是包装了断言的函数。比如AssertStrEquals(str, "open"),进行str和字符串“open”的比较,如果不相同则会报错。
根据框架的结构,在assert失败时候,有的进行长跳转longjmp,有的对类似failCount的全局的变量进行加1并记录错误位置。
2. 错误位置记录
得益于C语言的LINE、FILE宏,这是2个ANSI C标志支持的内置宏定义,可以得到当前的的行数和文件名。 在断言失败的地方,记录文件名和行号,以供用户查询错误的位置。

1

2

char buf[HUGE_STRING_LEN];

sprintf(buf, "%s:%d: ", _FILE_, _LINE_);

3. 测试case管理
这是测试框架区别于自己写的assert测试函数最根本的地方。 测试框架为了提高函数利用率,减少重复,方便测试例程汇总等,都会进行各种封装。比如以下几条。
1)setup和teardown
大部分的测试框架都提供这两个函数,主要是因为有些测试case,有大量重复的代码,比如准备输入数据,测试完毕后清理现场等通用的功能。
2)测试例子汇总
有的叫做TestSuit,有的叫做TestFixtures。把一类相似功能的测试case进行汇总,方便更高层次的调用,也方便用户管理测试例程。
3)测试的调用
多个测试例程汇总后,构成一个数组(表格),启动运行,一般由xxxRun函数负责。
在嵌入式c中,一般都有一个函数指针来操作,这也是为什么所有的测试case的函数名称都使用相同的声明,test_case需要和调用该测试的指针同类型。

4. 测试的执行
测试的执行本质就是函数的长跳转。可以看做在父函数中调用子函数,这个子函数如果是测试例程的话,子函数就会包含assert相关的语句,而assert语句在出错后,会记录错位位置和错误消息,然后进行长跳转(longjmp),longjmp和setjmp(buf)成对出现,返回到调用的位置,然后进行下一个测试case。

    for (i = 0 ; i < testSuite->count ; ++i){Test* testCase = testSuite->list[i];TestRun(testCase);if (testCase->failed) {testSuite->failCount += 1; }}

 

3. 测试框架的本质

1)为了更好的组织测试,提供的测试组的批量处理功能,一般由for循环遍历一个table数组实现;
2)为了减少重复进行测公用函数提取,比如准备测试环境和清理现场;
3)测试需要的各种断言;
4)断言失败后的跳转、记录错误位置-FILE-, -LINE-宏的使用;
5)测试case运行的监控和结果的汇总。


综上,如果你实现了上面的几个功能,那么也就自己完成了一个测试框架。
其实测试框架是一个很简单的事情,如今测试框架有很多,像VS这样的IDE已经集成了单体测试,所以对于一个开发者怎么规划测试才是测试工作的第一要务。
如何恰当的写测试用例,既不延误开发又不会造成工程臃肿,还能尽可能的覆盖测试范围,这才是测试中最花费功夫的地方。


测试涵盖设计文案,实现方式,代码框架,需求分析。

静态测试:阅读,查阅,学习需求文档,包括市场已有相关产品的说明手册。通过学习理解设计的初衷。并且对需求进行分析,拆分成测试用力。

动态测试:分阶段进行代码review,白盒测试,已经最后的产品黑盒测试。

嵌入式测试框架中的一个特点在开始就是一场探索性的测试方式。“探索性”的思考,“探索性”的测试行为贯穿于整个流程中。探索性测试在嵌入式测试的过程中并不等同于free test;也不是没有计划的冒险性测试。需要有测试基础知识和方法论的,制定符合项目阶段需求的测试计划,并且有效实施。

第一步:在需求分析阶段设计,学习框架。

这里提到的框架是产品设计框架。它将决定测试的内容是在产品实现的每个阶段,研发需要给测试提供的接口。

嵌入式软件开发案例

一个常规嵌入式软件开发架构包括下面几个模块:

1. 通讯协议

2. 实施系统

3. 控制装置

4. 事件处理

5. PC端的工具

6. 硬件配置

测试需要搞清楚这些模块之间的关系,任务内容,包括这些模块之间的通讯方法之后才能算对产品系统有一定的了解,之后进一步了解产品需求分析奠定好基础。

第二步:详细学习需求手册,学习原型代码结构

为什么要学习代码结构?代码结构中包含了对数据最直观的定义,比需求分析里面的数据解释清楚很多。

例如:需求手册里一句:用户通过网线连接装置后通过定义好的通讯协议完成数据发放。

就这一句话,测试需要查阅:通讯模块中的传送函数。在这个接口中将定义出传送数据的数据结构。有代码意识的测试人员看数据结构定义比看文档里面的文字定义速度快。另外一个好处,帮助研发完成了一个内部的code review。

第三步:在原型扩展的阶段,配合研发实现unit test。

理论上unit test是由研发自己完成的纯白盒测试。某论坛上的实践提议是:在研发人员动手写方法函数之前,需要完成各自方法函数的unit test方法,之后通过自己搭建的unit test框架结构来实现方法,任何的code变量都会因为unit test的存在及时地反馈给研发人员,从而作到高质量的控制。然后实际过程当中,我们多半遇到的是一堆函数接口,没有文档,没有code comments,没有unit test,这个时候怎么办?测试人员在前面两步的基础上,可以在这里帮助研发完成一部分unit test。主要考虑全局变量的稳定性;参数范围的准确性和一部分代码强壮性的测试。

第四步:探索性方法测试法去完成功能测试和集成测试

这部分本身需要研发来实现必要的测试接口,但是主要测试目的还是验证方法实现与否。最好的情况是,在代码级别又测试人员设计接口参数和返回值定义。在执行时,提供对应的测试接口运行方式。为何要说是探索性的测试方法,因为考虑到测试人员的代码能力和对产品的需求学习是否正确。那么在过程中,需要进行一步步探索的方式,吃透黑盒需求,搞清楚代码关系,才能完美的完成嵌入式级别代码的方法测试。

例如:状态机测试。状态机,顾名思义,功能而言就是通过状态变化完成信息透传。对于没有架构观念的人直接会跳过状态机功能测试,直接实现所谓的系统测试,就是通过配置工具直接作用于底层产品的功能测试,这样虽然节约时间,但是架空的状态机的测试,最终出现问题时会无法定位问题的根本。

只有把整个产品分模块吃透功能测试之后,进行集成管理发布的流程,才能说,此时发布的产品是可以用于进行黑盒系统测试的产品。

第五步:黑盒测试法去完成系统测试

这部分实际工作当中需要分别出:verification和validation。为何要分清楚。只有找到完全负责的对象之后,测试行为才能找到重心。Verification的负责对象是研发,即使走黑盒测试,主要目的是看代码功能是否完成和基本数据流程是否传递并工作。Validation的负责对象是用户,走黑盒测试的目的主要是模拟用户使用产品流程,不带破坏性操作的情况下完成系统的性能测试和强度(健壮性)测试。这部分的case的生成依赖第二和第四步。问题来了,在黑盒测试阶段我们依据工具完成嵌入式测试吗?是的,需要依附其他工具。现在每一套嵌入式的工具都会携带一部分在PC或者移动设备上的交互软件实现操作,也有一部分直接携带HMI,那么我们测试时还需要其他工具吗?需要!这些工具是这一整套产品,并不是用来给测试人员操作测试核心对象的。说白了,这些配置产品也是测试对象。在研发团队中需要有人来维护对应的测试工具。这样的测试工具可以作为配置设备的测试对比。

第六步:自动化测试计划完成维护测试,性能测试

能走自动化测试团队是比较厉害的。在短周期项目中,自动化测试部分只能作用于维护,而对于长周期项目来说,自动化是可以期待回归测试作用的。本身源于PC端,一直辅助功能的技术在嵌入式测试流程中也只能体现出辅助的功能。可以依据产品属性来定义自动化测试的存在与否。当产品周期短,实现产品内容繁多,操作复杂就不建议使用自动化测试。自动化测试方法的启动取决于测试对象,测试工具的发展。并不是团队自动化技能有否。

 

 


http://chatgpt.dhexx.cn/article/RfMOC2Fh.shtml

相关文章

全国软件测试大赛嵌入式测试步骤及所需工具

文章目录 前言一、所需工具二、测试步骤1.从慕测平台上下载题目2.搭建测试环境3.测试脚本编写怎么编写 总结 前言 全国软件测试大赛嵌入式测试最全步骤及所需的工具 一、所需工具 若需要测试工具请私信我 二、测试步骤 以2019年的省赛题目为例 1.从慕测平台上下载题目 下…

嵌入式软件测试(黑盒测试)-----三年嵌入式软件测试的理解

前言 文章内容为本人这三年来在嵌入式软件测试&#xff08;黑盒&#xff09;上的一些积累吧&#xff0c;说起来也挺快的&#xff0c;毕业三年的时间就这样过去了&#xff0c;在两家公司工作过&#xff08;现在这家是第二家&#xff09;&#xff0c;这几年的测试项目基本都是围绕…

简单聊聊嵌入式软件测试

一、什么是嵌入式&#xff1f;什么是嵌入式软件测试&#xff1f; 此文不从行业术语来讲&#xff0c;就用大白话来描述&#xff0c;容易明白&#xff0c;不当之处&#xff0c;还请见谅和指正。 嵌入式&#xff1f;简单的可以理解为上位机或者单片机&#xff0c;或者运行微型可定…

嵌入式测试

一、嵌入式软件测试的方法 嵌入式软件测试分为4个阶段&#xff0c;即模块测试、集成测试、系统测试、硬件/软件集成测试。前3个阶段适用于任何软件的测试&#xff0c;硬件/软件集成测试阶段是嵌入式软件所特有的&#xff0c;目的是验证嵌入式软件与其所控制的硬件设备能否正确地…

机器学习必备知识点 之 先验概率和后验概率

机器学习必备知识点 见 机器学习必备知识点 我们可以把概率获得分为两种&#xff1a; 一种是从原因到结果——先验概率一种是从结果到原因——后验概率 举个例子&#xff1a; 这里的P(C1)&#xff0c;P(C2)&#xff0c;P(x|C1)&#xff0c;P(x|C1)都是先验概率&#xff0c;因…

Gretna网络分析之先验知识

目录 1. 简介 1.1 小世界网络 1.2 平均路径长度 2.功能键介绍 2.1 Global Network metrics 2.2 Nodal and modular network metrics 3.彩蛋 &#xff08;转载请注明来自Ressan博客&#xff09; 1. 简介 网络&#xff1a;由节点和连线构成的图/模型&#xff0c;用来研究…

如何将先验知识注入推荐模型

看到知乎上的一个问题“如何向深度学习模型中加入先验知识&#xff1f;”&#xff0c;觉得这是一个很好的问题&#xff0c;恰好自己在这方面有一些心得&#xff0c;今天拿出来和大家聊一聊。 说这个问题有趣&#xff0c;是因为提问者一定是对DNN的“智能”程度不满意了&#xf…

如何给模型加入先验知识?

来源&#xff1a;PaperWeekly 作者&#xff1a;Billy Z 模型加入先验知识的必要性 端到端的深度神经网络是个黑盒子&#xff0c;虽然能够自动学习到一些可区分度好的特征&#xff0c;但是往往会拟合到一些非重要特征&#xff0c;导致模型会局部坍塌到一些不好的特征上面。常常一…

几何深度学习 - 利用几何先验知识的深度学习

深度学习很难。 虽然通用逼近定理表明足够复杂的神经网络原则上可以逼近“任何东西”&#xff0c;但不能保证我们可以找到好的模型。 尽管如此&#xff0c;通过明智地选择模型架构&#xff0c;深度学习取得了巨大进步。 这些模型架构对归纳偏差进行编码&#xff0c;为模型提供…

如何向深度学习模型中加入先验知识?

链接&#xff1a;https://www.zhihu.com/question/279012198 编辑&#xff1a;深度学习与计算机视觉 声明&#xff1a;仅做学术分享&#xff0c;侵删 作者&#xff1a;采石工https://www.zhihu.com/question/279012198/answer/1298985606 1) CNN 中使用的卷积层就是利用了图像像…

浅谈模型中加入先验知识

必要性 端到端的神经网络是个黑盒&#xff0c;虽然能够学习到一些可区分度好的特征&#xff0c;但是也会拟合到一些非重要特征&#xff0c;导致模型局部地区会有一些不好的特征表现&#xff0c;所以可以加入一些先验知识来优化这些区域表现。 首先给出可以有效的加入先验信息的…

综述:如何给模型加入先验知识

转载自&#xff1a;https://zhuanlan.zhihu.com/p/188572028 这里写目录标题 为什么要给模型加入先验知识&#xff1f;1 基于pretrain模型给模型加入先验2 基于输入给模型加入先验3 基于模型重现给模型加入先验4 基于CAM图激活限制给模型加入先验 为什么要给模型加入先验知识&a…

1 先验知识

目录 1. 脑的解剖学结构 &#xff08;1&#xff09;额叶Frontal lobe &#xff08;2&#xff09;顶叶Parietal lobe &#xff08;3&#xff09;颞叶Temporal lobe &#xff08;4&#xff09;枕叶Occipital lobe 2. 脑区命名 3. 脑组织定位 &#xff08;转载请注明来自Re…

给模型加入先验知识

‍ 点‍击上方“机器学习与生成对抗网络”&#xff0c;关注星标 获取有趣、好玩的前沿干货&#xff01;‍ ‍ 来源&#xff5c;知乎 作者&#xff5c;Billy Z 链接&#xff5c;https://zhuanlan.zhihu.com/p/188572028 报道&#xff5c;人工智能前沿讲习 01 模型加入先验知识的…

神经网络基础--指数加权移动平均ewma

因为神经网络中的常用优化算法都会涉及到指数加权移动平均&#xff08;exponential weighted moving average&#xff0c; ewma&#xff1b;也可称为exponential moving average&#xff0c;ema&#xff09;&#xff0c;所以这里单独写下这个知识点。 ewma通过将历史的值和当前…

EWMA 指数加权移动平均 模型

Exponentially Weighted Moving Average(EWMA)指数加权移动平均是一种常用的序列数据处理方式&#xff0c;如下&#xff1a; 在时间 t, 根据实际的观测值&#xff08;或量测值&#xff09;我们可以求取 EWMA&#xff08;t&#xff09;如下&#xff1a; EWMA(t ) λY(t) ( 1-λ…

时间序列分析 - 移动平均SMA, EMA(EWMA) 之python

pandas: pandas.DataFrame.rolling pandas.DataFrame.ewm pandas.DataFrame.mean 其中rolling可以指定窗口类型win_type,比如boxcar, boxcar, triang, blackman, hanning, bartlett 以hanning window为例&#xff0c;其窗口形状为钟型&#xff0c;曲线函数为&#xff1a; p…

线性和EWMA指数加权移动平均模型

线性和EWMA指数加权移动平均模型 模型应用场景&#xff1a; 对历史测量值赋权重&#xff0c;对现在t时刻的数值做估计。 1 移动平均 移动平均是是技术分析其中一种分析时间序列数据的工具移动平均可抚平短期波动&#xff0c;将长线趋势或周期显现出来。数学上&#xff0c;移…

(四十八)用EWMA和GARCH模型估计波动率和相关系数

ARCH、EWMA、GARCH介绍 案例 对2016年至2018年沪深300指数的涨跌幅数据建立ARCH(1)、EWMA和GARCH(1,1)三种波动率模型&#xff0c;并以30天前的数据为起点&#xff0c;逐一预测后一天的波动率。 ARCH(1) import numpy as np import pandas as pd dfpd.read_excel(C:/Users/De…