如果前面几篇文章讲的是"怎么设计用例、怎么把软件测得更全面",那这一篇要讲的内容,就是测试工作中你每天都要打交道的"主角"——BUG。
其实每个测试人第一天上手时,都是从"提 BUG"开始干活的。但"提 BUG"这件事远没有字面上那么简单:一个缺陷能不能被开发一眼看懂、能不能被快速修对、会不会被开发反驳回来,都取决于你描述它的水平。而在这背后,还藏着一套完整的规则——缺陷要分几级、它在系统里要经历哪些状态、和开发起了争执该怎么处理。这些就是我们这一篇要掰开揉碎讲清楚的东西。
我们先把底色铺上:因为 BUG 是"软件测试生命周期"里不断冒出来的东西,所以要先飞高一点,看清楚整个软件测试的生命周期长什么样。
一、软件测试的生命周期:先看清 BUG 诞生的土壤
有一句话在软件测试界流传很广:软件测试贯穿于软件的整个生命周期。这句话不能只当口号听,我们得把它落到具体的流程上去理解。
所谓软件测试的生命周期(Software Testing Life Cycle,简称 STLC),指的是一套测试流程。这套流程不是一盘散沙,而是按照一定顺序执行的、一系列特定的步骤,其目的就是保证最终交付的产品质量符合需求。在生命周期里,每一步(也叫一个阶段)都是有计划、有系统地在执行的,而且每个阶段都有自己明确的目标和交付产物——你每走完一步,手里都应该多出一样东西,比如一份文档、一批用例、一份报告。
下面这张主线,就是这个周期里大致要经历的阶段:
需求分析 → 测试计划 → 测试设计与开发 → 测试执行 → 测试评估 → 上线 → 运行维护
我们逐个阶段看它们各自要解决什么问题:
- 需求分析:这是源头。测试人员要先站在不同角度把需求"过一遍筛子"。站在用户角度,想这个需求是否合理;站在技术角度,想技术上是否可行、是否还有优化空间;站在测试角度,想这里面是否存在业务逻辑错误、冗余、冲突等问题。也就是说,测试不是等代码写完了才开始,而是从需求讨论阶段就要进场审视。
- 测试计划:制定测试计划,回答几个"元问题"——什么时候开始测试?什么时候结束测试?测试要耗多久?这一步的交付物是一份测试计划文档。
- 测试设计与开发:参考需求文档、技术文档等,编写测试用例;同时写测试文档,明确标注将使用到的测试方法、测试工具、测试形式等等。交付物是测试用例和测试设计文档。
- 测试执行:充分利用测试用例和测试工具,对项目尽可能做到全面的测试覆盖。这是真正"跑起来"的阶段,也是 BUG 大量冒出来的阶段。
- 测试评估:评估测试是否通过、本次测试是否有遗留的 BUG,最终需要产出一份测试报告。
- 上线:项目测试结束后,将项目发布到线上环境,测试人员需要跟踪上线,并测试线上环境下软件运行是否正确。
- 运行维护:软件上线后测试并未彻底结束。测试人员对项目的业务和操作非常了解,加上沟通表达能力一般都比较强,所以测试人员常常要参与用户使用软件的培训,在试运行期间收集问题并及时反馈给相关负责人。
把这七个阶段串起来看,你会发现"测试"这个词是加了引号的——它不只是"点一点、跑一跑",而是在需求阶段就审视合理性、在计划阶段就定策略、在维护阶段还在收集反馈。所以"软件测试贯穿整个生命周期"的准确含义是:测试人以多种角色、多种动作,全程参与软件的一生,而不是只在某个时间窗口里"测一把"。
这一篇的主角 BUG,主要出现在"测试执行"这个阶段,但它的影响会一路波及到后面的评估、上线甚至维护。 这也是为什么你处理 BUG 的方式,会被每一个测试老手反复校验。
本节思考题
问:为什么说"测试贯穿整个生命周期",而不是只在"测试执行"阶段?
**答:**因为"测试"不等于"跑用例"。它是一系列保障质量的动作。在需求分析阶段测试就要入场,是为了提前发现需求本身逻辑不通、冗余、冲突的问题——这类问题如果拖到代码写完才发现,改造成本极高;在计划阶段定测试策略和资源,是为了让后面所有动作有章可循;在执行阶段发现问题;在评估阶段判断质量是否达标、有无遗留缺陷;在上线阶段验证线上环境是否正常;在维护阶段收集用户反馈持续改进。一头一尾其实都算测试的职责范畴。所以准确地说,不是"测试只在这些阶段做,而是测试的动作遍布所有阶段",这正是这句话的深层含义。
二、什么是缺陷:给 BUG 下一个精准的定义
我们已经反复提到 BUG,那到底什么才算 BUG?这节我们从定义入手,把概念钉死。
2.1 缺陷的常见定义
计算机领域的 BUG(也译作缺陷)通常这样定义:一个计算机 bug 指在计算机程序中存在的一个错误(error)、缺陷(flaw)、疏忽(mistake)或者故障(fault),这些 bug 使程序无法正确地运行。Bug 产生于程序的源代码或者程序设计阶段的疏忽或者错误。
这里出现的 error、flaw、mistake、fault 四个英文词,在严谨的软件工程教材里有细微差别(比如 error 常指人犯的"差错",fault 常指落在代码里的"缺陷",failure 指运行时暴露出来的"失效"),但在日常工作中,大家基本把它们当近义词混用,指的都是"程序有问题、跑不对"这件事。所以你在看资料时见到这几个词,不用纠结它们的差异——心里知道它们说的是同一类东西就行。
2.2 更精准的判定标准
上面那个定义偏向现象描述,真正在判断"这算不算 BUG"时,软件工程界还有两条更精准的判定标准,值得记牢:
第一,当且仅当规格说明是存在的并且正确,程序与规格说明之间的不匹配才是错误。 这句话的意思是:判断依据"需求规格说明书"必须既存在、又正确。如果需求文档本身写的是错的(比如规格写反了、含糊不清),那程序跟它不一致,并不能简单归罪于程序"错了"——因为拿错的尺子去量,得出的结论本身就不可信。这时候要先去校准那把"尺子",也就是需求文档。
第二,当需求规格说明书没有提到的功能时,判断标准以最终用户为准:当程序没有实现其最终用户合理预期的功能要求时,就是软件错误。 这句话很关键。现实里需求文档常常没把所有细节都写全(甚至根本没写)。这时候不能因为没有规格可对,就说"这不是 bug"。判断的尺子递给了用户——只要用户按常识"合理预期"这个功能应该是这样,而程序没做到,那就是缺陷。比如一个电商 App 的"购物车",规格里没写"删除已售罄商品要不要提示",但用户普遍预期"我点删除,它就该删掉并给个反馈",如果点了没反应,即便没违反任何文档,它也是缺陷。
这两条标准合起来,就是缺陷判定的"双尺子":有规格,拿规格量;没规格或规格含糊,拿用户合理预期量。 这在后面"和开发争论"那一节也能作为你的立论依据——你提的 bug 是否成立,往往就落在这两把尺子上。
本节思考题
问:需求文档没写"登录按钮在弱网下要给出 loading 提示",但用户点击登录时因为网络慢半天没反应,看起来像卡死了。这算缺陷吗?
答:算。 按第二条标准:需求规格说明书没有提到这个功能,那么判断以最终用户的合理预期为准。用户在等待网络响应时,普遍合理预期是"系统给我一个正在加载的反馈",而不是一潭死水。程序没实现这个合理预期,就构成缺陷。这也反向提醒产品:好规格虽然不能把所有细节写尽,但至少该把"加载态、空态、异常态"这些用户能感知的状态想清楚。
三、描述缺陷的五个要素:让开发一眼看懂你的 Bug
接下来进入最实战的部分:怎么写一个"开发能看懂"的 BUG。
3.1 为什么描述缺陷还要讲"要素"
先看一个反例。假设你在 Bug 平台里写了这么一句:
浏览器打开链接失败
乍一看没问题,可仔细一想全是问号:哪个浏览器?Chrome 还是 IE?在一台机器上失败还是在很多台都失败?"失败"是白屏、是报错、还是转圈转不出来?对开发来说,就凭这句话,他根本不知道该从哪下手。为什么会这样?
这里有个很微妙的心理学现象:人在编写文档时,经常会出现"自己想表达的"和"实际写出来的"南辕北辙的情况。 你以为你写清楚了,其实只写了你脑子里的"结论",把推导过程和关键条件都省了。而开发看到的只有你留下的文字,他没有你的上下文,自然捕捉不到更多有效信息。结果就是沟通效率低下、工作质量低下。
为了避免这种"书难达意",业界把"一个合格的缺陷描述"总结成了固定的要素清单。照着清单补齐,就能最大程度减少歧义。
3.2 描述缺陷的基本要素
描述一个缺陷,基本要覆盖以下五个要素:
- 问题出现的版本——在哪个软件版本上发现的;
- 问题出现的环境——在什么操作系统、浏览器、设备环境下发现的;
- 问题出现的步骤——你是怎么一步步操作到出问题的那一步;
- 预期结果——按照设计或常理,这一步应该得到什么结果;
- 实际结果——程序实际给了你什么结果。
这五要素既能帮开发定位,也能帮你自己复现。下面看一个教材里非常经典的完整案例。
拿网站 https://www.101eduyun.com/ 举例,登录页上的二维码被登录模块遮挡:
- 问题出现的版本:谷歌浏览器版本 123.0.6312.123(正式版本)(64 位)
- 问题出现的环境:Windows 家庭版
- 问题出现的步骤:1. 打开谷歌浏览器,输入网址
https://www.101eduyun.com/;2. 等待首页页面渲染完成 - 预期结果:二维码与登录模块不会出现遮挡,二维码可以正常扫描
- 实际结果:二维码被登录模块遮挡,二维码扫描失败
你看,同样是"打开链接"那件事,一旦补全五要素,它就从一句含糊的话,变成了开发可以直接照着复现的描述:什么浏览器、什么系统、走哪两步、期望什么样、实际什么样,一目了然。
3.3 五要素之外,你还可以给 Bug 加的"佐料"
五要素是底线,但一份好报告远不止于此。为了让开发更快定位,你最好再补上这些:
- 缺陷标题:用一句话概括"在哪、做了什么、出了什么问题",比如"登录页二维码被登录模块遮挡,无法扫码"。标题决定开发第一眼扫列表时的优先级判断。
- 所属模块:这个 bug 落在哪个功能模块(如"登录/注册"、"支付"),方便按模块分工指派。
- 严重程度与优先级:这是下一节的重点,先知道有这两列就行。
- 复现频率:是 100% 必现,还是 5 次里出现 1 次?如果是偶现,你观察到的"概率",对开发排查内存泄漏、竞态这类随机性 bug 极有帮助。
- 复现步骤的最小化:这一点单独拿出来重点讲,见下条。
3.4 两个必须避开的坑:复现步骤要最小化、证据要截图留痕
坑一:复现步骤能多简就多简,别把无关操作一股脑塞进去。
什么叫"最小化复现步骤"?就是剔除所有和触发该缺陷无关的步骤,保留一条最短、最干净、几步就能从干净状态走到出问题的路径。比如你是从"登录→进首页→点开设置→切账号→回首页"才发现的遮挡,但如果直接在首屏就能复现,那你只留"输入网址、等首页渲染"两步就够了。为什么?因为步骤越少,开发需要推理和执行的路径越短,他越容易看清"到底是哪一行代码导致了遮挡",也越容易被自动化脚本复现来验证修复。
反之,如果你把一大串操作全贴上去,开发复现时千人千面,谁也说不准卡在哪一步,定位成本直线上升。记住:最小复现步骤,是给开发最好的礼物。
坑二:光说"出错"不够,必须留下证据。
描述里最好附上截图或录屏(用截图工具或录屏软件把现象固定下来)、日志(有报错日志就把相关片段贴出来)、必要时还有网络请求(打开开发者工具 Network 面板,看看是哪个接口返回了什么)。截图要能对照环境信息,最好带上时间、带上能看出本该怎样/实际怎样的画面;日志要贴"出错前后的相关片段",别一整份几千行全塞进去。
为什么证据这么重要?因为"文字描述"永远可能被理解出偏差,而证据是客观的。你给一张"二维码确实被挡住了"的截图,比写十句"它被挡住了"都有说服力——这也直接关系到后面和开发争论时的底气。
本节思考题
问:同样发现一个 bug,测试同学 A 提交的是"XX 页面有问题,请修复";测试同学 B 提交的是带完整五要素、截图、日志、且是 3 步最小复现路径的 bug。开发分别会怎么反应?这体现了什么?
**答:**对 A,开发大概率会来回追问"哪个页面?什么问题?截图有吗?"——一来一回消耗的是双方时间,甚至可能因为描述不清而被驳回。对 B,开发可以照单直接复现、直接定位,修复效率和沟通成本都大为改善。这体现了"缺陷描述质量"的本质价值:一份完整的 Bug 报告,本身就是一次成功沟通的一半。 描述做到位,能显著降低返工、扯皮和无效沟通。这也呼应了后面要讲的"先检查自身是否描述清楚"这条处理争执的原则。
四、缺陷的级别:严重程度与优先级
一个团队里会有成百上千个待处理的 bug,如果大家不分轻重缓急、按提交顺序一个一个修,项目根本没法按期交付。所以要给缺陷"定级",好让开发能按重要程度分配精力,怎么排、先修哪个,一目了然。
4.1 缺陷的四个级别
业界通常把缺陷按严重程度(severity,指缺陷对系统造成的影响有多大、破坏力多强)分成四档:崩溃、严重、一般、次要。
第一档:崩溃(也叫致命级)。 这类问题会阻碍开发或测试工作,造成系统崩溃、死机、死循环,导致数据库数据丢失、与数据库连接错误,主要功能丧失、基本模块缺失等问题。常见的如:代码错误、死循环、数据库发生死锁、重要的一级菜单功能不能使用等。这类问题在测试中较少出现,但一旦出现应立即中止当前版本的测试——因为连基本功能都跑不通,继续测下去意义不大。
第二档:严重。 系统主要功能部分丧失、数据库保存调用错误、用户数据丢失,一级功能菜单不能使用但不影响其他功能的测试;功能设计与需求严重不符,模块无法启动或调用,程序重启、自动退出,关联程序间调用冲突,以及安全问题、稳定性问题等。比如:软件中数据保存后数据库里显示错误、用户所要求的功能缺失、程序接口错误、数值计算统计错误等。这类问题在不影响其他功能测试的情况下,可以继续当前版本的测试。
第三档:一般。 功能没有完全实现但不影响使用,功能菜单存在缺陷但不会影响系统稳定性。比如:操作时间长、查询时间长、格式错误、边界条件错误、删除没有确认框、数据库表中字段过多等。这类问题在实际测试中存在最多。
第四档:次要。 界面、性能缺陷,建议类问题,不影响操作功能的执行,可以优化性能的方案等。比如:错别字、界面格式不规范、页面显示重叠、不该显示的组件要隐藏、描述不清楚、提示语丢失、文字排列不整齐、光标位置不正确、用户体验感受不好、可以优化性能的方案等。此类问题在测试初期较多、优先程度较低;在测试后期出现较少,一旦出现应及时处理。(因为临近发布还冒出一堆错别字,传递的是质量和态度信号。)
为了方便记忆,我把四档整理成了这样一张对照表:
| 级别 | 通俗说法 | 典型表现 | 对测试的影响 |
|---|---|---|---|
| 崩溃 | 直接跑不了 | 死机、死循环、数据丢失、核心功能丧失、一级菜单不可用 | 立即中止当前版本测试 |
| 严重 | 主要功能坏了大半 | 主要功能部分丧失、数据丢失、功能与需求严重不符、安全问题 | 不影响其他功能的测试时可继续 |
| 一般 | 功能有不完美但不碍事 | 操作/查询慢、格式错、边界条件错、缺删除确认框 | 测试中最多见,按正常节奏处理 |
| 次要 | 小问题、可优化 | 错别字、界面不整齐、提示语丢失、光标位置不对、体验优化 | 初期多、优先级低,后期出现要尽快处理 |
4.2 严重程度 ≠ 优先级:这一对概念必须分清
这里要特别强调一对极易混淆的概念——严重程度和优先级。
- 严重程度(Severity):指缺陷"本身"的破坏力。它是缺陷自带的客观属性,描述"这个问题有多严重",一般在提 bug 时由测试人员根据缺陷对系统的影响来标注。上面四档就是按严重程度划分的。
- 优先级(Priority):指缺陷"被处理的先后次序、紧迫程度"。它描述"这个问题该多快修",往往由开发再结合现有排期、人力、风险来最终确定。
一句话:严重程度看"多严重",优先级看"多急"。 二者通常正相关,但并不总是一致,现实中会出现不少"倒挂"的组合,这才是它们要分开记的原因。举两个典型例子:
- 高严重、低优先级:一个只在"极冷门、几乎没人用"的功能里出现的崩溃。它确实很严重(一触发就崩),但因为没有真实用户会用,修复紧迫性不高,可能排到很后面。比如某个只有内网管理员进入的、用来导报表的角落功能出了崩溃,普通用户根本碰不到,优先级就可以放低。
- 低严重、高优先级:一个"只是错别字、功能性上无影响"的缺陷,却撞在首页标题或提交按钮上的关键文案上。严重程度确实只是"次要",但因为它直接影响公司品牌形象、影响用户第一印象,往往要加班加点先改。比如注册页面写成"注策",虽然功能没坏,但运营会盯着让你马上改。
所以,提 bug 时标的是严重程度;开发的排期、是否当期版本修复,主要看优先级。 两者可能重合也可能分裂,理解了这一层,你后面既不会把"我认为很严重"当成"必须马上修"的强词夺理,也能在合理的场合坚持"这个看起来轻但应该优先处理"。
本节思考题
问:只影响极少数管理后台用户的一个功能崩溃(严重程度:崩溃),和一个出现在首页商品名上的错别字(严重程度:次要),你会怎么给优先级?
**答:**两者都可能出现"倒挂"。崩溃级的功能影响极少量管理后台用户,若该功能不阻塞主流程、也没有数据丢失,优先级可以定为"低"——先不修也不影响绝大多数用户;而首页商品名的错别字直接影响品牌和用户观感,虽然严重程度只是"次要",但优先级往往要提到"高",甚至要求发布前必修。这个例子正说明:严重程度是缺陷盖章,优先级是修复排期,两者必须分开评估。 你一上来就把"崩溃=马上修"划等号,遇到这种场景就会判断失误。
五、缺陷的生命周期:一张状态机图
一个 bug 从被发现,到被修复、验证、关闭,会像一件商品一样经历一系列"状态"的流转。这个流转过程,就叫缺陷的生命周期(Bug Life Cycle)。它本质上是一台状态机——每个状态都有固定的名字,状态之间只能按规定的边转移,不能乱跳。
**状态机(State Machine)**你可能第一次听这个词,不用紧张,它就是个"有规矩的状态流转规则":系统在任何时刻只能处于其中一个状态;只有当某个"事件/条件"满足时,才能从当前状态跳到另一个允许的状态。
5.1 生命周期里都有哪些状态
测试人员在执行测试的过程中,一旦发现 bug,就要在对应的缺陷管理平台(比如 Jira、Mantis、禅道等)里创建缺陷——这是缺陷生命的起源。创建之后,这个 bug 还要被开发修复,以及被测试持续跟踪和回归验证。整个生命周期里,核心状态有这么几个:
下方是缺陷生命周期中几个关键的状态定义(这也是面试的高频考点,值得逐条背熟):
- New(新发现):新发现的 Bug,尚未经过评审决定是否指派给开发人员进行修改。这是缺陷出生后的第一个状态。
- Open(打开/确认):经过确认它确实是 Bug,并且认为需要修改,将它指派给相应的开发人员。也就是"认领"了它。
- Fixed(已修复):开发人员修改完毕后把状态标记为已修复,此时有待测试人员进行回归测试验证(回归测试,即修改后的验证)。
- Rejected(拒绝/不采纳):如果开发人员认为这不是 Bug(或不属于该负责范围),则拒绝修改。
- Delay(延期):如果认为暂时不需要修改、或暂时不能修改,则延后修改,进入"延期中"。
- Closed(关闭):已修复状态的 Bug 经测试人员的回归测试验证通过,则关闭 Bug。
- Reopen(重新打开):如果经测试验证 Bug 仍然存在(说明修复无效或没修到位),则需要重新打开 Bug,并重新指派给开发人员再次修改。
5.2 状态是怎么流转的:标准路径与无效路径
把这些状态串起来,缺陷的"标准人生"大致是这样的:
New(新建)→ Open(确认指派开发)→ Fixed(开发修复)→ Closed(回归验证通过,关闭)
这是最理想、最标准的路径:提缺陷、认领、修好、验证通过,闭环完成。而现实中会有很多分叉:
- Rejected(拒绝):New 或 Open 后,开发审查认为"这根本不是 bug"或"不在我模块",会 Rejected,退回测试。测试如果同意,就接受;如果不同意、认为确实是 bug,需要走后面讲的"与开发争执"流程,甚至可以召开 bug 评审。
- Delay(延期):确认为 bug 也认可要修,但当期版本来不及或不划算,标记为 Delay,排到下个版本再处理。
- Reopen(重新打开):Fixed 之后,测试做回归验证发现问题依旧,就把状态从 Fixed 拉回 Open(或 Reopen),再次指派开发修复。这里最容易让人困惑的是"刚刚 Fixed 的 bug 又回到开发手里"——这正是回归测试的意义所在。
- 无效的缺陷路径:还有两条被单独归纳为"无效 bug"的路径——
Open → Closed和Open → Rejected → Closed。它们的意思是:有些缺陷,还没到开发动手修,评审就直接判定不予处理,最终以"关闭"收场。比如确认是历史遗留、是环境配置问题、或经评审决定不做,直接关掉即可,不需要走"修复"环节。
我可以在脑中想象一张流转图:New 向右到 Open,Open 向右到 Fixed,Fixed 到 Closed;从 Open 向下可以到 Rejected、Delay;从 Fixed 往下可以回到 Reopen,再回到 Open 重新入户。这张图里的弧就是"允许的转移",跳过去的路径才是合法的。
5.3 两个必须深挖的概念:回归测试与其背后的风险
在生命周期里,"Fixed → Closed"之间夹着回归验证,这里要单独展开一下。
**回归测试(Regression Testing)**是指:在软件被修改后,重新测试修改的部分及其相关联的功能,确认这次修改没有引入新的缺陷、也没有破坏原有功能。它的"回归"二字,指的是"防止问题回归/回退"——代码一改,曾经好用的地方可能就被改坏了,要去查有没有"退回去"。
这里有个测试人必须有的风险意识:修 bug 本身可能带来新问题。 开发改一行代码修好 A,可能连带把 B 弄坏。所以 Fixed 之后测试绝不能"看它报'已修复'就关了",而是要亲手把这条路径及相关联路径再跑一遍。而且——这一点非常关键——修改很可能不止带来回归测试的工作量,还可能带来新的风险。如果时间紧迫,修改后剩余时间不足以做一次有效回归,那么"修改"可能是比"不改"更危险的决定。这是后面 bug 评审里测试代表要反复权衡的点。先记住这个判断,后面第五节还会用到它。
本节思考题
问:一个缺陷的状态是 Fixed,测试人员去回归验证,发现问题依然存在。接下来状态应该怎么走?为什么不能直接把 Fixed 关闭?
**答:**应该把状态从 Fixed 转回 Reopen(重新打开),并重新指派给开发继续修改,直到回归验证通过才允许转 Closed。原因有两个:其一,Fixed 只是开发单方面宣称"我修好了",是否真正修好必须由测试独立验证才能下结论,不能盲目信任状态;其二,回归验证的失败,恰恰说明要么修复无效、要么修复方式引入或暴露了新问题,必须打回去重试。Fixed 不代表结束,验证通过才是结束的分水岭。 这也是"测试是质量守门员"这一角色的具体体现。
六、一份规范的 Bug 报告:把所有要素串成一份成品
前面分别讲了要素、级别、生命周期,这一节把它们合起来,给你一份"可以直接照着抄"的规范 Bug 报告,并配上几个进阶的注意事项。
6.1 一份完整的 Bug 报告范例
还是沿用那个二维码被登录模块遮挡的例子,一份规范的 Bug 报告整整齐齐长这样:
缺陷标题:登录页二维码被登录模块遮挡,无法扫码
所属模块:登录 / 注册
严重程度:一般(界面遮挡,但登录主流程仍可用)
优先级:建议本周内处理(影响用户扫码登录体验,属高频入口)
问题出现的版本:谷歌浏览器 123.0.6312.123(正式版本)(64 位)
问题出现的环境:Windows 家庭版
复现步骤:
- 打开谷歌浏览器,输入网址
https://www.101eduyun.com/; - 等待首页页面渲染完成。
复现频率:100% 必现
预期结果:二维码与登录模块不会出现遮挡,二维码可以正常扫描。
实际结果:二维码被登录模块遮挡,二维码扫描失败。
附件/证据:遮挡现象截图 1 张(含 URL 和浏览器版本,见附件);无控制台报错。
备注:该问题在最新发布版本 123.0.6312.123 上开始出现,上一版本正常,疑似与近期登录模块布局调整相关。
缺陷状态/指派人:New(待评审后指派)。
你对照五要素会发现,这份报告把版本、环境、步骤、预期、实际全部拆开单列,又额外补了标题、模块、级别、优先级、复现频率、证据和一条很有价值的备注("上一版本正常、疑似与某某改动相关")。最后这条备注尤其加分——它替开发缩小了排查范围,让整个报告的含金量上一个台阶。
6.2 这份报告里暗藏的进阶心法
从这份报告里,你可以提炼出几条长期受用的心法:
- 标题要"可筛选":开发每天对着长长的 bug 列表,标题是他第一眼判断"要不要当下点开"的依据。合格的标题 = "模块 + 位置 + 动作 + 现象",去掉所有废话。
- 级别和优先级分开标:你在"严重程度"填"一般",在"优先级"填"建议本周内处理"——这正用上了上一节讲的"倒挂":现象不严重(只是遮挡,还能点按钮登录),但影响高频入口的体验,所以建议优先。
- 证据优先于解释:有截图、有版本号、有 URL,比任何形容词都有力。
- 备注是点睛之笔:主动附加"什么时候开始出现的、可能和什么改动相关",能显著降低开发的定位成本,也侧面体现你测试时留了心、做了版本对比。
6.3 进阶坑位:偶现 bug、报错日志怎么处理
再补三个实践中一定会遇到、但总有人栽跟头的细节。
第一,偶现 bug 一定要写"复现频率和触发条件"。 老练的测试会在复现步骤后加一句"约 5 次出现 2 次;在快速连续点击时更容易触发"。偶现问题背后往往是竞态条件、内存问题这类最难的 bug,你给的频率和"什么情况下概率更高",就是开发抓偶现问题的救命稻草。
第二,日志要"截片段"而不是"整段扔"。 贴日志别把几千行全塞进 bug 里。用能方便检索的关键词(如异常类型、报错文案)在日志里过滤,截出出错时刻前后的相关几行,足够了。关键是要让开发能立刻定位到报错点。
第三,提 bug 之前先搜一遍"是不是重复缺陷"。 团队里几个测试员同时测一个模块,撞车极其常见。提报前在平台里检索相同模块、相同现象的关键词,如果已经有同学提过,就不要重复开单,而是在原 bug 下补充你的复现信息或截图。这样既避免后台被刷屏,也让原始 bug 的信息更完整、更有说服力。这个动作,就是对"重复 bug"的最好处理。
本节思考题
问:你测出一个偶现 bug,10 次里出现 3 次,且无固定操作规律。你会怎么写这份 bug 报告?
答:首先是认真记录复现概率(约 30%),并在复现步骤里补充你观察到的、可能提高触发概率的上下文(哪怕只是猜测也要如实标注"疑似与长时间停留页面后立即点击相关")。其次必须给出尽量多的证据——在出问题时立刻截屏/录屏、抓取控制台报错和网络请求。最后,因为偶现、难复现,语言上更要诚实,明确写"复现不稳定",请求开发协助或提供打日志的调试版本,而不是含糊其辞地声称"每次都这样"。偶现 bug 对测试人最大的考验,不是"写得漂亮",而是能否把有限的观测资料组织成对开发排查真正有用的信息——概率、触发条件、证据,三样缺一不可。
七、与开发产生争执怎么办:测试人的高阶修养
讲完"怎么把 bug 提好",一定躲不开下面这个很多人又爱又恨的话题——和开发因为 bug 起争执。
在测试工作中,最常遇到的就是和开发人员的 PK(这里的 PK 是"对决、较劲"的意思);等你做到测试经理,还会和项目经理、产品经理 PK 进度、PK 质量。遇到争执不要怕,要理性地分析和反馈问题。 关键是掌握一套待人接物的方法。教材把常见的场景和应对拆成了五条。
7.1 先检查自身,是不是缺陷描述不清楚
这是争执发生后的第一自省项。如果能正确、高质量地录入一个 Bug,那么基本上就已经成功地和开发沟通了一大半关于 Bug 的信息——可话又说回来,总有"书难达意"(文字表达不出来)的时候,这时就需要测试主动开口。
如果你发现写完之后,好像还有很多关于 Bug 的信息没表达出来、或者很难用书面语言表达出来,那就应该在提交 Bug 后,马上找相关的程序员当面解释刚才录入的 Bug,确保程序员理解了 Bug 描述的意思,而不是干等着开发回头找你问。主动去说,比被动等质询,姿态和效果都更好。
记住:先怀疑自己描述得清不清楚,再怀疑开发是不是不配合。 这一步很多时候就把问题消解于无形了。
7.2 站在用户角度考虑并抛出问题
如果描述没问题、开发仍然不接受,第二招是把视角拉到用户身上。让开发了解这个 Bug 对用户可能造成的困扰,往往才能促使开发更积极、更高质量地去修改。
争执到一个僵局时,你可以问开发一句非常有分量的话:"如果你是用户,你可以接受么?"
这一问非常聪明:它把纯技术层面的"这行代码对不对"之争,拉回到"用户会不会因此受伤"的共情层面。开发也是产品的用户,他一换位,常常就松口了——毕竟没人愿意承认"我做的功能,连我自己作为用户都不愿意用"。
7.3 BUG 定级要有理有据
争执的另一个高发点,是"这个 bug 算几级"。这时记得前面讲的内容:BUG 定级时,不仅参考 BUG 级别,还要考虑 BUG 是否会影响到流程;往往用户的 BUG 级别和我们的是有区别的,要站在用户的角度去考虑定级。
也就是说,定级不是拿张表照本宣科,而要结合业务影响。开发说"这只是界面小问题、别看太重",你可以摆出"它挡在登录入口、影响扫码登录"这样的用户角度事实,说明为什么虽然现象不严重、但对用户的影响不小。定级争论的胜负手,从来不是嗓门,而是你有没有一个站得住的用户视角依据。
7.4 提高自身技术和业务水平:不仅要提出问题,最好还能给出解决方案
这是拉开初级测试和资深测试差距的分水岭。提高自身业务和技术水平,不但要能提出问题,还要能提出解决问题的思路,这样才能更让人信服。
工作中你会发现,同一个 bug,资深测试工程师提出和初级测试工程师提出,两者的结果完全不同。两者最大的差别,正是资深测试工程师往往会提出解决方向、给出方案思路。长此以往,你在开发眼中的权威性就建立起来了——开发看到你提的 bug,第一反应是"这是个 bug",而不是"这是个 bug 吗?" 一旦形成这种信任,后面所有沟通都会顺畅得多。
但这里有个重要的度要拿捏:可以给出解决思路,但不能喧宾夺主、命令式地让开发按照你的想法来改。你的角色是帮助定位、提供线索、说明严重性,而不是指挥对方写代码。越界了,反而容易激起抵触。
7.5 友好沟通无效,就启动 bug 评审
如果前面招都用过了、确认确实是 bug、但友好沟通仍然解决不了,那就该把问题升级到缺陷评审(Bug Review / 缺陷评审会),让项目层面来裁决。
缺陷评审主要解决两个问题:1)决定如何处理这个 bug;2)分析缺陷产生的原因,找出预防的对策。 它不是一个随意的碰头会,而是需要至少各方向代表参加的正式评审。教材给出了三个关键角色:
- 测试代表:主要从 Bug 的具体表现、严重程度等方面提供信息,并提出自己对 Bug 的处理意见。这里教材特别提醒测试人:不应该一味地要求对 Bug 进行修改。因为修改本身可能带来回归的风险,也带来回归测试的工作量;如果时间紧迫,修改后剩余的时间不足以做一次有效的回归测试,那么"不修改"很可能是个更明智的选择。也就是说,测试代表要站在"整体质量"而不是"我要把这个 bug 销掉"的角度发言。
- 开发代表:主要从修改缺陷的难度和风险出发,考虑修改需要付出的代价、可能影响的范围、可能引发的风险;如果决定要修,还要一起讨论出修改的初步方案。
- 产品代表:主要从产品的整体计划、用户的要求等方面,对缺陷修改的必要性、修改的时间和归属版本发表意见。
这三方立场互补、缺一不可:测试懂现象、开发懂代价、产品懂对用户和排期的影响。评审会的目的不是"吵出谁对谁错",而是在一个合理的范围内,为这个 bug 找到"做不做、何时做、怎么做"的一致答案。
本节思考题
问:你确定一个 bug 确实存在,开发却坚持"这不是问题、不改"。你会怎么一步步处理?
**答:**按教材的次序推进:第一步,先自省——我的描述是否清晰?如果有说不清的细节,立刻当面和开发补充解释。第二步,若描述已清晰,转到用户视角,用"如果你是用户,你能接受么"让他换位思考。第三步,若还僵持,冷静核实定级是否站得住、是否有用户视角的依据能支撑这个 bug 的重要性。第四步,提升说服力——除了指出问题,能不能补充现象分析、甚至给个初步的排查方向,让开发看到你的专业度。第五步,如果以上都做了、确实是 bug、友好沟通仍无果,就把问题摆上缺陷评审会,由测试、开发、产品三方代表共同裁定如何处理,既不再为一个 bug 纠缠,也让结论有项目层面的权威背书。整个过程的精髓是从"对错之争"逐步升级到"项目裁决",而不是靠情绪去压人。
写到这里,我们把 BUG 这条主线走完了。回头看,这一篇其实讲了一套完整的"缺陷观":
先看清软件测试的生命周期,知道 BUG 是在"测试执行"这个舞台上大量登场的,但它会一路影响评估、上线和维护。然后给缺陷下了精准的定义,记牢那两把"尺子"——有规格量规格、没规格量用户的合理预期。接着掌握描述缺陷的五要素(版本、环境、步骤、预期、实际),再叠加上标题、模块、级别、复现频率和证据,把一份"开发能一眼看懂"的报告写出来,同时避开"步骤不清、证据缺失、重复提报"这些最常踩的坑。然后分清严重程度与优先级这对容易混淆的概念,明白"严重"不等于"紧急"。再走一遍缺陷的生命周期状态机——从 New、Open、Fixed,到 Rejected、Delay、Closed、Reopen——理解回归验证的意义,以及"修 bug 可能带来新风险"这一层。最后一手应对和开发的争执:先自省、再换位、定级有据、给出方案、必要时启动缺陷评审,一步步把情绪之争升级成项目裁决。
下一篇文章,我们会进入软件测试里最考验设计与逻辑的部分——如何设计测试用例、有哪些经典的用例设计方法,看看在"没测过、也要尽量测全"这件事上,测试人是如何下棋的。
今天的这些概念,你不必一次全背下来;真正上手提上几十个 bug、被开发打回来几次、再亲手走一遍 New→Open→Fixed→Closed 或 Reopen 的循环,这套"缺陷观"自然就会长在你身上了。
还没有评论 — 第一条由你来留。