在构思这个主题的题目时,脑子里先是蹦出来三个词,“哲学”、“本质”和“底层逻辑”。
同时转念一想,打算通过一篇文章就想探到如此深度岂非痴心妄想和不知天高地厚。实际上,诸多冠此类帽子的文章多是名不副实。算了,人近不惑,脑力渐衰,把书读薄也更甚于读厚。
不过,读薄的前提至少是要有体系和脉络。所以选用了“脉络”这个词,细想来,确实比前面想到的那三个词更合我真意。
在开始这条脉络之前,还是先把概念澄清,以设定一个理解基线。
0
什么是软件测试?
《软件测试的艺术》的作者梅耶的定义是“软件测试就是为了发现缺陷而运行程序的过程”。
尽管不同的角色在不同的角度都有不同的定义,比如有从需求入手的、有从质量着眼的,也有从一致性、风险和成本等展开的……
各有各的道理,但我从实务的角度看,选用了梅耶的定义,毕竟运行程序发现缺陷是我们日常可见的测试的最显著特点。
好,正式开始。
为了更贴近实际项目运行,我大体按照业务的运行时间线,把这条脉络的一头一尾分别定义为“测试策略”和“测试汇总”。
1
测试策略
在企业里,我们所做的所有工作,从来不是独立的,也从来不是单一的技术问题或者管理问题,而是需要一个统筹的考虑。
测试也一样,开始之前我们要有“策略”,这是一个High-level的概念,多少有一点模棱两可,很难说清楚其准确内涵,不同干系人也有不同的期望,本文给三个参考的维度,分别是测试规则或指南、测试目标和测试原则。
尽管实际工作中,我们基本无法清晰地拆分出隶属于不同维度的工作,而是相互混杂和渗透,但为了便于沟通和理解,暂且还是按此拆分。
1.1 测试规则或指南
测试规则或指南,我们把它定义为统领性、强制性或推荐性的一些规则、要求或建议,它们一般由公司层面整体定义,并要求执行。
比如,什么节点前应该做测试分析,应该用哪个报告模板,什么测试条目是必测项,测试用例的选择要考虑哪些,测试的准入准出规则是什么,是否必须先完成冒烟测试,什么情况下必须做压力测试,测试覆盖率怎么考虑,测试通过率怎么定义,如何区分不同层次测试的责任人,缺陷的处理方式,测试与需求的追溯性要求,单元测试必须在其他测试前完成,回归测试时测试用例如何选择,自动化测试比例及开始时机怎么定义,必须执行全量测试的标准等等。
会有很多的角度去定义,无法详述。
总之,是一些基于公司策略和历史经验等制定的纲领性的文件。
当然,多数不那么规范的公司不会定义很细,要求也不会很严格,姑且有这么个概念。
1.2 测试目标
测试目标呢,比较宽泛的理解有查找问题、确认满足需求、避免问题泄漏、保证客户满意、提升质量、降低成本、推进持续改善等等。
这些内容虽然并不难理解,但还是太泛泛而谈了。
在具体的某个客户、某个平台、某个项目、某次迭代、某次交付的组合里,会有多方面因素要考虑,这是个复杂的且需要背景信息的事,无法简单说明。
举几个可能需要思考的问题,感性感觉下。
这个客户对测试报告的提交需求是什么?这次上了哪些主要功能点?该平台或该项目是否有历史LLs?已经识别到什么潜在风险需要测试探测吗?内部有什么质量目标?本次交付变更点是什么?自动化测试台架是否可用?这次是工程车间装车,还是台架或者产线?什么功能是本次交付最关注的?是否上路,上什么路……
综合各种信息,项目经理或测试经理可以来统筹判断及调整本次测试的目标,据此再来进行后续的计划、执行等工作。
1.3 测试原则
考试有答题技巧,工作有方法 论,打仗有兵法。测试原则差不多等同于这类。在整个和测试相关的工作中,是否有一些参考性的原则呢?
1、要尽可能早地测试。这是质量成本的原则,发现问题越晚,成本和影响越高越大。
2、不可能进行穷举式测试。进行完全的测试是不可能的,完全没有任何缺陷的软件也是不存在的,要根据风险评估进行测试用例设计,进行最佳的测试量定义。
3、关注缺陷群集效应。二八法则我们都听说过,在此也是适用的,少量的模块经常包含大部分缺陷。统计数据也表明,一段程序已发现的缺陷越多,则该段程序发生更多缺陷的可能性也很大.
4、杀虫剂悖论。如果同一个测试人员重复执行相同的测试,该方法将无法发现新的测试缺陷。这既有测试用例更新不及时的原因,也有测试人员的思维定势和思维懈怠的原因。所以测试用例要经常更新,测试人员也可以适时轮换。
5、测试只能证明存在缺陷,而无法证明不存在缺陷。因为测试实际上是一个样本实验,不可能涵盖所有情况。
6、没有缺陷不代表软件一定能够使用。比如测试用例本身未覆盖需求,这其实说明了测试本身的局限性,也说明了我们要进行全方位软件开发及测试管理的必要性。
7、测试最好由非软件开发人员担任。这是从心理学角度来看的,毕竟让一个人否定自己的工作是令人沮丧的,而且如果开发人员对某个功能有错误认识,再去测试可能依旧无法识别。
8、测试顺序。为了尽可能早地合理退出,要首先执行具有较高失败概率的测试。比如,最好依次进行冒烟测试(核心功能预测试)、缺陷重新测试、测试新功能、测试修改或优化的特性、测试未改变的特性(回归测试)。
实际工作中,策略更多是在项目经理或测试经理脑子里的整体谋篇布局,以上三个维度是落于纸面上的一个参考。
2
测试管理
有个通盘的策略性考量后,就可以进入管理层面的工作上了。
接下来看测试管理。
当组织结构庞大和软硬件功能复杂时,测试也同样会变得很复杂和容易混乱。
这时,就非常需要由专门的人按照特有的流程进行组织和管理。管理的范畴很大,为了避免描述混杂在一起,我们这里只谈小管理,不涉及具体工程层面的内容。
我们可以将测试管理的目标定义为,根据确定的测试范围,交付与测试相关的工作包(例如,测试规范、测试执行、评审和报告等),同时还要满足项目进度计划中定义的里程碑节点。
简单来说,就是先要明确谁在什么时间做完什么,然后,在出现异常时,进行调整。
当然,这个交付目标的达成需要很多支持。
首先,要明确做什么,根据我们的策略定义测试范围,比较粗略的分类,可能会有单元测试、集成测试、系统测试,以及辅助性的文档、报告、评审之类的工作。这些内容之间可能会有依赖关系和前后次序等。同时,也要识别出责任人,根据我的项目经验,没有明确到具体的人的任务99%会延期。
接下来,要确认资源(Resource),这里包括人员和设备及样品,再细分还要看人员是否充足与人员能力是否足够、设备及样品是否充足和可用。比如,可能考虑到软件测试工程师、系统测试工程师、具备特殊测试能力的专家,以及台架、ECU、线束、CAN工具、诊断仪、示波器等等。当这些有问题时,就需要管理人员进行调配。
对于执行人而言,会提出工作包的完成时间(Duration),这个也是经常在测试人员和管理人员之间针锋相对的地方,测试人员希望As long as possible,管理人员希望As soon as possible。就看实际工作中,如何论战和平衡了。
如果成本管控比较好的公司,还会考虑成本(Cost),一般包含人员工时和材料成本。特别是涉及到第三方公司或其他独立结算团队时。
对于项目经理而言,最关心的是完成的截止时间及监控,也就是催催催。根据整个项目的进度和前面的一些梳理,就可以得到详细的计划。至于所需的详细程度,取决于产品的复杂性和所涉及的测试人员的数量等。
然而,出问题和延期几乎是必然的,基本没有哪一个项目能够完全避免,解决这些问题也是管理人员最主要的任务了。或拿出自己的Buffer,或减少测试,或调整优先级,或谈判,或带风险并行,或升级管理层支持。
整个管理过程会有不同的工具支持、流程部署、模式风格,暂不详述,各有各的做法。
这里给一个我所见到的众多做法中做得比较严谨的案例。
简单思路是,在测试之初,定义一张完整的测试全量计划表,这里面包含系统、软件、硬件、结构等所有的测试条目,以及每个条目测试与否、不测试的分析理由、通过与否、对应缺陷和报告链接等。由项目经理或测试经理作为总负责人,组织相关人员进行测试范围识别、测试计划排定、测试进度跟踪、测试报告提交完善等。每次迭代都对应这样一份统一的测试汇总表,通过这种方式可以系统地将测试管理起来。
3
测试过程
上面的阐述都属于规划管理性质,下面开始进入具体操作层面。
测试的分类方法有很多种,比如。
按照测试时序,可以把整体的测试过程分为需求分析、测试计划、测试设计、测试环境搭建、测试执行、测试报告这几大部分。
按照测试类型,可以分为功能测试、性能测试、负载测试、压力测试、冒烟测试、安全性测试、兼容性测试等。
按照是否执行程序,可以分为静态测试和动态测试。
按照对软件内部信息的了解程度,可以分为黑盒测试、白盒测试、灰盒测试。
按照测试层次呢,又可以分为单元测试、软件集成测试、软件需求测试、系统集成测试、系统测试、验收测试这几大部分。
从另外一个工程应用的思路,我们将测试层次还能做一个整合,单元测试、集成测试都属于“设计”层(Technical),软件需求测试和系统测试属于“功能”层(Functional),而验收测试属于“方案”或“问题解决”层(Solution)。
五花八门,不一而足。
粗略来看,从测试层次的角度,基本也能够覆盖到其他分类的内容。为了理解起来比较清晰,而且业内讲得非常多的V模型或ASPICE也是按照层次来划分的,所以我们着重从测试层次逐一铺展开。
3.1 单元测试
单元测试是软件验证的最低级别,是对软件的最小可测单元进行验证的工作。
但如何定义单元一直是争论的焦点,通常我们会说是一个函数,可有的函数代码段很短,这样去做又会显得很浪费,经常也会将单元异化为具有独立功能的组件。
总之,单元是一个人为定义的最小测试点,去针对软件的详细设计(即代码)来进行的,一般是开发自己去完成的。
测试方法 论有静态代码分析,如熟知的基于MISRA C规范的静态代码扫描,或者关注代码覆盖率的测试,如语句覆盖率、分支覆盖率、MC/DC覆盖度等。
在这个阶段之后,软件组件可以被集成了。
3.2 软件及系统集成测试
软件集成测试的目的是为集成的软件组件与软件架构的一致性提供证据,包括组件之间的接口。
测试的内容可能包括通过接口的数据是否丢失、组件组合后能否达到预期父功能以及一个组件是否会对其他组件造成影响等。
此外,非功能的测试会涉及到CPU负载率、内存占有率等资源消耗的内容。
在测试思路的选择上,一般有两类:增量式和非增量式,主要差别在于是一次性集成完毕后一次性测试,还是边集成边测试。前者容易造成大量缺陷报出而难以定位原因的问题,而且修改过程也会不断引入新问题,造成混乱。
系统集成测试呢,是沿着HW/SW的接口进行的,通过物理引脚(物理层)和逻辑协议(逻辑层)连接的HW/SW接口构成系统内部接口。
因此,系统集成的先决条件是已经集成的软件和硬件。从技术上讲,系统集成只需根据BOM在硬件上刷新软件即可。这和软件集成过程中功能集成是逐步进行的有些不同。
尽管理论上,软件集成测试是侧重于软件模块之间的接口的,系统集成测试是着眼于软硬件之间的接口的,但是系统不会单独悬浮于软件和硬件之上,硬件需要软件驱动,软件也需要运行在硬件上,所以系统集成测试的用例往往来源于软件或硬件各自的测试,有时也会来源于系统测试。
此外,还可以提的一点是,系统可以分几个层级的,比如,ECU能作为一级系统,ECU加传感部件能作为二级系统,ECU加传感部件再加执行部件能作为三级系统,三级系统集成于整车环境里还能被定义为四级系统。
宏观来讲,系统集成测试需要考虑到这所有的系统及对应接口,只不过越往上走,就越不是单一的软件范畴了。
3.3 软件及系统需求测试
软件需求测试,顾名思义,就是为在芯片上运行的集成软件符合软件需求提供证据,证明软件功能满足需求。
系统需求测试呢,习惯被简称为系统测试,也是类似,是确保测试集成系统,以提供符合系统需求的证据,并确保系统已准备好交付。
与软件需求测试的差别,主要是系统需求测试要在集成软件、标定、硬件、外设设备、数据乃至人员的系统下进行的,这也是最常见的最终交付前的测试。
测试内容上,主要是针对需求、风险、特定用例或其他高层级系统行为的描述进行的功能测试与非功能测试(如性能、负载、压力、可靠性、鲁棒性、恢复性、安全性、兼容性等各类测试)。
这个层次的测试也都是黑盒测试,不需要了解内部实现细节,只需关注输入与输出。
3.4 验收测试
验收测试,实际上已经脱离了严格意义的工程开发的范畴,在ASPICE里也没有明确定义。
但是,现在行业内越来越多地思考用户导向和用户思维,所以把验收测试单独拿了进来。
我倾向于把验收测试定义为非专业的客户评判,比如汽车行业领导或特定人员的试驾,就属于比较典型的验收测试,它是更高层级的、更贴近实际使用的一种确认,他们可能不懂软件,不懂汽车,只是从自己的需要上来给出判断。
还有个例子,你买新房交房时或者毛坯房装修后,业主要去验房,就是典型的验收测试,他们显然不那么懂装修、懂材料、懂建筑资质、懂行业标准,但他们会从使用上、美观上、感觉上去评判。
以往的汽车行业基本不太会关注终端消费者的切身体验,大家没那么多可选的,造什么买什么。现在及往后的时间,终端消费者会介入得越来越多,以新势力为领头的各大车企也会不遗余力地关注到他们的“验收”。
4
测试报告
测试报告及相应文档定义的主要的焦点在于测试基础(需求或设计)和所有测试级别上相应的测试用例及结果之间的可跟踪性。
理论上或者说做得比较好的,这些测试相关文档都要通过配置管理管理起来。
测试执行后,得到的结果和评估结果被输入到不同格式的报告中。其中的评估必须要进行,以避免不适当的测试用例或测试环境引起的“假阳性”,就像最近持续做的核酸检测,要审核的。
测试失败的用例要建立相应的缺陷记录,以确保可追溯性。如果一个缺陷在专家评审后可以被接受,那么它也应该在测试文档中被清楚地注释。
5
测试汇总
这一部分就到了我们这条“脉络”的结尾,实际项目中很多都没有这部分,各类报告都是散落各处的、千奇百怪模板的、由各人负责的报告。
为了”客户”满意,我想这个工作包最好是有。
一份整体测试状态的汇总可以比较清晰地让内外部都知道当前的或历史的软件质量状态。
当然,做起来会有些障碍,特别是系统复杂、分工细的领域,及时且准确维护一张不断更新的大表是需要一番心力的,后续我们可以探讨下是否有改善思路。
文章有点长,但还是只能在“皮毛”和“脉络”上聊一下,毕竟测试是一门很大的学问。
最后呢,尝试总结一下这条“脉络”。
汽车软件测试是一项以寻找问题为主要目标,基于各种组织策略、测试原则和业务限制,而进行多层次验证并提供证据的管理和工程实践工作。
完