Web测试囧事(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-13 21:40:57

点击下载

作者:黄勇

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Web测试囧事

Web测试囧事试读:

前言

为什么要写这本书

1)人不能像走兽那样活着,应该追求知识和美德。——但丁

2)助人为乐,人生一美德。

我们4个作者加起来年龄过百,而且有着年超半百的工作经验,算起来也是测试领域的老鸟了。

根据上面的1)和2),我们得出一个很重要的结论:

经过这么多年在工作中不断总结经验,时不时与Bug斗智斗勇,最后提炼出来的经验,我们希望能分享给更多的人,更重要的是能抛砖引玉,引发对更优秀的工作方式和实践的思考。为什么需要看这本书

怎样判断你是否需要这本书?以下场景,如果8条以内你都似曾相识,那么请看这本书吧!

1)测试过程中,某个功能的测试除了依据需求文档编写测试用例,好像找不到别的测试点了。

2)按需求文档编写的测试用例,执行过后测试都通过了,但自己还是没有信心,总觉得还有没测到的地方。就像都出门了,还在怀疑自己究竟是否锁门了。

3)产品上线了,Bug出来了。为什么老是遗漏?

4)当前测试的功能怎么和之前项目的很相似,当时还发现了一个很有意思、很难发现的问题,可现在居然想不起来了。接着,又重新慢慢摸索。要是有记录可以翻查多好!

5)发现一个Bug,提交请求修复时,却被要求提供更多信息。更多信息?怎么提供,不知道,找不着,没头绪。

6)团队其他测试人员遇到技术问题,我却只能抓耳挠腮,无法提供更多帮助,怎么办?

7)分析测试进度和风险时,文档是写了,内容却无关痛痒。问题的实质在哪里?貌似离我有点远。

8)开发过程中,不知道自己编写的代码质量怎样,哪些Bug会变身为“大笑话”。

你符合哪一条或者哪几条?这本书到底写了些什么

归根结底:总结工作中发现、解决Bug的经验,并通过一个个活生生的故事描述出来,能让你开拓思维、唤起记忆、深入知识、学以致用,把这些经验积累的精华举一反三地运用到自己的项目中。本书特色

以大型购物网站Web测试为背景场景,以初入测试领域的小蔡为主人公,以功能测试、性能测试、安全性测试、自动化测试、移动Web测试、非功能性测试以及其他类型的测试为主线,向大家展示不同测试场景下,如何发现、分析并解决问题。

本书通过对故事的分析,引出缺陷出现的规律和模式,并通过对缺陷模式的总结和抽象化,提示大家在以后的测试中如何更高效地捕捉类似缺陷。

本书并没有详细描述如何通过对Bug的分析发现开发人员的开发模式,以避免缺陷。所以,如何预防开发人员编写存在缺陷的代码,帮助他们了解自己的弱点,使之有针对性地提高,就需要读者们从这一个个小故事中“悟”。读者对象

·测试工程师

·测试经理

·业务分析师

·产品经理

·系统架构师

·其他对测试技术感兴趣的人员如何阅读本书

本书着重讲解Web测试中可能遇到的各种问题以及思考和解决思路,包括以下10章内容。

第1~4章 这4章重点介绍了Web测试中最为关键的功能测试,并从开发和测试技术、测试覆盖率、测试实践及业务需求4个方面分析了功能测试中Bug产生的原因及其解决思路。

第5、6章 详细介绍在Web测试中安全和性能测试要怎么做,作为一个非专业安全/性能测试的人员,从思维和实践上如何进行安全和性能测试。

第7章 详细介绍在进行Web自动化测试过程中你可能遇到的各种“坑”,以及如何应对和预防。

第8章 详细介绍了在移动应用迅猛发展的浪潮下,针对移动Web测试我们需要进行什么样的调整。

第9章 介绍了非功能性的其他测试,例如可用性测试及本地化和全球化测试是如何运用在项目中,保证产品质量的。

第10章 通过介绍在需求澄清、测试环境管理和运维中的测试实践,阐述如何通过这几方面的测试活动提升产品质量。

附录A介绍了可以移植到更多项目中的Web测试优秀实践,附录B为广大测试人员展现了可以大展宏图的职业路径。

希望读者在开始阅读本书之前,已具备基础的测试理论知识。在阅读中,希望读者能在阅读完每一个故事后,留给自己一点时间重新审视故事的内容,想一想故事中的场景与自己工作中的相似之处,触类旁通地解决类似的问题或者运用相应的实践进行质量提升。勘误和支持

由于笔者的水平有限,编写时间仓促,书中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果你有更多的宝贵意见,欢迎通过邮箱bug_big_bang_in_web_testing@outlook.com联系我们,期待能够得到你的真挚反馈,在技术之路上互勉共进。致谢

我们要特别感谢师洁以及ThoughtWorks中国区的QA们,也要感谢机械工业出版社华章公司的策划编辑高婧雅在写作上的支持与鼓励。

谨以此书献给我们最亲爱的家人,没有你们的鼓励和支持,我们就不会这么全身心地投入到本书的创作。

最后感谢购买和阅读本书、热爱测试技术的朋友们!黄勇 雷辉 徐潇 杨雪敏第1章功能测试:技术篇

提到测试,大家首先会想到的就是功能性的测试,因为只有保证了产品的基本功能和流程,产品才具备给用户提供使用价值的能力,从而才有可能确定产品的核心竞争力。基于这一点,不仅测试人员和开发人员,还有产品经理、项目经理、业务方对功能完备性和正确性的重视程度也往往都是最高的。这也使得功能测试成为任何测试类型的基础。

在进行功能测试时,我们会使用诸如边界值分析、等价类划分、因果分析、组合测试(Pairwise Testing)等测试方法来设计和规划测试用例,但是这些方法大多都是从书本上学来或者从别的渠道了解到的理论方法。而实际上在一个真实的项目中如何运用,或者如何在特定的场景和情境下使用这些方法,去充分发挥这些测试方法的作用,并帮助我们高效地设计和执行测试用例却是更重要的问题。

正因如此,我们在功能测试部分并没有介绍这些方法是什么,而重点在于展示在一个具体的场景下,读者应该如何思考,怎么把理论知识和实际工作结合起来,以发现和避免可能遇到的陷阱。

功能测试部分的故事篇幅都会比较长,希望读者能够每读完一个故事,都留出一段时间进行思索和回味,从而理解故事的核心,触类旁通。

为了让每一章的故事更凝练,我们把功能测试部分分成了4章,分别是:技术篇、测试覆盖篇、测试实践篇和业务需求篇。这4章从Web开发流行的各种技术(例如响应式设计、特性开关、虚拟化等)、测试技术(例如实例化需求、集成测试、契约测试等)、测试实践(例如探索性测试、回顾会议、缺陷大扫除等)和业务需求(例如用户的并发操作、关联操作以及产品功能的一致性等)方面向读者全方位展示功能测试范畴中的常见问题和解决办法,更重要的是指引大家从一步一步的分析中得到解决问题的思路。

本章(技术篇)介绍了在开发和测试的技术方面引起的11个功能测试问题,现在大家和我们一起来看看这些丰富多彩的故事。1.1输入框中输入超过最大允许值造成页面跳转溢出

作为计算机系毕业生的小蔡,一直觉得学校里学的理论知识和现在的测试工作差距太大,在实际的工作中也没有什么作用,直到有一天她碰到这么一个有趣的问题。

小蔡负责测试的是一个Web产品,基于不同的搜索条件会显示大量的结果。由于搜索结果太多,所以页面有分页功能,为了方便用户快捷跳转到特定的页面,开发人员特意设计了一个页面快速跳转的功能(见图1-1)。图1-1 搜索结果页面快速跳转

在设计测试用例的时候小蔡就留心了,因为很多测试理论的书籍都描述过,对于输入框可以进行的验证点很多,比如:特殊字符、超长字符、负值、0值和null值,以及很大的数值等。小蔡发现,对于大部分的测试用例,开发人员都处理得很好,没有发现缺陷,她也就松了口气。

但是,当她测试到输入大数值的测试用例时,由于不确定多大的数值会出错,也不能拿到代码,小蔡就探索性地选了一个数值:9999999999(10个“9”)。当输入10个“9”点击“确定”按钮时,突然页面崩溃了!她仔细回想刚才的测试过程:100以内的小数值,以及输入小于等于搜索结果页面数的数值等情况,测试结果都很正常。那到底数值大到什么程度的时候页面会崩溃呢?一时想不到更好的办法,小蔡只好硬着头皮尝试着定位出错的数值范围。

她发现,当输入10个“9”就会出错,而输入9个“9”,页面正常跳转到最后一页。突然,小蔡想起来数据结构课程不是学过很多查找法嘛!这样,二分法就这么出现在了眼前,对,二分查找法(见图1-2)!5000000000(9个“0”),出错;2500000000(8个“0”),正常。她还是没有线索,可是她坚持这么一点一点查找。最后花了将近3个小时,小蔡终于定位到了出错的数值:4294967295。这个时候,小蔡很纳闷,怎么是这么一个奇怪的数值呢?有零有整的。计算机专业的背景给了小蔡一个提示,不会是2的多少次幂吧?果真,324294967295是2-1。当小蔡收集到这些线索之后和开发人员一沟通,32才发现由于开发人员设想页面最大不会超过2,所以对这个字段可以输入的最大数值的类型,选择的是int32。但是,开发人员并没有对超过这个范围的数值进行任何的处理,这就造成了程序判断中请求更大数值页面时的溢出,从而导致了产品页面的崩溃。图1-2 二分查找的原理提示 二分查找算法(binary search)或者折半查找算法,是一种在有序数组中查找某一特定元素的搜索算法。

搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

发现了这个隐藏的缺陷,小蔡很有成就感,但又觉得如果能早点知道代码的逻辑,可能自己就不会花这么长的时间了。同时,小蔡一直觉得计算机的理论知识不会应用到测试实践中,可没想到这次多亏32了学校中学到的这些基础知识,不只是int32,2,甚至还有二分查找算法也给了自己解决问题的灵感。没有这些知识,定位问题就更困难了。核心知识 边界值分析法

边界值分析法是一种常见的黑盒测试方法。

测试界的前辈们通过分析常见Bug,发现绝大多数的Bug都出现在输入/输出范围的边界处。因此,如果能够针对这些边界来设计用例,通常能够更加有效。

边界值测试法通常是作为等价类测试法的补充,和等价类测试法结合起来用。即每个等价类的边界部分就可以作为边界值的测试用例之一。

举个例子。假设有一个日期选择器(date picker)的需求,要求我们能够输入时间后,点击搜索查询输入日期前后一年范围内的数据。假设我们把输入的时间分为如下几个等价类:

1)正常时间范围内:now–1年

2)正常时间范围外:test datanow+1年

3)特殊时间:例如now=2月29,1970/01/01等

4)输入非时间的input value:比如输入值为@等

……

结合分类1、2,这个时候边界值的取值则可以取:

·test data=now-1年;

·test data=now+1年;

·test data=now-1年-1天;

·test data=now-1年+1天

……

考虑到输出范围是一整年的数据,结合特殊时间和时间的边界(跨年、跨月等),还可以增加

·test data=2月29

·test data=12月31号

·test data=1月1号

……

总之,边界值的取值,应该着重考虑边界情况。如果测试对象是时间,则应该重点考虑跨年、跨月等;如果测试对象是纯数字,则应该重点考虑数字的类型与取值范围;如果测试对象是数据表,则应该重点考虑数据表设计的字段长度,等等。拓展知识 测试用例设计

测试用例记录了测试的过程,我们可以通过测试用例了解哪些场景已经被验证了,哪些场景还没有被验证。除此之外,在传统的测试行业中,测试用例数量通常也被作为度量测试工作量和指定测试工作计划的重要输入。

测试用例通常会包含几个基本要素:用例编号、输入数据、期望结果以及前置条件等。测试覆盖率则是评价测试用例好坏的关键标准。覆盖率高的测试用例能够提高开发、产品以及其他验收人员对产品的信心。在设计过程中,我们通常会通过边界值、等价类等测试方法,结合配对组合测试(pairwise testing),基本路径分析法等测试策略优化测试用例,以达到提升测试覆盖率和减少冗余测试用例的方法。

以下是测试用例设计原则。

1)测试用例的代表性:能够代表并覆盖各种合理的和不合理的、合法的和非法的、边界的和越界的以及极限的输入数据、操作和环境设置等。

2)测试结果的可判定性:即测试执行结果的正确性是可判定的,每一个测试用例都应有相应的期望结果。

3)测试结果的可再现性:即对同样的测试用例,系统的执行结果应当是相同的。1.2索引值计算错误使资源缩略图显示和大图展现不一致

业务方希望在商品展示的页面,不仅能添加展示图片,还可以展示关于商品的视频(见图1-3)。图1-3 商品展示页面支持展示图片和视频

业务方希望通过图1-3下方的统一翻页操作,实现无缝浏览图片和视频。如果商品既有图片又有视频,当用户在浏览图片时,在图1-3右下角显示“Video”(视频),这时用户可以通过点击“Video”链接打开第一个视频;同样当用户在浏览视频时,在图1-3右下角显示“Image”(图片),这时用户可以通过点击“Image”链接打开第一张图片。

小蔡按照通常的步骤编写完测试用例,开始使用标准测试数据执行测试。小蔡首先发现点击右下角链接时,本应该显示第1张图片或者视频,但是打开的却是第2张图片或者视频。

小蔡觉得这可能是开发人员在处理图片和视频展示的数组时,使用的是自然数计数,从1开始作为第1个数据项,而非计算机程序数组中通常使用的把从0开始计数作为第一个数据项。当小蔡把这一问题上报之后,开发人员发现确实是这个原因,并进行了快速修正。

小蔡在开发人员新发布的包上又一次进行了测试,这次测试用例基本没有什么问题,她就开始在类真实环境中执行探索性测试,结果发现在某些商品页面进行图片和视频跳转时,出现图片或视频显示错误或者显示成空白的问题。

在老牛的协助下,小蔡发现了问题出现的两个规律:①当从第n张图片切换到视频的时候,系统显示的并不是用户期待的第1个视频,而是第n个视频;②当商品的图片和视频数量不一致,从数量多的资源切换到另一个数量少的资源时,内容就会出现空白。

小蔡和老牛都觉得出现问题的原因比较明确了,是因为在图片和视频跳转时,打开资源的索引值并没有清零,而是保存着前一个元素的索引值。

为什么这个问题在测试环境中没有发现,而在类真实环境中才被发现?原来最初小蔡在测试环境中执行测试用例的时候,使用的是基本测试数据,图片和视频都只有两个,而且两张图片和两个视频的内容分别都是一样的,因此不会出现这个问题。

小蔡和老牛商量了下,决定为了避免遗漏这样的问题,需要丰富测试环境的测试数据,使得测试数据更像真实数据,这样测试结果才更为准确。

同时他们认为这个问题在开发人员的开发过程中也是不应该引入的,因为这样的错误比较初级。于是小蔡和开发人员进行了沟通,发现引入该问题的根源在于开发人员的疏忽。由于图片的文件格式和视频的文件格式不同,所以开发人员使用了两个库来支持图片和视频的打开,但是两个库之间的跳转需要通过在两个库之间传递参数来实现,然而开发人员并没有仔细检查两个库之间所传递的参数,导致并不需要被传递的索引值也传递到另一个库中。

老牛带着小蔡和开发人员立下一个约定:在使用第三方库实现功能时,一定要把使用的函数方法中的所有参数都核对清楚。核心知识① 探索性测试

探索性测试(Exploratory Testing)是软件测试方法的一种。这种方法强调测试者的主观能动性,以及测试设计和测试执行的同时性。目的是探索开发更多不同形态的测试方法,以便改善测试流程。“先设计,再测试”的传统做法,通常是先分析出测试点,然后针对测点设计好测试方法,最后执行测试。这种模式也带来了一些问题,比如在测试目标不确定的情况下(改需求、输出范围过大等)经常可能出现测试遗漏等,而且在一定程度上也限制了测试思维的发散。而探索性测试的出现,正好弥补了传统测试中出现的这种问题。

探索式软件测试一共分为自由式探索式测试、基于场景的探索式测试、基于策略的探索式测试和基于反馈的探索式测试。(1)自由式探索

纯粹从使用的角度出发,抛开规则、模式,测试人员可以以任意顺序和方式对软件进行使用测试。这种测试通常会被选作快速冒烟测试用例。(2)基于场景的探索式测试

这种测试跟传统基于场景的测试比较像,不同的是,在这种测试中测试人员会扩大测试范围。例如,对某搜索框的测试,传统的场景测试用例可能是:

1)输入“电视”,期望结果是搜索到电视;

2)输入“123”,搜索到123相关的内容。

而基于场景的探索性测试下,测试场景则可能是:

1)输入“电视”,探索搜索结果;

2)粘贴“1@3”,搜索结果;

3)输入一个乱码,搜索结果;

4)输入电视,搜索结果后回退到搜索首页再搜索;

……(3)基于策略的探索性测试

这是一种比较依靠经验的测试方式。简单讲就是测试老手,融合自己的经验、技能、感知等条件,结合自由式探索性测试,用自己积累下来的知识来指导测试。是一种经验结合随机性的测试。(4)基于反馈的探索性测试

反馈指的是当测试人员对被测程序做出指令后得到的响应结果。基于这个结果,测试人员可以调整自己的输入,以期望得到不同的结果。例如,在基于场景的探索性测试的描述中,输入电视和输入电冰箱会得到不同的结果,而其中电视的搜索结果就是对电视这个输入的反馈,电冰箱的结果就是对电冰箱这个输入的反馈。核心知识② 软件开发中的各种环境

1)开发环境:就是每个开发人员进行编程的电脑,包括软硬件及其配置,为了开发调试方便,一般打开全部错误报告。

2)测试环境:测试人员进行产品部署,并进行功能等测试的环境。

3)预生产环境(非必须):与生产环境不定期同步,保持和生产环境的设置、数据的一致性,也是用于测试的环境。与测试环境的最大区别就是它和生产系统同步性最高,有些比如数据迁移测试,用这个环境测试比测试环境(一般情况下数据较少)更准确。

4)生产环境:正式使用的系统环境,一般会关掉错误报告,打开错误日志。

通常情况下,一个环境对应一个服务器,不同环境代表着系统开发的不同阶段:开发→测试→部署→上线。1.3测试Web Service能否正常提供JSON数据

某一天,小蔡所在的项目组刚开发完成一个Web Service,服务的功能是,通过在客户端调用时指定的一个ID,可以从后台数据库中读取对应的房产信息,还有与这个房产关联的一到多个房东信息、一到多个图片信息,以及地址信息等。Web Service最终把这些信息组合成JSON格式的数据返回给调用方,调用方可以通过界面来展示相关信息,也可以通过其他方式去使用这些信息。但是,调用方具体如何使用这些信息与Web Service服务本身的测试关系不大,所以暂且不表了。小蔡需要做的是验证这个Web Service服务能否正常地提供JSON数据。1.寻找测试关键点

和开发人员讨论后,小蔡了解到,给Web Service服务发送ID后,后台系统会根据这个ID去查询数据库,数据库对应的对象模型如图1-4所示。

在这个对象关系图里可以看到,Building对象是图的核心,其他对象分别和Building对象是一对一或者一对多的关系。那么小蔡觉得,测试的关键点就是这些数据之间的关系能否正确反映在生成的JSON数据里。(特别是要确保生成的JSON数据的格式没有被破坏,否则解析器就无法解析JSON数据了。)2.爬楼梯开始了

在确定好测试点之后,小蔡测试思路如下。

1)依据边界值进行测试。由于数据库的数据存在多种情况:0条记录、单条记录、多条记录,需要验证根据这些数据条数生成的JSON文件是否正确。图1-4 生成JSON的对象模型

2)需要关注对象之间的关联关系限制。例如一个Building对应0到4个Callout,那么需要测试当多于4个Callout时,生成的JSON的情况。

3)Web Service允许用户输入参数,所以需要验证输入特殊数据后,系统是否出现异常或者崩溃的现象,以及是否会出现SQL注入的问题。

4)Web Service有可能会被多个客户端并发调用,因此需要验证其性能是否符合设计要求。

根据测试思路,小蔡设计了如下测试用例。

1)Building对象可以有多个Space,所以可以选取0个、1个、6个Space去看生成的JSON是否正确,这个可以通过修改数据库数据的方式生成假数据去完成相关测试。另外,如图1-4所示,小蔡还需要测试Building和其他对象的关系,包括Customer、MediaLink等。小蔡还特别注意了边界值测试,比如,一个Building对应0~4个Callout,那么可以用0、1、4、5个Callout去测试。当有5个Callout的时候,要去查看返回的JSON数据是返回了前4个Callout,还是返回了前5个,又或者抛出了异常,当然,具体哪种结果是程序设计所期望的,需要和开发人员去沟通。

2)调用Web Service时需要指定ID,所以可以测试在ID存在和不存在两种情况下JSON结果是否返回正常。

3)异常处理,调用Web Service时可以把ID换成错误的参数,例如null、非常长的字符串、空字符串、英文字符、其他文字(例如中文字符)等。接着小蔡就去验证服务对异常是否做出了正确的处理。

4)安全测试,这个Web Service会被外网使用,那就需要在安全性上投入更多的测试。例如,如果URL可以输入任何参数,这些参数是否包含危险数据导致SQL注入这类安全问题。还有,因为Web Service被外网使用,那在调用这个服务时是否需要提供用户名和密码。

JSON使用了一种特殊描述数据的方式,用“,”、“[”、“]”、“{”、“}”等分割数据,小蔡需要测试,如果数据库存储的数据恰好有这些符号,这些数据被读取并生成为JSON后是否会破坏JSON的格式。

5)性能测试,如何对Web Service进行性能测试呢,快速测试方式就是通过一些工具的多线程调用,或者手工编写简单多线程代码去调用,然后查看持续调用两小时之后服务是否正常,服务后台内存曲线是否出现异常,有没有出现内存泄露等问题。另外,查看Web Service是否能在符合性能期望的时间内返回数据。

还有一个边缘的性能测试路径是:一个对象有成千上万个关联子对象,能否正常生成对应的JSON文件,以及性能是否能达到期望目标。庆幸小蔡这次测试任务不需要这么做,因为后台数据明确了不可能存在这种情况,但是在别的测试任务中可能需要测试。提示 假设一种大数据量的场景,如果关联的对象有10万个,我们可以通过工具在数据库中生成10万条数据。这时候,生成的JSON文件可能会有几十兆,那么我们要看需求文档,对这种场景期待的性能指标是多少,例如单个用户调用的话5分钟之内需要生成完毕,20个用户并发情况下10分钟生成完毕。我们需要验证是否5分钟或者10分钟内能生成完毕,同时还要验证,在这个过程中,后台内存增长曲线是否出现过于陡峭的现象。

6)查看生成的JSON数据中,一些特殊类型的数据是否和数据库完全一致。例如,对于float类型,有个Bug是该类型数据精度在数据库中是保存到小数点后8位,但生成的JSON中只保留小数点后2位;类似的特殊数据还包括非常长的字符串,需要查看是否被截断;如果在数据库中保存的是0,在JSON中是否会生成0.00,此外还可以查看空字符串是否正确生成在JSON中。

7)确定服务是否需要支持HTTPS加密,如果需要,就要去测试返回结果是否正常。

哈哈!终于爬完楼梯了,小蔡可以松口气了,走!喝杯啤酒,再来块炸鸡么?1.4利用JavaScript加载的漏洞提前购买抢购商品

自从小米手机推出以来,抢购风潮在各类网站上盛行起来,小蔡测试的网站自然也不能免俗,项目组开发的网站也包含了抢购功能。

对于抢购来说,只有到了特定的时间后,商品才会开放并允许抢购,并且抢购网页的代码里使用的时间会定期和服务器进行同步。

小蔡设计了丰富和全面的测试用例,在执行基础测试用例过程中没有发现抢购功能的Bug,不过在进行多地区和多语言的性能测试时,她发现了一个功能上的漏洞,发现漏洞的过程是这样的。

在执行性能测试时,需要选取不同国家和地区的服务器去模拟用户的真实访问,以验证产品性能是否能满足用户体验的要求。显然,通过这些不同国家和地区的服务器访问网站,会比小蔡在公司内部使用内网访问速度慢,更别提有些国家和地区网络发展慢,这些区域的访问速度就更慢了。

然而正是通过使用这些网速很慢的服务器,小蔡发现了这个功能上的漏洞。

1)在高速或者说正常网速的情况下,当用户打开抢购商品的页面时,页面JavaScript会很快加载并执行完成,这时“加入购物车”的按钮会变灰,无法进行操作(见图1-5)。图1-5 正常网速,等JavaScript加载完成之后“加入购物车”不能操作

2)而当网速很慢时,由于网页中JavaScript是顺序加载执行的,所以“加入购物车”按钮先会显示为可以操作的状态,等JavaScript加载完成后,才会变灰,不可操作(见图1-6)。图1-6 慢速网络,在JavaScript加载完成之前“加入购物车”按钮可以操作

3)所以在慢速网络中,当页面JavaScript没有加载完成时,用户会看到“加入购物车”按钮是可用状态,因此用户可以点击该按钮,并把抢购商品加入购物车,于是用户就可以在正式抢购开始之前顺利地抢到该商品了。实际上甚至在商品无货的情况下,用户也可以在JavaScript没有加载完时点击“加入购物车”按钮,并且成功把无货商品加入购物车(见图1-7和图1-8)。图1-7 慢速网络,无货的商品也可以添加到购物车图1-8 慢速网络,无货的商品也可以支付购买

这个问题是由JavaScript没有加载完成引起的,但是稍懂技术的人甚至可以禁用浏览器的JavaScript,或者通过查看网络访问的URL后,在按钮是灰色的状态下也有可能提交购买请求。所以,修改这个Bug时,还需要在提交订单时做二次验证,去验证该商品是否有货,或者是否已经处于抢购状态,当状态为“是”的时候,才允许后续操作。

当小蔡把这个问题提交给开发人员和产品经理后,经过大家的讨论,发现如果调整商品页面上的JavaScript加载顺序,会涉及很多JavaScript文件的修改,影响范围会很广,包括移动页面上的代码也需要大幅修正,因此整体工作量比较大。鉴于刚才提到的在提交订单时做二次验证也能避免这样的问题,所以他们一致决定采取做二次验证这种方案来进行修复。拓展知识 JavaScript的加载与执行

浏览器的渲染线程和JS执行线程是互斥的,并且JavaScript默认是阻塞加载的。页面的下载和渲染都必须停下来等待脚本执行完成。JavaScript执行过程耗时越久,浏览器等待响应用户输入的时间就越长。(1)加载

不管是script标签直接引入的情况,还是src加载的外部资源,都会阻塞页面的渲染。所以一般为了从体验上考虑,我们会将JS文件放置在body标签闭合之前。不过新版的IE、Firefox、Safari和Chrome都允许并行下载JavaScript文件。但是只是JavaScript文件可以并行下载,渲染还是被阻塞的,页面仍然必须等待所有JavaScript代码下载并执行完成才能继续。(2)执行

每当JavaScript文件加载完成后,都会立刻执行该文件。所以你会看到下一次的请求并不是在上一次请求结束之后立即开始,中间的耗时就是上一个脚本文件的执行时间。

一般对于JavaScript的优化建议如下。

1)将script脚本文件放置在body标签闭合之前。

2)减少script请求数量。

3)无阻塞脚本,在页面加载完成后才加载JavaScript代码。这就意味着在window对象的onload事件触发后再下载脚本。

·Defer,async。

·动态添加script元素。

不过在上面这个故事中,正是由于对JavaScript的优化引发了抢购页面先显示元素可操作,然后在JavaScript加载完成后,JavaScript执行使元素不可操作。1.5过长的控件名称造成其他元素显示错位

小蔡接到一个公司内部在线表单项目的测试任务,这个项目中有3个独立的角色:管理员A负责编辑和布局表单控件,用户B负责填写表单中控件的内容,而审核员C只能查看B操作后的结果。

这个需求看上去不难,小蔡快速分析并且记录了以下几个测试点,开始了测试工作。

1)A可以正常添加不同类型控件(文本框、富文本框、下拉列表、多选框、单选框等)到页面中。

2)B可以正常在这些控件中输入数据。

3)C可以正常查看B所有的操作内容。

4)针对各个角色所具有的不同的操作权限进行验证。

5)A更新表单后,B要可以看到对应的变化。

6)A未完成操作或者未保存的表单,B是无法看到和使用的。

7)B不保存后者提交操作结果,C无法看到B的操作内容。

8)跨浏览器和跨平台测试。

在测试过程中,小蔡发现这个表单做的类似于我们熟知的Office应用的所见即所得的形式,即A在屏幕左上方放置一个多选框并保存后,B打开页面后也可以在屏幕左上方看到一个多选框,最后C登录后也可以在屏幕左上方看到这个多选框。这使得整个功能变得更加容易测试,几乎是瞥一眼就能看到有没有问题。

三下五除二就跑完用例,小蔡正准备结束测试,偶然间一眼瞥到表单上的多选框选项上,她突然意识到既然多选框和单选框中的选项内容都是自己定义的,那在选项内容中输入超长字符串时,会不会导致该控件的显示位置发生变化呢?

带着这个疑问,小蔡重新使用A角色设置了一个超长的多选框选项名称,然后用B角色做了勾选操作,最后再用C去查看结果。结果她发现了问题:C查看到的结果中,勾选后的内容和多选框显示错位了。

再仔细重现了一遍问题后,小蔡发现A在编辑模式给多选框设置超长的选项名称的时候,在界面上多选框的位置被挤到了文本中央,如图1-9所示。图1-9 表单编辑界面

B在操作视图中看到的这个多选框又被强制对齐到了文字最左侧,如图1-10所示。

而C在审核视图中看到的情况却是A和C的结合体,即多选框被重置到了文字中央,而被勾选的位置却出现在文字的最左端(见图1-11)。

有了小蔡的过程重现,开发人员很快就定位到出现问题的原因:首先是在A用户使用的过程中(见图1-9),没有把操作结果查看视图中的多选框强制左对齐。其次是在用户C使用过程中(见图1-11),由于使用jQuery定制化多选框中的代码逻辑错误,导致勾选状态下的可勾选位置和多选框本身出现了分离,最终导致问题出现。图1-10 表单操作界面图1-11 操作结果查看页面核心知识 常见的HTML元素及常见检查点

1)

常见检查点:下拉列表数据的正确性;数据被选中是否正确,是否变形,是否只读,多选/单选是否正确。

2)

常见检查点:文本是否正确;文本字体、大小、颜色、间距是否正确;for属性是否绑定了正确的元素等。

3)标签,用于收集用户信息。

根据不同的type属性值,输入字段拥有很多种形式。可以是文本字段、复选框、掩码后的文本控件、单选按钮、按钮等。

4)button可点击的按钮,点击后通常会触发相应事件。

常见检查点:点击按钮后触发的行为和期望不符合;页面卡死未响应;点击后变形等。

5)text文本输入。

常见检查点:是否只读;SQL注入攻击;输入内容超过文本框长度是否引起形变等。

6)checkbox多选框。

常见检查点:选中/取消勾选是否有效;文本长度过长是否引起形变;页面刷新后是否被自动取消/勾选等。

7)radio单选框。

常见检查点:单选是否有效;文本长度过长是否引起形变;页面刷新后是否被自动取消/勾选等。

8)image图片区域。

常见检查点:图片加载是否正确;图片加载失败或者关闭时行为是否符合预期;鼠标指针移动到图片上后显示的文本是否正确;图片是否可以正确点击/拖曳等。

9)submit提交按钮,提交当前

表单信息到指定页面。

常见检查点:提交信息完整性等。1.6多次操作本该禁用的页面组件造成服务器出错

对页面上的组件进行多次点击是测试人员经常使用的小技巧之一,通常小蔡在执行完基本测试用例之后,开始进行探索性测试时会使用这个技巧,并且利用这个测试技巧发现了不少问题。

这些问题主要集中在用户提交服务器请求后服务器进行处理的相关功能上,例如读取、保存、提交、删除等功能(见图1-12)。

小蔡发现如果网络速度比较慢或者产品本身性能不够好,在用户点击了这些功能按钮后,而页面刷新完成之前这段时间内,该功能按钮仍然可能被用户继续点击。即使有些页面上的按钮处于灰色不可用状态,但当你尝试点击这些灰色的按钮,会发现点击后仍然会给服务器端发送请求(见图1-13)。图1-12 用户通过“删除”“保存”等功能和服务器交互图1-13 功能按钮在被置灰后仍然可以使用

这样带来了一系列问题,举例来说,对于保存功能,用户多次点击后会向后台发送多次请求,数据库中也会产生多条重复的数据,这样不仅会造成数据统计错误,更会给再次使用这些数据的人或程序造成很大的麻烦。一个更极端的例子是免密码支付的场景,当用户不小心多次点击支付按钮后,会给用户造成不小的损失;对于删除功能来说,多次点击“删除”按钮后,实际上第一个请求已经让数据库将对应的数据删除了,接下来的删除请求可能会造成后台程序的大量异常。

小蔡发现解决此类问题也很简单,只需要开发人员在编写代码时注意,只允许对该类功能按钮操作一次,在用户操作之后,不仅需要把对应的功能按钮置灰,同时需要取消这些功能按钮上面绑定的事件响应处理机制。

通常小蔡除了会在小组的回顾会议上向开发人员分析这些问题产生的原因和避免方式,还在每张开发故事卡上明确地标注需要测试多次快速点击按钮的场景,这样可以让开发人员从意识上提高对这类缺陷的警惕,从而在编写代码时注意预防此类问题的发生。拓展知识 回顾会议

无论一个Scrum团队有多出色,总有需要改进的地方。即使一个好的Scrum团队会不断寻找需要改进的方面,这个团队也应该做一个简单回顾,目的是在每个迭代的最后来回顾团队目前做得如何以及找到改进的方法。

回顾会议(Sprint Retrospective)通常发生在每个迭代最后一天,用来帮助团队进行自我改进。会议长度通常为1个小时,团队成员在一起列出团队应该做的事情、需要停止做的事情、应该保持下去的事情。接着团队成员对所有提议进行投票,这样可以在有限的时间里优先讨论大家最关心的几个问题。通过集思广益,提出改进方法,在紧接着的迭代中进行改进。

在下个迭代的回顾会议一开始,会首先关注上一次回顾会议的结果是否被落实。1.7页面跳转后出现HTTP 400错误

公司网站又升级了!这次升级后网站增加了一个保险报价功能:客户先在网站上回答公司设计的各种问题(单选题),系统会把答案汇总起来,传给后台计算价格,然后后台系统把计算出的保险报价返回给网站并显示在页面上。

从功能上看,小蔡觉得这个功能需求的关键是网站上设计的每一个问题都会作为一个价格因子并对最终报价产生影响。测试的重点应该是检查每个因子能够引起的价格变化是否符合预期。另外由于每类问题都分布在不同的页面上,所以需要确保在页面切换后,系统能保存之前选择的答案而不丢失。最后性能要求是在后台系统返回报价的时间上,根据业务方的需求需要遵守2/5/8原则,最长不能超过8秒,所以还需要增加对应的性能测试。

设计完用例,小蔡和开发人员一起进行了冒烟测试,结果每个功能都符合预期。于是小蔡在正式测试阶段把大部分精力都放到了验证各个价格因子对价格变化的影响上面。

经过大量的反复选择问题答案和页面切换操作后,小蔡像之前一样准备进入到报价汇总页面查看最终价格,突然发现页面出现HTTP 400错误(见图1-14)!图1-14 HTTP 400异常

小蔡眼睛一亮,赶紧回退到上一个页面,重新点击报价汇总按钮再次进入报价汇总页面,反复试了好几次,发现仍然会碰到HTTP 400这个问题。于是她关闭并重新启动浏览器,尝试再次重现这个问题,准备整理下出现问题的场景,然后报给研发人员修复,结果这次却正常进入到报价汇总页面。

小蔡觉得挺奇怪的,难道刚才是服务器“抽风”才导致HTTP 400异常?于是她又一连操作了好几次到汇总页面的场景,结果都没有重现问题。虽然感觉很神奇,但是因为没有能够重现问题,小蔡也只能暂时作罢,一边想着肯定是服务器抽风了吧,一边继续测试价格因子。

5分钟以后,当她再次准备进入到价格汇总页面时,问题又出现了,再次显示HTTP 400错误页面!看着页面上提示的错误信息,小蔡突然间有点儿明白了,提示信息说HTTP Request Header长度过长,因此问题应该是在HTTP Request Header上。小蔡利用浏览器自带的开发工具查看了下HTTP的请求头,结果瞬间就发现Cookie看上去似乎比平时看到的要长好多(见图1-15)。

小蔡怀疑是Cookie有问题,于是就找开发人员确认。在给开发人员演示了一遍这个Bug后,开发人员终于分析出造成这一结果的直接原因是Cookie长度太长,导致Request Header长度超标,最后发生HTTP Error 400。而再深入一层的根本原因是开发人员为了在切换页面时保存前几个页面的答案状态,把这些状态存到了Cookie里面,而每次翻页的时候又把答案信息错误地添加到Cookie已有信息之后,导致随着小蔡翻页操作越来越多,Cookie也越来越长,最后当Cookie长度超过浏览器限制后就产生了错误。图1-15 从浏览器工具中查看Cookie

知道了问题原因,小蔡仔细回想了下整个用例设计过程,觉得这样的问题即使通过覆盖各种用户使用场景仍然会不好发现。但如果测试人员在测试之前能够对整个功能的设计或者实现有一些了解的话,就可以注意到这个点,并且加以测试了。例如这次的Cookie超长问题,如果测试人员和开发人员先进行一些沟通,了解到代码是通过把信息存储到Cookie中去实现该功能,那么测试人员会很自然地想到Cookie长度通常是有限制的,因此会对这种存储信息的方式做特定的测试。核心知识 HTTP Request Header长度限制

Request Header就是往服务器发送的请求头,HTTP协议中并没有限制Header的大小。理论上无论我们的Header有多大都是可以的。

但实际上各个主流浏览器都会对Header长度进行限制,从几十KB到几百MB不等,基本上能满足平时的需求。此外,在服务端也可以对Heder长度做限制。比如Nginx就可以限制Header的长度。

HTTP Header如果不限制大小会有什么影响?

如果某个网站的服务器是不限制Header大小的,那么它就有可能被黑客利用实施攻击,比如DDoS。黑客可以利用这一点,发送一个非常大(比如几MB)的请求,会占用服务器一个进程来专门处理这个请求。此类请求数量过多时,服务器就无法提供其他对外服务。1.8使用没有添加时间戳的缓存使用户看到过期数据

当代主流的网站都使用了缓存技术,目的在于减少用户请求对服务器的压力。当用户首次通过浏览器请求服务器的资源时,服务器会返回所有的资源;当用户再次请求服务器资源时,浏览器会判断资源是否已更新,如果更新了,再向服务器发起请求,如果没有更新,就使用浏览器中缓存的资源。

这里有一个问题,浏览器是如何判断资源是否更新了?一般来说,资源文件在文件名中要么添加时间戳(见图1-16),要么添加标识符(标识符可以是任何一组区别资源不同版本的数值,如v1、v2,或者GUID等)来唯一区分资源的不同版本(见图1-17)。只要本地缓存的资源文件和服务器端最新的资源文件名称不一样,浏览器就要从服务器端获取新的资源文件,如果一样,就使用本地缓存的资源。图1-16 带有时间戳的资源文件图1-17 带有标识符的资源文件

如果资源文件没有被添加时间戳或者标识符呢?那用户只能通过手动清除浏览器的缓存来强制获取最新的资源文件了,不过这样等于所有用户请求的文件都没有从浏览器缓存中读取,也就没有为服务器缓解访问压力。并且绝大多数用户并不会去手动清除浏览器的缓存,这就导致用户看到网页的资源文件不是最新的。

最近小蔡测试的商品详细信息页面出现的Bug就属于这种情况。根据用户线上反馈,当用户修改了商品图片并且发布之后,不能及时看到更新后的图片,而是需要等一段不确定的时间才能看到更新后的图片。

经过小蔡和开发人员的调查,发现导致这个问题的原因是缓存资源文件没有被设置时间戳或者标识符,导致用户修改后不能看到更新后的图片。而之所以会造成不确定时间后才能看到更新后的图片,是由于不同浏览器对于没有设置时间戳或者标识符的缓存资源文件处理不一致造成的。

例如IE缓存时间就是一个Session的时间,如果用户打开一个新的IE窗口时,他们就会获取最新的静态资源;而其他浏览器(例如Firefox),则会通过HTTP头文件中Last-Modified参数的具体定义来判断是否需要去重新获取资源。

而小蔡在之前的测试中,为了避免缓存数据对测试结果的影响,她在浏览器中设置了每次退出浏览器时清空缓存(见图1-18),这反而导致小蔡漏测了缓存没有及时刷新的问题。

由于缓存在Web产品中是普遍存在的,所以小蔡立刻取消了浏览器中清除缓存的设置,改为使用手工清除缓存的方式。当她之后在测试中遇到测试结果和预期结果不同,并且有可能是缓存未清除造成的情况时,她会手动清除缓存,这样可以更准确地进行测试。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载