雷辉:ThoughtWorks 高级质量保证工程师,多年研发与测试经验,丰富的大型商业软件的测试工作实战经验,精通自动化、性能和探索式测试,以在软件中发现各种隐藏 Bug 为乐。
我是 TW 一名测试人员,不敢说是老司机,还算资深吧,因缘际会入了 IT,做得测试这一行。其实按照大学的专业,我现在应该是一名杰出的销售大师,哈哈。然而,一入 IT 深似海,回头已是中年身。我有多年的 Java 开发经验,后来转为测试,对开发和测试都有了解,所以今天打算从测试角度出发,为开发人员照照灯下黑。
完成一个功能卡的简化流程是这样的:程序员开发→自测→QA 测试。通常开发一张卡的工作量为 1~3 天,少量卡需要 5 天左右。从过去的数据看,从开发接手的卡,90% 以上都有 Bug,没有 Bug 的卡比较少,要么是功能特简单,不易出错,要么是开发经验老道又细心。
又年轻、工作年限又短的工程师们通常漏测的点在哪里呢?
有时系统需要和第三方的系统进行集成,开发工程师对第三方系统不熟悉,自测过程中,有不少分支流程没有执行,恰巧就在这里隐藏着很多 Bug。当系统业务过于复杂,开发只熟悉某一部分,在这种情况下自测时,需要放在完整的业务流程中测试,真实地去使用,会碰到意想不到的事情发生。我们团队开发一个类似 Jenkins 的持续集成平台,最近给构建过程增加了多阶段(Stage)构建的功能,用户可以在每个 Stage 执行不同的任务。
开发自测时,通常都会覆盖主流程,如:
还有更多的流程分支需要测试:
示例 1 : 构建包的使用原则 。当一个 Stage 有过一次成功构建,即便该 Stage 下一次构建失败,它之后的 Stage 仍然可以使用上一个 Stage 最后一次构建成功的包。
示例 2 : 特殊流水线 。系统中有多个流水线,其中发布流水线与其他流水线实现不同,需要单独测试。
示例 3 : 被忽视的运行方式 。开发自测时常用手动或者自动模式进行构建,但系统还提供了定时运行方式,需要测试定时运行时多 Stage 是否构建正常。
示例 4 : 修改 Stage 后对构建的影响 。删除或修改某个 Stage 信息,是否会对构建产生错误的影响。此外需要查看在"历史页面"模块,是否正确显示对 Stage 修改的各个历史版本记录。
示例 5 : 与其他模块的关联 。只有一个 Stage 时,报表可以显示构建过程中单元测试结果。变成多个 Stage 后,如果每个 Stage 做了不同的单元测试,报表还能正确显示吗?
开发人员自测时候没有跑通所有的业务分支流程,主要原因在于企业开发都是团队协作,一个小组十多个人,每人日常工作中,做的功能卡比较散:今天给页面加滚动条,明天做 XML 的解析。对功能卡的上下游使用场景难以了解得十分清楚。
这是一个困难点,但换一个思路,将来出现了 Bug 谁来修?大多数情况还得自己去修复。到那时还是要去熟悉和了解上下游的使用场景,但修复的成本就会变大很多。
开发一个功能时,多花费时间去了解上下游使用的场景,看似多投入的时间,可以有效减少 Bug 的出现,此外,还可以让自己更了解整个产品的全景图,了解每张卡给用户产生的业务价值。因此,认真分析功能卡的上下游场景,对产品质量和个人成长都很有好处。
一个小例子:开发一个系统对外提供的 Web Service 服务,当我们把这个接口的使用场景都分析到,才能做到 Bug 更少。
需要测试的场景包括:
做每种软件的测试,都需要仔细分析其使用场景。
示例 1 :开发只在 Chrome 浏览器上进行了自测,而用户使用的是除此之外的其他浏览器。浏览器兼容性的问题非常多。
示例 2 :用户使用手机软件时,常因坐姿不同而旋转屏幕。自测时就需要关注屏幕旋转对界面布局的影响。
示例 3 :自测时只在界面上建了 3~5 个组件,而用户可能会新建 N 个。在实际使用中发现,新建组件一旦超过 30 个页面,反应就会明显变慢,存在性能问题。
示例 4 :一个 Web Service 服务要被用在公网上,却只在 HTTP 下进行自测,没有在使用 HTTPS 加密的场景中进行测试 。
……
大部分的 Bug 出现在边界值附近。需要理解业务逻辑,理解输入数据的含义,来确定边界值在哪里。
例如,一个医保本允许登记 0~10 家医院,那 0 个、1、 9、10、11 这些数字都是这个功能的边界值,此外还要随机挑选 1~10 中的任一数字进行测试。
测试完上面的场景,还要注意的就是:
除此之外,那些特殊字符:引号、星号、问号是否都被正确处理了呢?别小看这些引号、星号等的处理,如果没处理好,可能会抛出 HTTP 500 ERROR 异常,还可能会暴露后台代码异常堆栈,给黑客提供可循的机会。
对一个英文系统来说,它的文本处理边界也许是所有的英文字符,这时候可以输入中文和德文字符,看会不会造成系统问题。
功能开发过程中,可能会破坏以前的功能。最好快速的对页面的其他功能做回归测试,不能只关心当前完成的部分。
软件界面上经常看到按钮布局没有对齐、位置差几个像素,或者是页面上的树形结构展开时,垂直虚线中间有中断的现象;或者是字体和系统其他模块使用的字体有差异等。这些可以归到一个字上—— 慌 。开发通常会得到 UI 设计稿,而 UI 设计稿中对字体、高度等都有细到像素级别的描述。页面元素较多,可能是导致开发变慌的原因。
从使用上来说,把自己当做用户,就能轻而易举地发现这些不细心之处。 如果是金融和银行软件,出现此类细微错误,作为用户怕是不敢把钱放进去的。重视细节才能凸显专业。
经过对同类产品的详细对比分析,我们能快速发现自己开发的软件有哪些不足,以及有哪些可以提升的地方。
我不喜欢写测试用例,工作中也很少写测试用例。除非是某个功能业务比较复杂,需要用文字帮助梳理和记忆思路的时候,才写一点点测试用例。
测试用例的主要问题在于,用文字描述各种逻辑分支、界面,使用的文字量大,还容易变身老版本,需要维护。好一点的方式是用 BDD(我用的是 Cucumber+Selenium+Java)去描述测试用例,然后用后台的自动化代码去把测试用例自动化起来,这样就不容易变成老版本了。
探索性测试第一步,先选择最简单的 Happy Path,看系统反馈的直观感受。这个过程中,我注意到界面上的下拉选择框不是通用的 HTML 控件,如果是自定义的,这时就要担心自定义控件的 JavaScript 代码是否都能正常工作。
第二步,用这个下拉框选择一个最简单的选项,看选择过程是否流畅(如果不流畅,先记上一笔,可能是 JavaScript 代码中存在性能问题,待功能测试完成后,再回头看这里的性能)。此外,检查选中后移除选择项的删除等按钮是否正常。最基本的功能测试完了,再选择多个选项,用特殊的数据测试。
如果这个控件所在的页面,有其他 HTML 控件,当从别的页面跳转到这个页面时,有的控件的值没有预填写,就要测测这个自定义的控件,在同样流程中,能否把值预填写成功。
最后,界面上这个控件宽度被固定,就要考虑如果选择项值是一个 150 个字符的合法数据,会怎么显示。页面布局是否会被破坏?
就这样,一步一走,通过系统的反馈,点燃新的测试思路,并一步步执行测试。
在探索性测试过程中,最重要的是:测试人员要有能力根据系统给出的反馈,想出更多的测试路径去验证,或者有选择地去重点测试某一个部分。
这种能力是建立在大量的 IT 认知上的,IT 知识越丰富,被系统激发出的思路就越多。这就好比,让一个不了解玉石的人去检验一块玉石的真伪一样,只有具备丰富的玉石知识后,才能练就一双火眼金睛来。
当我们足够了解一个东西时,我们才更清楚它的薄弱环节在哪儿。做过很多开发工作,有很多开发经验的人,拿到一个软件,差不多就知道这个软件的实现过程,以及该软件可能出现问题的位置。
示例 1 :一个测试 Web 服务返回 HTTP Code 的功能卡,因为返回值计算过程简单,出错概率不大。但由于返回有十多种值,需要写很多分支,这种情况程序员往往会漏测一两个分支。
示例 2 :知道 JSON 数据的格式,就应联想到把大括号、中括号等作为数据的一部分进行测试。
示例 3 :有缓存机制,在性能测试时不用同一个关键字进行压力测试,而要改变关键字。
示例 4 : 如果单元测试用了 Mock 机制,要清楚 Mock 往往在系统交接处漏测 Bug,需要另外进行端到端的完整流程测试才行。这就要求我们熟知 Mock 的使用原理。
示例 5 : 自定义的 HTML 组件,需要写大量的 JavaScript 代码,这里容易出错,需要着重测试,而通用的 HMTL 组件的测试就不用花费过多精力。
示例 6 : 了解测试环境的差异,比如后台部署多台服务器会带来 Session 复制分发的问题,这就需要在多台服务器的测试环境中,测试 Session 复制分发是否正常。
示例 :测试发送邮件时,需要验证多种邮件客户端接收后的界面排版是否正常。有这样的工具可以帮助我们只发一封邮件,它给你显示出各种邮件客户端的排版。但是也不能全信它们,使用前最好自己做抽样检查,看看这个工具是否真如它所说的那样好用。
① 在程序员开发一张卡时,首先大家会坐在一起,包括 QA、BA、DEV、UI 等,讨论这张卡的接收条件,避免一开始写代码就走偏的情况。
② 开发完成后,会在本机给 QA 演示功能,QA 给出反馈,减少 Bug 出现在部署环境后才被发现的可能。
③ 小组的 Code Review 可以帮助 QA 减少测试工作,Code Review 能及早发现代码的潜在问题。
关注单元测试覆盖率。单元测试覆盖率不高,QA 的工作会越做越累,每次新加的代码都可能破坏之前的功能。
此外,还需要关注 UI 自动化的运行情况,它可以弥补单元测试没有覆盖到的地方。
自动化的方式包括:
以上是我的一些拙见,以作引玉之砖,欢迎大家补充和探讨:bug_big_bang_in_web_testing@outlook.com。
本以为日子就在找地鼠和打地鼠的日子中流逝,直到有一天,黄勇问我,要不要一起写书,写关于测试的书。于是有了这本《测试囧事》,也希望本书为大家的开发和测试之路点亮了一排路灯。