测试员最不愿遇到的18个测试问题,怎么解决?

news2024/11/17 9:40:25

 测试员最不愿遇到的18个测试问题,怎么解决?

目录:导读

 测试员最不愿遇到的18个测试问题,怎么解决?

一  测试充分度(Test Sufficiency)

二  测试有效性(Test Effectiveness)

三  测试用例瘦身

四  测试分层

五  减少分析遗漏

六  用例自动生成

七  问题自动排查

八  缺陷自动修复

九  测试数据准备

十  异常测试

十一  并发测试(Concurrency Test)

十二  回滚的测试

十三  兼容性测试

十四  Mock

十五  静态代码分析

十六  形式化验证(Formal Verificaition)

十七  防错设计(Mistake Proof)

十八  可测性(Testability)


导读:对于软件测试来说,怎么样才算测够了?如何评价测试的有效性?那么多测试用例,以后怎么删?在软件测试中会遇到非常多的问题,阿里研究员郑子颖分享了18个他总结出的难题以及相关看法,希望对同学们有所启发。

先前我在上一家公司的时候看到过内部有个网站有一个Hard Problems in Test的列表,上面大概有三四十个问题的样子,是各个部门的测试同学提供的。但可惜后来那个list失传了,我很后悔自己当时没有保存一份。后来很多次我都想要找到那份list,因为上面列的那些问题指出了测试专业在自身专业性上的巨大发展空间。那份list上的问题让当时的我相信,软件测试这件事情本身的难度一点都不亚于软件开发,甚至可能更难一点。
如果今天要重建这么一份Hard Problems in Test列表,下面这些问题是我会加到这份列表上的[1]。

一  测试充分度(Test Sufficiency)

如何回答“测够了吗“(包括测新和测旧)。代码覆盖率是衡量测试充分性的起点,但远远不是终点。要回答”测够了吗“,至少还要考虑是否测了所有的场景、所有的状态、所有的状态转移路径、所有的事件序列、所有可能的配置、所有可能的数据等等等等。即便如此,我们可能还是无法100%确信我们已经测够了。可能我们最终只能做到非常趋近于测够了[2]。


二  测试有效性(Test Effectiveness)

如何评价一组测试用例的发现bug的能力。有效性(发现bug的能力)和充分性(测够了没有)是两个正交的属性。评价测试用例有效性可以通过正向的分析进行,例如,分析测试用例是否校验了所有在测试过程中SUT落库的数据。更具有通用性的做法是变异测试(Mutation Testing),即在被测代码里注入不同的“人造bug”,统计多少能被测试用例感知到。目前变异测试我们已经有工程化规模化的落地了,后续的工作重点有:1)如何防止钝化(或曰“杀虫剂效应”),2)不但对被测代码进行注入,还能对配置、数据等进行更全面的注入。


三  测试用例瘦身

以前广告行业有句话:我知道广告费有一半是浪费掉的,但不知道哪一半是浪费掉的[3]。
软件测试也有类似的困惑:那么多用例,要花那么多时间去跑,我知道这里面有很多时间是浪费掉的,但我不知道哪些时间是浪费掉的。浪费的形式包括:

  • 冗余步骤:有些是浪费在一些重复的步骤上,每个用例都要去做一些类似的数据准备,每个用例都要去执行一些中间过程(这样才能推进到下一步)。

  • 等价类:一个支付场景,我要不要在所有的国家、所有的币种、所有的商户、所有的支付渠道和卡组的排列组合都测一遍?这么测,代价太高。不这么测,我担心可能某个特定商户在某个特定国家有个特定逻辑我就漏掉了。对于具体的业务,还可以进行人肉分析。有没有更通用的、而且比较完备和可靠的等价类分析的技术手段?

  • 我有N个用例,我猜这N个用例里面可能存在M个用例,即使删掉这M个用例,剩下的N-M个用例的效果和之前N个用例的效果一样。如何识别是否存在这样的M个用例、如果存在的话是哪M个。


我参加过内部一场质量线晋升到P9的评审,当时有个评委问了那位同学一个问题:“那么多测试用例,以后你怎么删”。这个问题看似简单,其实非常难。我觉得,从原理上来说,如果测试充分度和测试有效性的度量都做的非常好了、度量成本非常低了,我们是可以通过大量的不断的尝试来删用例的。这是一种工程化的思路,也许还有其他的理论推导的思路。


四  测试分层

很多团队都会纠结到底要不要做全链路回归、做到什么程度。这个问题的核心点就是:有没有可能、有没有一种做法,只要把系统间的边界约定的足够好足够完整,就可以做到在改动一个系统的代码后,不需要和上下游系统进行集成测试,只要按照边界约定验证好自己的代码就可以确保没有任何regression了。
包括我在内的很多人相信那是可能的,但既无法证明,也不敢在实操中就完全不跑集成。我们也缺乏可以完全复制的成功经验,缺乏一套完整的方法论指导开发团队和QA团队要怎么做就可以达到回归无需集成上下游。
有时候,我觉得我现在就像是哥德堡的市民,不断的走啊走,尝试找出一条一次性不重复的走过那7座桥的路线。但也许就有那么一天,有一个像欧拉那样的人会出现在我面前,用理论证明告诉我,那是不可能的。


五  减少分析遗漏

分析遗漏是很多故障的原因。开发做系分的时候,有一个corner case没考虑到、没有处理。测试做测分的时候,忘记考虑某个特殊场景了。兼容性评估,评估下来没有兼容性问题的,但结果是有的。而且很多时候,分析遗漏属于unknown unknowns,我压根就不知道我不知道。有没有一套方法和技术,可以减少分析遗漏,可以把unknown unknowns转化为knowns?


六  用例自动生成

Fuzz Test、Model Based Test、录制回放、Traffic Bifurcation(引流)等都是自动生成用例的手段。有些已经比较成熟(例如单系统的录制回放、引流),有些多个团队都在探索(例如Fuzz),有些则一直没有大规模的成功实践(例如MBT)。我们也有过探索如何从PRD里通过NLP来生成用例。用例自动生成中,有时候难点还不是生成test steps,难度反而是怎么生成test oracle。Anyway,测试用例自动生成是一个非常大的领域,这个方向上未来可以做的还非常多。


七  问题自动排查

包括线上和线下。对于比较初级的问题,自动排查方案往往有两个局限性。首先,方案不够通用,多多少少比较定制化。其次,比较依赖人工积累规则(说的好听点叫“专家经验”),主要是通过记录和重复人肉排查的步骤来实现。然而,每个问题都不完全一样,问题稍微一变,之前的排查步骤可能就不work了。现在有一些技术,比如调用链路的自动比对,对排查问题和缺陷自动定位很有帮助。


八  缺陷自动修复

阿里的Precfix、Facebook的SapFix等是目前比较知名的一些工业界的做法。但总的来说,现有的技术方案,都有这样那样的局限性和不足,这个领域还在相对早期阶段,后面的路还很长。


九  测试数据准备

测试用例的一个重要设计原则是:测试用例之间不应该有依赖关系,一个测试用例的执行结果不应该受到其他测试用例的执行结果(包括是否执行)的影响。基于这个原则,传统的最佳时间是确保每个测试用例都应该是自给自足的:一个用例需要触发的后台处理流程应该由这个用例自己来触发,一个测试用例需要的测试数据应该自己来准备,等等。但如果每个用例所需要用到的测试数据都是自己来从头准备的,执行效率就比较低。怎么既不违背“测试用例之间不应该有依赖关系”的大原则,又能减少测试数据的准备时间?
我设想的是一种更加完备的数据银行。每个测试用例执行完后,都会把它自己产生的数据交给数据银行,例如,一个在某个特定国家的已经通过KYC、已经绑了一张卡的会员,一笔已经支付成功的交易,一个已经完成入驻签约流程的商户。下一个测试用例开始的时候,会先问一下数据银行:“我要一个满足这样这样条件的商户,你有没有”。上个用例跑出来的那个商户正好符合条件,数据银行就会把商户“借”给这个用例用。而且一旦借出,直到被归还前,这个商户不会被借给其他用例。
经过一段时间的运行,数据银行能够学习到每个测试用例需要什么样的数据、以及会产生什么样的数据。这个知识是通过学习得到的,不需要人肉去添加描述,所以也能适用于老系统的存量用例。有了这个知识,数据银行可以实现两个优化:

  • 一次测试执行批次开始后,数据银行会看到这个批次中后面那些用例需要什么样的数据,提前先准备起来。这样,等执行到那些用例的时候,数据银行里就已经有符合条件的数据准备好了。

  • 根据每个测试用例需要什么样的数据、以及会产生什么样的数据,数据银行可以合理的编排测试用例的执行先后次序,最大化的实现测试数据的复用,减少测试数据的量和准备开销。


测试银行把测试数据“借”给用例的时候,可以有多种不同的模式。可以是独占(exclusive)的,也可以是共享的。共享的也可以指定共享读、共享写、还是都只读不能写(例如,一个商户可以被多个用例用来测试下单支付结算场景,但这些用例都不可以去修改这个商户本身,例如重新签约)。
如果把开关、定时任务等resource也作为一种广义的测试数据由数据银行来管理,能实现测试用例尽可能并行执行。例如,有N个用例都需要修改一个开关值,这N个用例如果并行执行的话就会相互影响,他们相互之间应该串行执行。但N个用例中的任何一个,都可以和这N个用例之外的用例并行执行。数据银行掌握了每个用例对各种资源的使用模式的详细情况,再加上每个用例的平均运行时间等数据,就可以最优化、最准确的对一批测试用例进行编排,做到可以并行的都尽可能并行、不能并行的确保不并行,而且还可以在一个批次的执行过程中不断的调整余下还未执行的用例的编排。
这样一个数据银行是普遍适用的,不同业务之间的差异无非是具体的业务对象和resource不一样。这些差异可以通过插件形式实现。如果有这么一个通用的数据银行[4],可以很方便的adopt,大量的中小软件团队的测试效率都可以得到明显的提高。这样的一个更加完备的数据银行的想法,我到目前为止还只是想法,一直没有机会实践。


十  异常测试

一个分布式系统,它的内部、内部各部分之间以及它和外部的交互都会出现各种异常:访问超时、网络连接和耗时的抖动、连接断开、DNS无法解析、磁盘/CPU/内存/连接池等资源耗尽等等。如何确保系统的行为(包括业务逻辑、以及系统自保护措施如降级熔断等)在所有的情况下都是符合预期的?今天我们的线上演练(本质上也是一种异常测试))已经做了很多了。如何把更多的问题提前到线下来发现?对于一个复杂的分布式系统来说,要遍历所有可能出现异常的地方和所有可能出现的异常,异常用例的数量是非常大的。此外,某些异常情况下,系统对外表现出来的行为应该没有变化;而另一些异常情况下,系统行为是会有变化的。对于后一类,如何给出每一个异常用例的预期结果(即test oracle),也是比较有难度的。


十一  并发测试(Concurrency Test)

并发(concurrency)可能出现在各个level:数据库层面,对同一张表、同一条记录的并发读写;单系统层面,同一个进程内的多个线程之间的并发,单服务器上的多个进程之间的并发,以及单个服务的多个实例之间的并发;业务层面,对同一个业务对象(会员、单据、账户等)的并发操作,等等。传统的并发测试是基于性能测试来做的,有点靠撞大运,而且经常是即便跑出问题来了也会被忽视或者无法repro。并发测试领域,我接触过的一些成果包括Microsoft的CHESS以及阿里的谭锦发同学在探索的分布式模型检查&SST搜索算法。


十二  回滚的测试

安全生产三板斧宣传了多年,在阿里经济体内大家都能做到“可回滚”了。但我所观察到的是:很多时候我们有回滚的能力,但是对回滚后系统的正确性,事前保障的手段还不够。我们更多的是靠灰度和监控等事后手段来确保回滚不会回滚出问题来。事实上,过去两年,我自己已经亲身经历过好几次回滚导致的线上故障。回滚测试的难度在于:需要覆盖的可能性非常多,一个发布可能在任何一个点上回滚。回滚可能还会引发兼容性问题:新代码生成的数据,在新代码被回滚后,老代码是否还能正确的处理这些数据。


十三  兼容性测试

代码和数据的兼容性问题有很多形式。例如,如何确保新代码能够正确的处理所有的老数据?有时候,老数据是几个月前的老代码产生的,例如,一个正向支付单据可能会到几个月以后才发生退款退票。有时候,老数据可能就是几分钟前产生的:用户的一个操作,背后的流程执行到中间的时候代码被升级了。验证这些场景下的兼容性的难度在于:需要验证的可能性太多了。今天的退款请求对应的正向单据,可能是过去很多个版本的代码产生的。一个业务流程执行到中间具体什么地方代码被升级了,可能性也非常多。
异常测试、并发测试、回滚测试、兼容性测试,这些问题的一个共同点是:我们知道这些问题是可能存在的,但要测的话,需要测的可能性又太多。


十四  Mock

测试的有效性也依赖于mock的正确性。既然是mock,它和被mock的服务(包括内部的、二方的和三方的)的行为就多多少少会有差异。这种差异就有可能导致bug被漏过。前人也为此想出了“流量比对”等办法。我曾经有另一个想法:“一鸭三吃”。也就是说,通过bundle和compiler instruction等方法,让同一套源代码支持三种不同的编译构建模式:

  • 正常模式:这就是和今天的编译构建是一样的,产出的构建物是拿去生产环境跑的。

  • Mock模式:这个模式编译出来的就是该服务的一个mock,但由于是同一套代码编译出来的,最大可能的保留了原来的业务逻辑,做到最大限度的仿真。而且由于是同一套代码编译出来的,后期也不会有“脱钩”的担心,应用代码里的业务逻辑变化都能及时反映在mock里,大大减少mock的人肉维护工作量。

  • 压测模式:这个模式编译出来的也是一个mock,但这个mock是用来给(上游)做性能测试用的。过去在线下的性能压测中经常遇到的情况是:我们想要压的系统还没到瓶颈,这个系统的下游系统(往往是一个测试环境)反而先到瓶颈了。压测模式编译出来的这个mock牺牲了一部分的业务逻辑仿真,但能确保这个mock本身性能非常好,不会成为性能瓶颈(但对lantency仍然是仿真的)。


这个“一鸭三吃”的想法so far还停留在想法层面,我还一直没有机会实践一下。


十五  静态代码分析

有一些类型的问题,要用通常意义上的软件测试来发现,难度和成本很高,但反而是通过静态代码分析来发现反而比较容易。例如,ThreadLocal变量忘记清除,会导致内存溢出、会导致关键信息在不同的不同的上游请求之间串错。另一个例子是NullPointerException。一种做法是通过fuzz testing、异常测试等手段来暴露代码里的NPE缺陷,以及可以在执行测试回归的时候观察log里面的NPE。但我们也可以通过静态代码分析,更早的就发现代码里面可能存在的NPE。有一些并发问题也可以通过静态代码分析来早期准确发现。总之,我们希望尽可能多的通过静态代码分析来防住问题。


十六  形式化验证(Formal Verificaition)

除了在协议、芯片、关键算法等上面的运用以外,形式化方法在更偏业务的层面是否有运用的价值和可能?


十七  防错设计(Mistake Proof)

严格来说,防错设计并不是software testing范畴内的。但做测试做久了就发现,有很多bug、很多故障,如果设计的更好一点,就压根不会发生(因此也就谈不上需要测试了)。去年我总结了一下支付系统的防错设计,后面希望能看到在各类软件系统形态下的防错设计原则都能总结出来,另外,最好还能有一些技术化的手段来帮助更好的落地这些防错设计原则,这个难度可能比总结设计原则的难度更高。


十八  可测性(Testability)

虽然目前大部分开发和QA同学都知道“可测性”这么件事情,但对可测性把握的还不够体系化,很多同学觉得可测性就是开接口、加test hook。或者,还没有很好的理解可测性这个东西落到自己这个领域(例如支付系统、公有云、ERP)意味着什么。在需求和系统设计分析阶段还不能做到很有效很有体系的从可测性角度提出要求,往往要求比较滞后。我希望可测性设计可以总结出一系列像程序设计的DRY、KISS、Composition Over Inheritance、Single Responsibility,Rule of Three等设计原则,总结出一系列的反模式,甚至出现像《设计模式》那样的一本专门的著作。
以上就是我会加到Hard Problems in Test列表的问题,也是我已经或打算投入精力解决的问题。

写在最后

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!

看到这篇文章的人有觉得我的理解有误的地方,也欢迎评论和探讨~

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/186817.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人大金仓数据库-表的定义

表的定义 使用子查询来创建表 通过复制student表创建student_m表,只复制原表中的部分数据到新表 通过复制course表创建course01表,复制原表中的全部数据到新表 使用LIKE语法来创建表 非空约束会默认复制到新表中 create table t03(LIKE t02 INCLUDING…

设计循环队列

前言:队列中有一种特殊的存在——环形队列,其有一定的价值与意义,这篇文章主要由一道与其相关的例题来引出相关的知识内容。 注:下述解题过程是用C语言实现。 目录 一:题目简述 二:环形队列的简单介绍 …

什么是Docker?看这一篇干货文章就够了!

什么是Docker容器技术的起源容器技术 vs 虚拟机什么是容器什么是docker如何使用dockerdocker是如何工作的docker的底层实现总结作为程序员我们应怎样理解docker? 容器技术的起源 假设你们公司正在秘密研发下一个“今日头条”APP,我们姑且称为明日头条&…

ORB-SLAM3算法和代码学习——重定位Relocalization

0总述 重定位是ORB-SLAM系列保持跟踪稳定性的保障,从ORB-SLAM沿用至ORB-SLAM3。主要作用是在跟踪失败时,通过词袋向量搜索在关键帧数据库中寻找和当前帧相似的关键帧作为匹配帧,建立数据关联并计算当前帧的位姿,恢复相机的运动。…

正大国际期货:外盘短线交易九大生存准则:从亏损预期出发

一、生存是第一位 这并不是陈词滥调,投机是非常危险的活动。投机非并输赢那样简单,首要的任务是在顶峰和谷底之间的波动中生存,如果连生存都做不到,你根本就没有谈及赢的资格。 即使有了好的资金管理、正确的系统和行动的前提&a…

Ubuntu18.04下安装配置AndroidStudio软件图文教程

运行环境:操作系统为Ubuntu18.04,android-studio版本为2022.1.1.19-linux,Java版本为jdk8,安装路径/opt/android-studio/,当前用户为xqf222,sdk下载路径默认为/home/xqf222/Android/Sdk 详细步骤和指令如下: 1.安装JDK8&#xf…

VTK CT重建(一) MPR 多层面重建 四视图

除了MPR之外,在CT重建后处理中还有很多别的常用方法,包括 多层面重建(MPR)最大密度投影(MIP)最小密度投影(MinIP)表面阴影遮盖(SSD)容积漫游技术&#xff08…

go validator参数校验器自定义规则及提示(自定义异常返回提示语)

原文连接:https://segmentfault.com/a/1190000040445612 笔者针对参数为指针的情况做了一点小优化 这里我们用validator用来做参数校验,gin默认的github.com/go-playground/validator,可以直接使用 除此之外还有一些其他的工具也挺好用的&am…

Linux基础指令

本文已收录至《Linux知识与编程》专栏!作者:ARMCSKGT演示环境:CentOS 7 目录 前言 正文 查看当前用户whoami 查看当前目录路径pwd 清理屏幕clear 查看目录下文件指令ls 进入目录指令cd 以树状结构显示目录文件tree 创建普通文件指令t…

Leetcode.1669 合并两个链表

题目链接 Leetcode.1669 合并两个链表 Rating : 1428 题目描述 给你两个链表 list1和 list2,它们包含的元素分别为 n个和 m个。 请你将 list1中下标从 a到 b的全部节点都删除,并将list2接在被删除节点的位置。 示例 1: 输入:li…

rtsp实时流通过rtmp推送到服务端

ffmpeg可以实现这个功能。ffmpeg支持rtsp协议,也支持rtmp。在这个案例中rtsp是输入, rtmp是输出,ffmpeg实现了转码的功能。下面可出一个整体思路流程图。 如图1所示:在获取都rtsp流以后,解复用(demux&…

检测之VOC转YOLO

文章目录检测所用数据有几种文件格式,我们对于检测,将使用VOC格式做为基础,与其它格式的的互转实现部分如下:检测系列相关文章参考如下链接: VOC数据的结构介绍及自定义生成,用labelimg自已标注VOC标准数据…

Notepad++作死,国产文本编辑器Notepad--发布

作死的Notepad Notepad 和 Notepad 都是基于 Windows 的文本编辑器,通常用于编写和编辑纯文本文件。 这两个应用程序都是简单的轻量级程序,提供基本的文本编辑功能。 Notepad是一口君经常使用的一款文本编辑软件,用了大概10年了。 然而Not…

配置并行(RH294)

当Ansible处理playbook的时候会顺序运行每个play确定play的主机列表之后Ansible将按顺序运行每个任务一般来说,所有主机必须在任何主机在play中启动下一个任务之前成功完成任务理论上,Ansible可以同时连接到play中的所有主机来执行每项任务Ansible所进行…

​力扣解法汇总1669. 合并两个链表

目录链接: 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目: https://github.com/September26/java-algorithms 原题链接:力扣 描述: 给你两个链表 list1 和 list2 ,它们包含的元素分别为 n 个和 m 个。…

解决Vue启动失败报错:Module not found: Error: Can‘t resolve ‘less-loader‘

问题描述 今天想在网上找一个好看的登录页面,把别人的代码引入进来之后,发现项目编译不了,并且报错了: Module not found: Error: Can’t resolve ‘less-loader’ 分析问题 从错误的日志就可以看出来,是缺少了less-…

Linux: 关于 SIGCHLD 的更多细节

僵尸进程 何为僵尸进程? 一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用 wait 或 waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程成为僵尸进程的因素 子进程 先…

AOP的一点浅薄理解

AOP思想应该怎么去理解! Aspect(切面): Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。 Joint point(连接点):表示在程序中明确定义的点…

C语言学习笔记-变量

我们知道每一个程序的运行都需要内存,那么C语言的变量的定义是什么含义呢? 假如我花了200元买了一块4G内存条,然后我定义了一个int a ;就意味着从这4G的内存上要拿走4个字节,又定义了一个int b;那么b同样也要从4G的内存…

【OpenGL学习】OpenGL实现 基于Phong模型的基础光照

基于Phong模型的基础光照 在本节中,我们将利用 Phong 光照模型来完成一个简单的光照场景的渲染。 一、Phong 光照模型 Phong光照模型是20世纪70年代被提出的一种渲染逼真图像的方法,模型的提出者是越南出生的计算机图形学研究员Bui Tuong Phong&#…