因掘金一文章不能超过2W字,所以分开上下篇;前端
本文阅读来自极客,课程连接以下: time.geekbang.org/column/103java
做者:茹炳晟程序员
先把我的感想列出来吧,全文很长,耐心看,可能要20分钟+,部份内容会比较详,阅读体验可能会比较差,由于都是文字为主;算法
总的来讲,这个课程值这个价格,看完了以后,以为知识面广了不少,不必定对实际工做有用,可是用来扩展知识面,是一个很不错的课程,同时也了解其余企业是怎么作的,建议小伙伴都看一下;数据库
经过这个课程目录,其实也能够看得出,不少大公司的测试工程师,并不带带是业务测试,具有开发能力是必要条件,由于也但愿能给本身一个警戒;编程
若是非要推荐,第5章的自动化测试工具跟35章的数据构建值得一看,里面的内容很丰富;json
这个课程,陆陆续续看了很久,看的很认真,包括评论都不放过,所以看到有意思的评论,都会贴出来;后端
下面的内容都是亲手打出来的,由于jb依然相信,本身写/打出来的东西,印象会加深~api
经历过的变革:数组
趋势总结:
输入用户名和密码,点击确认按钮,验证是否登陆成功便可
将全部可能的输入数据划分红若干个子集,在每一个子集中,若是任意一个输入数据对于揭露程序中潜在错误都具备同等效果,这样的子集就构成一个等价类;
是选取输入、输出的边界值进行测试; 简单描述就是正好等于、刚刚大于、刚刚小于;
边界值算是对等价类划分的补充
指包含了软件输入值和前提条件全部可能组合的测试方法,彻底穷尽测试的系统里应该不残留任何未知的软件缺陷;
但这种作法不实际,由于受时间成本,通常采用基于风险驱动的模式,有所侧重地选择测试范围和设计测试用例;
显式功能性需求指的是软件自己须要实现的功能;
基于等价类划分和边界值分析方法:
输入已注册的用户名和正确的密码,验证是否登陆成功;
输入已注册的用户名和不正确的密码,验证是否登陆失败,而且提示信息正确;
输入未注册的用户名和任意密码,验证是否登陆失败,而且提示信息正确;
用户名和密码都为空,验证是否登陆失败,而且提示信息正确;
用户名额密码二者之一为空,验证是否登陆失败,而且提示信息正确;
若是登陆功能启用了验证码功能,在用户名和密码正确的前提下,输入正确的验证码,验证是否登录成功;
若是登陆功能启用了验证码功能,在用户名和密码正确的前提下,输入错误的验证码,验证是否登录失败,而且提示信息正确;
复制代码
其余场景用例:
用户名和密码是否大小写敏感;
页面上的密码框是否加密显示;
后台系统建立的用户第一次登录成功时,是否提示修改密码;
忘记用户名和忘记密码的功能是否可用;
前端页面是否根据设计要求限制用户名和密码长度;
若是登录功能须要验证码,点击验证码图片是否能够更换验证码,更换后的验证码是否可用;
刷新网页是否会刷新验证码;
若是验证码具备时效性,须要分别验证时效内和时效外验证码的有效性;
用户登陆成功可是会话超时后,继续操做是否会重定向到用户登陆界面;
不一样别的用户,好比管理员用户和普通用户,登陆系统后的权限是否正确;
页面默认焦点是否认位在用户名的输入框里;
快捷键Tab和Enter等,是否能够正常使用;
网络延迟或者弱网或者切换网络或者断网时正常登录是否正常
是否支持第三方登录;
是否可记住密码,记住的密码保存是否加密;
记住密码是否有有效期,过时以后是否会清空密码;
用户名密码是否支持特殊字符和中文;
是否能够使用登陆的api发送登陆请求,并绕开验证码校验;
是否能够用抓包工具抓倒的请求包直接登陆;
截取到的token等信息,是否能够在其余终端上直接使用,绕开登陆;
后端是否有校验内容的格式长度;
登陆后输入登陆URL,是否还能再次登陆;
登陆错误后的提示是否有安全隐患;
密码强弱型校验;
空和输入空字符串的校验是否一致;
安全性方面异地登陆校验、更换设备登陆校验;
设备互斥;
密码错误限制次数;
输入帐号密码时对键盘格式是否有要求;
密码一栏是否须要设置明暗码切换按钮;
输入帐号密码格式不规范时是否将按钮设置为不可点击;
输入栏是否设置快速删除按钮;
多设备多平台同帐号登陆是否有互踢机制;
修改密码后,前密码不生效;
用户名规则、密码规则;
先后台切换,横竖屏切换;
复制代码
主要涉及安全性、性能和兼容性测试;
安全性测试用例:
用户密码后台存储是否加密;
用户密码在网络传输过程当中是否加密;
密码是否具备有效期,密码有效期到期后,是否提示须要修改密码;
不登陆的状况下,在浏览器中直接输入登陆后的url地址,验证是否会重定向到用户登陆页面;
密码输入框是否不支持复制和粘贴;
密码输入框内输入的密码是否均可以在页面源码模式下被查看;
用户名和密码的输入框中分别输入典型的SQL注入攻击字符串,验证系统的返回页面;
用户名和密码的输入框中分别输入典型“XSS跨站脚本攻击”字符串。验证系统行为是否被篡改;
连续屡次登陆失败状况下,系统是否会阻止后续的尝试以应对暴力破解;
同一用户在同一终端的多种浏览器上登陆,验证登陆功能的互斥性是否符合设计预期
同一用户前后在多台终端的浏览器上登陆,验证登陆是否具备互斥性;
用户登录后存储在数据库中的用户我的信息是否加密;
用户登录过程当中log中是否有我的信息明文打印;
是否使用到缓存;
复制代码
性能压力测试用例:
单用户登陆的响应时间是否小于3秒;
单用户登陆时,后台请求数据是否过多;
高并发场景下用户登陆的响应时间是否小于5秒;
高并发场景下服务端监控指标是否符合预期;
高集合点并发场景下,是否存在资源死锁和不合理的资源等待;
长时间大量用户连续登陆和登出,服务器端是否存在内存泄露;
同时支持10个用户登陆,同时9个或者11个用户登陆是否正确或者提示信息正确;
复制代码
兼容性测试用例:
不一样浏览器下,验证登陆页面的显示以及功能正确性
相同浏览器的不一样版本下,验证登陆页面的显示以及功能正确性
不一样移动设备终端的不一样浏览器下,验证登陆页面的显示以及功能正确性
不一样分辨率的界面下,验证登陆页面的显示以及功能正确性
复制代码
小结
1)用例设计须要考虑明确的显示功能性需求,还要考虑兼容性、安全性、性能等一系列的非功能性需求;
2)用例设计是不可穷尽的,受限于时间成本,所以须要兼顾缺陷风险和研发成果之间的平衡;
可以覆盖全部等价类以及各类边界值的用例都是好用例;
总体完备性
是一个完备的总体,是有效测试用例组成的集合,可以彻底覆盖测试需求;
等价类划分的准确性
对于每一个等价类都能保证只要其中一个输入测试经过,其余输入也必定测试经过;
等价类和的完备性
保证全部可能的边界值和边界条件都已经正确识别;
等价类划分
等价类中任意一个输入数据对于揭露程序中潜在错误都具备同等效果;
成绩系统,取值范围0-100之间的整数,及格60分;
有效等价类:
0-59之间的任意整数;
59-100之间的任意整数;
无效等价类:
小于0的负数;
大于100的整数;
0-100之间的任何浮点数;
其余恩义非数字字符;
复制代码
边界值分析
成绩系统:-一、0、一、5九、60、6一、9九、100、101
复制代码
错误推测方法
指基于对被测试软件系统设计的理解、过往经验以及我的直觉,推测出软件可能存在的缺陷,从而有针对性地设计测试用例的方法,相似于探索性测试;
复制代码
在具体的用例设计时,首先须要搞清楚每个业务需求所对应的多个软件功能需求点,而后分析出每一个软件功能需求点对应的多个测试需求点,再针对每一个测试需求点设计测试用例;
2个关键点:
只有深刻理解被测试软件的架构,才能设计出更好的测试用例,去发现系统边界值以及潜在缺陷;
必须深刻理解被测软件的设计和实现细节,深刻理解软件内部的处理逻辑;
须要引入需求覆盖率和代码覆盖率来衡量测试执行完备性;
小结
1)好的测试用例必定是一个完备的集合,可以覆盖全部等价类以及各类边界值; 大部分状况是采用过后的角度,从漏测率和问题严重程度来评估用例的好坏;
2)设计而是用例的方法有不少种,但综合运用等价类划分、边界值分析和错误推测方法,能知足绝大多数的需求; 需求合理性测试,即用户体验测试;
3)好的测试用例再设计时,须要从软件功能需求出发,全面、无遗漏的识别出测试需求;
4)想设计好一个好的测试用例,必需要深刻理解被测软件的架构设计,深刻软件内部的处理逻辑,而且使用需求覆盖率和代码覆盖率来衡量测试执行的完备性;
单元测试是指,对软件中的最小可测试单元在与程序其余部分相隔离的清空下进行检查和验证的工做,这里的最小和测试单元一般是指函数或者类;
单元测试通常以自动化的方式执行,在大量回归测试的场景下更能带来高收益;
电视机的生成、测试和软件的开发、测试对比:
电子元器件就像是软件中的单元,一般是函数或者类,对单个元器件的测试就像是软件测试中的单元测试;
组装完成的功能电路板就像是软件中的模块,对电路板的测试就像是软件中的集成测试;
电视机所有组装完成就像是软件完成了预发布的版本,点司机所有组装完成后的开机测试就像是软件中的系统测试;
复制代码
单元测试的对象是代码;
单元测试的主要手段有驱动代码、桩代码、mock代码;
代码的基本特征与产生错误的缘由:
通常状况下,单元测试的用例是一个输入数据和预计输出的集合;
在明确了代码须要实现的逻辑功能基础上,什么输入,应该产生什么输出;
输入数据:
被测试函数的输入参数
被测试函数内部须要读取的全局静态常量
被测试函数内部须要读取的成员变量
函数内部调用子函数得到的数据
函数内部调用子函数改写的数据
嵌入式x系统中,在中断调用时改写的数据
复制代码
预计输出:
被测试函数的返回值
被测试函数的输出参数
被测试函数所改写的成员变量
被测试函数所改写的全局变量
被测试函数中进行的文件更新
被测试函数中进行的数据库更新
被测试函数中进行的消息队列更新
复制代码
驱动代码是用来调用被测函数的;
驱动模块一般包括调用被测函数前的数据准备、调用被测函数以及验证相关结果三个步骤;
桩代码和mock代码是用来代替被测函数调用的真实代码;
桩代码是用来代替真实代码的临时代码;
桩函数内部实现:
mock代码跟桩代码很是相似,都是用来代替真实代码的临时代码;
mock跟桩代码的本质区别-测试期待结果的验证:
对于mock代码来讲,关注点是mock方法有没有被调用,以什么样的参数被调用,被调用的次数,以及多个mock函数的前后调用顺序;
复制代码
对于桩代码,关注点是利用stub来控制被测函数的执行路径,不会去关注stub是否被调用以及怎么样被调用;
并非全部的代码都要进行单元测试,一般只有底层模块或者核心模块的测试中才会采用单元测试;
须要肯定单元测试框架的选型:
引入代码覆盖率:
执行单元测试、代码覆盖率统计和持续集成流水线; 确保每次代码提交都会自动触发单元测试;
精密耦合的代码难以隔离;
隔离后编译连接运行困难;
代码自己的k可测试性较差,一般代码的可测试性和代码规模成正比;
没法经过桩代码直接模拟系统底层函数的调用;
代码覆盖率越日后越难提升;
复制代码
小结
1)介绍了单元测试概念,讨论了用例的组成,以及实际项目中开发单元测试的方法;
2)开展过程须要注意3个问题:
把人对软件的测试行为转化为由机器执行测试行为的一种实践;
本质就是写一段代码,而后去测试另一段代码; 实现自动化测试用例自己属于开发工做,还须要随着被测对象的改变而不断更新,维护用例成本;
当自动化用例维护成本高于其节省的测试成本时,自动化测试失去了价值;
小结
1)自动化测试是,把人工对软件的测试转化为由机器执行测试行为的一种实践,能够把测试工程师从机械重复的测试工做中解脱出来,将更多的经历放在新功能的测试和更全面的测试用例设计上;
2)自动化测试是一把双刃剑,必定程度上解放测试工程师的劳动力,完成一些人工没法实现的测试,但并不是万能;一旦维护成本高于节省的测试成本,自动化就不合适了;
单元测试自己就是自动化测试,由于它根据软件详细设计采用等价类划分和边界值分析方法来设计测试用例,在测试代码段实现后再以自动化的方式统一执行;
广义上讲,单元测试阶段的自动化内涵不只仅指测试用例执行的自动化,还应该包含如下5个方面:
有些框架代码是由自动化工具生成的,而并不是手工完成的,这样,开发者就能够把更多的精力放在测试逻辑的覆盖和测试数据的选择上;
好比selenium的代码能够经过录制生成,TestNG框架代码由自动化工具生成;
这部分是指,自动化工具可以根据不一样变量类型自动生成测试输入数据;
自动桩代码的生成是指自动化工具能够对被测试代码进行扫面分析,自动为被测函数内部调用的其余函数生成可编程的桩代码,并提供基于测试用例的桩代码管理机制;
那什么是抽桩?在单元测试阶段,假如函数A内部调用的函数B是桩代码,那么在代码级集成测试阶段,但愿函数A再也不调用假的函数B,而是调用真是的函数B,这个用真实函数B代替本来桩代码函数B的操做,就成为抽桩;
静态分析主要指代码的静态扫描,目的是识别出违反编码规则或编码风格的代码;
一般这部分工做是结合项目具体的编码规则和编码风格,由自动化工具经过内建规则和用户自定义规则自动化完成的;
经常使用的静态代码分析工具备Sonar和Coverity;
单元测试用例执行结束后,自动化工具能够自动统计各类测试覆盖率,包括代码行覆盖率、分支覆盖率、MD/DC覆盖率等;
这些自动统计的指标,能够帮助衡量单元测试用例集合的充分性和完备性,并能够为你增补测试用例以提升测试覆盖率的依据;
简单的说,代码级集成测试是指将已经开发完成的软件模块放在一块儿测试;
代码级集成测试与单元测试最大的区别是,代码级集成测试中被测函数内部调用的其余函数必须是真实的,不容许使用桩代码代替,而单元测试仲容许使用桩代码来模拟内部调用的其余函数;
Web Server测试,主要是指SOAP API和REST API这两类API测试,最典型的是采用SoapUI和Postman等相似的工具;
但这类测试工具基本都是界面操做手动发起requests并验证response,因此难以和CI/CD集成,因而乎就出现了API自动化测试框架;
若是采用API自动化测试框架来开发测试用例,那么这些测试用例的表现形式就是代码,以下:
对于基于代码的API测试用例,一般包含3个步骤:
目前最流行的API自动测试框架是REST Assured,能够方便的发起Restful API调用并验证返回结果;
一样的,Web Server的自动化测试内涵不只仅包括API测试用例执行的自动化,还包括如下几个方面:
在开发API测试的过程当中更加关心的是,如何设计测试用例的输入参数以及组合,以及在不一样参数组合状况下response的验证;
这时候就须要测试脚手架代码的自动生成技术; 生成的测试脚手架代码包含被测试API的调用、测试数据与脚本的分离,以及response验证的空实现;
与单元测试的输入数据的自动化生成相似,惟一不一样的是,单元测试针对的参数是函数输入参数和函数内部输入,而API测试对应的是API的参数以及API调用的Payload;
数据生成的原则一样遵循边界值原则;
对于API调用返回结果的验证,比较关注的点是返回状态码、Scheme结构以及具体的字段值;
核心思想是自动化比较两次相同API调用的返回结果,并自动识别出有差别的字段值,比较过程能够经过规则配置去掉诸如时间戳、会话ID(Session ID)等动态值;
SoapUI或者Postman都是单一调试,累积到必定程度,里面会有大量测试用例集,若是引入基于代码实现的API测试框架,这意味着这些大量的用例都须要用代码的方式重写一遍,这是很是恶心的;
建议是,开发一个自动化代码转换生成工具,这个工具的输入是SoapUI或者Postman的测试用例元数据(JSON文件),输出是符合API测试框架规范的基于代码实现的测试用例,好处是原来积累的用例能够直接转换成在CI/CD上能够直接接入的自动化测试用例;
新增的用例,能够在SoapUI或者Postman测试验证,没问题,直接转化成符合API测试框架规范的测试用例;
postman集成CICD,经过Postman+newman+jenkins,在Postman导出一个json文件,在另外一个服务器部署newman,命令行执行Postman导出的json文件,而后直接在服务器用newman工具就能测试并生成测试报告;
robot framework+requestslibrary的方式来作API自动化测试,识别编程能力不强的团队;
核心思想是基于页面元素识别技术,对页面元素进行自动化操做,以模拟实际终端用户的行为并验证软件功能的正确性;
小结
介绍了软件研发生缪功能周期各个阶段的自动化测试技术,包括单元测试、代码级集成测试、Web Service测试和GUI测试的自动化技术;
测试覆盖率一般被用来衡量测试的充分性和完整性,从广义的角度来说,测试覆盖率主要分为两大类: 面向项目的需求覆盖率和技术的代码覆盖率;
需求覆盖率是指测试对需求的覆盖程度,一般的作法是将每一条分解后的软件需求和对应的测试简历一对多的映射关系,最终目标是保证测试能够覆盖每一个需求,以保证软件产品的质量;
一般会采用ALM,Doors和TestLink等需求管理工具来创建需求和测试的对应关系,以此计算测试覆盖率;
需求覆盖率统计方法属于传统瀑布模型下的软件工程实践,传统瀑布模型追求自上而下地制定计划、分析需求、设计软件、编写代码、测试和运维,属于重量级流程,已经很难适应当今胡丽娜网时代下的敏捷开发;
因此,通常的覆盖率,默认是指代码覆盖率,而并不是需求覆盖率;
是指,至少被执行了一次的条目数占整个条目数的百分比;
若是条目数是语句,对应的就是代码行的覆盖率; 若是条目数是函数,对应的就是函数覆盖率; 若是条目数是路径,那么对应的就是路径覆盖率;
统计代码覆盖率的根本目的是找出潜在的遗漏测试用例,并有针对性的进行补充,同时还能够识别出代码中那些因为需求变动等缘由形成的不可达的废弃代码;
代码覆盖率越高越能说明你的测试用例设计是充分且完备的,但测试的成本会随着覆盖率的提升以指数的方式迅速增长;
代码覆盖率反馈的仅仅是已有代码的哪些逻辑被执行过了,哪些逻辑尚未被执行过,但若是其余模块依赖这段代码,能确保必定没有问题吗?
其根本缘由在于代码覆盖率的计算是基于现有代码;
高的代码覆盖率不必定能保证软件的质量,但低的代码覆盖率必定不能保证软件的质量;
JaCoCo是一款Java代码的主流开源覆盖率功能,很方便的嵌入到Ant、Maven,而且能够很好的集成到jenkins等主流持续集成工具;
JaCoCo的代码覆盖率报告长啥样的?
如图所示,包括了每一个Java代码文件的行覆盖率以及分支覆盖率,并给出了每一个Java代码文件的行数、方法数和类数等信息;
下图所示为每一个Java文件内部详细的代码覆盖率状况,绿色行表示已经被覆盖,红色行表示还没有被覆盖,黄色行表示部分覆盖; 左侧绿色菱形块表示该分支已经被彻底覆盖、黄色菱形块表示该分支仅被部分覆盖;
经过这个报告,就能够知道代码真实的执行状况,而后再能够针对性的设计测试用例;
前端能够考虑使用jest;
实现代码覆盖率的统计,最基本的方法就是注入(Instrumentation); 注入就是在被测代码中自动插入用于覆盖率统计的探针(Probe)代码,并保证插入的探针代码不会给源代码带来任何影响;
对于Java代码来讲,根据注入目标的不一样,能够分为源代码(Source Code)注入和字节码(Byte Code)输入两大类; 基于JVM自己特性以及执行效率的缘由,目前主流的工具基本都是使用字节码注入,注入的具体实现采用ASM技术;
ASM是一个Java字节码操纵框架,能被用来动态生成类或者加强既有类的功能,直接直接产生class文件,也能够在类被加载入JVM以前动态改变类行为;
根据注入发生的时间点,字节码注入又能够分为两大模式: On-The-Fly注入模式和Offline注入模式;
特色在于无需修改源代码,也无需提早进行字节码插桩,适用于支持Java Agent的运行环境;
优势是能够在系统不停机的状况下,实时收集代码覆盖率信息,缺点是运行环境必须容许使用Java Agent;
实现 On-The-Fly 模式,主要有两种技术方案:
Offline 模式也无需修改源代码,可是须要在测试开始以前先对文件进行插桩,并事先生成插过桩的class文件;
这种方式适用于不支持Java Agent的运行环境,以及没法使用自定义类装载器的场景;
优势是JVM启动时再也不须要使用Java Agent额外开启代码,缺点是没法实时获取代码覆盖率信息,只能在系统停机时下获取;
Offlinne模式根据是生成新的class文件仍是直接修改原class文件,又能够分为Replace和Inject两种不一样模式;
和On-The-Fly注入模式不一样,Replace和Inject的实现是在厕所运行前就已经经过ASM将探针插入了class文件,而在测试的运行过程当中不须要任何额外的处理;
Cobertura就是使用Offline模式的典型表明;
小结
测试覆盖率一般被用来衡量测试的充分性和完整性,包括面向项目的需求覆盖率和偏向技术的代码覆盖率;
而需求覆盖率的统计方式再也不适用于如今的敏捷开发模式,全部如今谈到的测试覆盖率,大可能是指代码覆盖率;
高的代码覆盖率不必定能保证软件的质量,由于代码覆盖率是基于现有代码,没法发现那些未考虑某些输入已经未处理某些状况造成的缺陷;
缺陷报告是测试工程师与开发工程师交流沟通的重要桥梁,也是测试工程师平常工做的重要输出,把发现的缺陷准确无歧义地表达清楚,是测试工程师最基本的一项技能;
准确无歧义的表达就意味着,开发工程师能够根据缺陷报告快速理解缺陷,并精肯定位问题;开发经理能够准确预估缺陷修复的优先级;产品经理能够额了解缺陷对用户或业务的影响以及严重性;
缺陷报告自己的质量将直接关系到缺陷被修复的速度以及开发工程师的效率,同时还会影响测试工程师的信用、测试与开发人员写做的有效性;
缺陷标题一般是别人最早看到的部分,是对缺陷的归纳性描述,一般使用"在什么状况下发生了什么问题"的模式;
描述不只要作到清晰简洁,最关键是要足够具体,切忌不能采用过于笼统的描述;描述的同时还必须清楚地表述发生问题的上下文,也就是问题出现的场景;
并且缺陷的标题不易过长,对缺陷更详细的描述应该放在缺陷概述里;
缺陷概述一般会提供更多归纳性的缺陷本质与现象的描述,是缺陷标题的细化;
缺陷概述的目的,清晰简洁地描述缺陷,使开发工程师可以聚焦缺陷的本质;
缺陷影响描述的是,缺陷引发的问题对用户或者对业务的影响范围以及严重程度;
缺陷影响决定了缺陷的优先级(Priority)和严重程度(Severity),开发经理会以此为依据来决定修复该缺陷的优先级;产品经理会以此为依据来衡量缺陷的严重 程度,并以为是否要等该缺陷被修复后才能发布产品;
准确描述缺陷影响的前提是,必须对软件的应用场景以及需求有深刻的理解,这也是对测试工程师业务基本功的考验;
环境配置用以详细描述测试环境的配置细节,为缺陷的重现提供必要的环境信息,好比操做系统类型和版本、被测软件软包、浏览器的种类和版本、被测软件的配置信息、集群的配置参数等等;
须要注意的是,环境配置的内容是按需描述,就是只描述那些重现缺陷的环境敏感信息;
前置条件是指测试步骤开始前系统应该处在的状态,目的是减小缺陷重现步骤的描述,排除没必要要的干扰,使其更有针对性;
缺陷重现步骤是整个缺陷报告中最核心的内容,目的在于用简洁的语言像开发工程师展现缺陷重现的具体操做步骤;
须要注意的是,操做步骤一般是从用户角度出发来描述,每一个步骤都应该是可操做且连贯的;
在写缺陷重现步骤时,要反复执行这些步骤确认:
而对于缺陷重现步骤的描述,应该要避免3个场景问题:
在描述重现步骤的过程当中,须要明确说明指望结果和实际结果; 指望结果来自于对需求的理解,而实际结果来自于测试执行的结果;
根据百度百科的解释,缺陷优先级是指缺陷必须被修复的紧急程度,而缺陷严重程度是指因缺陷引发的故障对软件产品的影响程度;
严重程度是缺陷自己的属性,一般确认后就再也不变化,而优先级是缺陷的工程属性,会随着项目进度、解决缺陷的成本等因素而变更;
那缺陷优先级和严重程度是什么关系?
变通方案是提供一种临时绕开当前缺陷而不影响产品功能的方式,一般由测试工程师或者开发工程师完成,或者一同决定;
变通方案的有无以及实施的难易程度,是决定缺陷优先级和严重程度的重要依据;
若是在发现缺陷的同时,定位出问题的根本缘由,清楚地描述缺陷产生的缘由并反馈给开发工程师,那么开发工程师修复缺陷的效率就会大幅提高;
附件一般是为缺陷的存在提供必要的证据支持,常见的附件有界面截图、测试用例日志、服务器端日志、GUI测试的执行食品等;
小结
一份高效的软件缺陷报告,应该包括缺陷标题、缺陷概述、缺陷影响、环境配置、前提条件、缺陷重现步骤、指望结果和实际结果、优先级和严重程度、变通方案、缘由分析、附件这几大块;
如何对一个阶段的BUG进行统计、分析并报告?
这种属于测试缺陷统计,bug趋势分析,bug收敛状况,bug模块分布,bug发现阶段统计等等,属于面向管理层和质量流程保障团队,通常这种都是利用缺陷管理系统的自带功能来生成相似的报告;
除了上面所须要的内容,还须要如下内容:
在早期的软件工程实践中,软件测试计划的制定一般是在需求分析以及测试需求分析完成后开始,而且是整个软件研发声明周期中的重要环节;
若是没有测试计划,会带来什么问题?
从这些问题,能够逆向思惟推导出,一份好的测试计划要包括如下几点: 测试范围、测试策略、测试资源、测试进度和测试风险预估;
顾名思义,测试范围描述的是被测对象以及主要的测试内容;
测试范围的肯定一般是在测试需求分析完成后进行,因此肯定测试范围的过程在必定程度上也是对测试需求分析的进一步校验,有助于在早期阶段发现潜在的测试遗漏;
测试策略简单来说就是需求明确"先测什么后测什么"和"如何来测"两个问题;
测试策略会要求明确测试的重点,以及各项测试的前后顺序;
测试策略还须要说明,采用什么样的测试类型和测试方法;不只要给出为何要选用这个测试类型,还要详细说明具体的实施方法;
根据测试需求分析的思惟导图来设计测试用例;
这里须要注意,要先实现主干业务流程的测试自动化;
对于须要手工测试的测试点,要决定采用什么类型的测试用例设计方法,以及如何准备相关的测试数据;
还要评估被测软件的可测试性,若是有可测试性的问题,须要提早考虑切实可行的变通方案,甚至要求开发人员提供可测试性的接口;
Web测试须要肯定覆盖的浏览器类型和版本,移动设备测试须要肯定覆盖的设备类型和具体IOS/Android的版本等;
那怎么肯定须要覆盖的移动设备类型以及IOS/Android的版本列表?
通常来讲,兼容性测试是功能测试的后期,等功能基本稳定后,才会开始兼容性测试;
假如是接入一些新框架,这时候就须要评估接入新框架的信息,此时就须要先进行兼容性测试,以确保后期不会引入没法解决的兼容性问题;
而兼容性用例的选取,基本上是来自于已经实现的自动化测试用例;
须要在明确了性能需求(并发用户数、响应时间、事务吞吐量、CPU、内存、IO、带宽、事务成功率、超时错误率等)前提下,结合被测系统的特色,设计性能测试场景并肯定性能测试框架;
好比,是直接在 API 级别发起压力测试,仍是必须模拟终端用户行为进行基于协议的压力测试。再好比,是基于模块进行压力测试,仍是发起全链路压测。
若是性能是背景数据敏感的场景,还须要肯定背景数据量级与分布,并决定产生背景数据的技术方案,好比是经过 API 并发调用来产生测试数据,仍是直接在数据库上作批量 insert 和 update 操做,或者是两种方式的结合。
无论采用哪一种方式,都须要明确待开发的单用户脚本数量,以便后续可以顺利组装压测测试场景;
性能测试的实施,是一个比较复杂的问题; 须要根据你想要解决的问题,肯定性能测试的类型,而后根据具体的性能测试类型开展测试;
测试资源一般包括测试人员和测试环境,这两类的资源是有限的;
而测试计划的目的就是,保证在有效资源下的产出最大化,因此,测试资源就是须要明确"谁来测"和"在哪里测"和"怎么测"的问题;
测试人员是最重要的,直接关系到整个测试项目的成败和效率,测试人员的资源一般由2个维度:
测试进度主要描述各种测试的开始时间,所需工做量,预计完成时间,并以此为依据来建议最终产品的上线发布时间;
在传统瀑布模型中,测试进度彻底依赖于开发完成并递交测试版本的时间;若是开发案提交测试版本发生了延误,那么在不裁剪测试需求的状况下,产品总体的上线时间就一样会延期;
然而在敏捷模式下,测试会贯穿于整个开发过程,不少测试工做会和开发工做同步进行,这样测试进度就不会彻底依赖于开发递交能够测试版本的时间;
行为驱动开发(Behavior-Driven-Development),就是平时所说的BDD,只的是能够经过天然语言书写非程序员可读的测试用例,并经过StepDef来关联基于天然语言的步骤描述和具体的业务操做,最典型的框架就是Cucumber;
计划赶不上变化,一般需求表更、开发延期、发现重大缺陷和人员变更是引入项目测试风险的主要缘由;
因此,在制定测试计划的时候,就要预估整个测试过程当中可能存在的潜在风险,以及当这些风险发生时的应对策略;
一份成功的测试计划,必须清楚的描述:测试范围、测试策略、测试资源、测试进度和测试风险预估这5个重要的方面;
在快速迭代过程,建议增长产品需求测试,意义在开发和测试开发前,保证全部人对需求理解的一致性;
目前测试工程师分为两大类别,一类是作业务功能测试,另外一类是作测试开发的;
按照对测试工程师重要程度进行排序,以下:
这项是核心竞争力;
测试策略设计能力是指,对于各类不一样的被测软件,可以快速准确地理解需求,并在有限的时间和资源下,明确测试重点以及最适合的测试方法的能力;
具有出色的测试策略设计能力,能够很是明确地回答出测试过程当中遇到的这些关键问题:
出色的测试策略设计能力,不是一朝一夕的事情,须要经历大量的实际历练,还要保持持续思考,主动去提炼共性的内容;
测试用例设计能力是指,不管对于什么类型的测试,都能设计出高效地发现缺陷,保证产品质量的优秀测试用例;
要作好测试用例设计,不只须要深刻理解被测软件的业务需求和目标用户的使用习惯,还要熟悉软件的具体设计和运行环境,包括技术架构、缓存机制、中间件技术、第三方服务集成等等。
要想提升测试用例设计能力,平时就要多积累,对常见的缺陷模式、典型的错误类型以及遇到过的缺陷,要不断地总结、概括,才能逐渐造成体系化的用例设计思惟。
还能够阅读一些好的测试用例设计实例开阔思路;
包含两个层面的含义:
学习工具,直接看官方文档会更快,由于里面的内容确定是最新最权威的;
在学习新内容时,必定要作到理解其原理,而不是只停留在表面的、简单的操做和使用,长期保持这种学习状态,能够在很大程度上提升逻辑思惟和理解能力;
探索性测试是指测试工程师在执行测试的过程当中不断学习被测系统,同时结合基于本身经验的错误猜想和逻辑推理,整理和分析出更多的针对性的测试关注点;
本质上,探索性测试思惟是测试用例设计能力和快速学习能力结合的必然结果;
优秀的探索性测试思惟能够帮助实现低成本的精准测试,精准测试最通俗的理解能够归纳为针对开发代码的变动,目标明确而且有针对性地对变动点以及变动关联点作测试,也是目前敏捷测试主推的测试时之一;
包含3个层面的含义:
这3个层面是依次递进的关系,越日后越能提现出测试工程师的核心竞争力;
自动化测试的核心价值仍是测试自己,自动化仅仅是手段;
测试工程师在项目中的做用,有点想润滑剂:
沟通能力会直接影响事务开展的效率,是一块敲门砖;
除了代码开发能力,测试开发工程师要具有测试系统需求分析能力; 要可以站在测试架构师的高度,识别出测试基础架构的需求和提升效率的应用场景;
测试开发工程师须要具有很是宽广的知识体系,你不只须要和传统的测试开发工程师打交道,由于他们是你构建的测试工具或者平台的用户; 并且还要和 CI/CD、和运维工程师们有紧密的联系,由于你构建的测试工具或者平台,须要接入到 CI/CD 的流水线以及运维的监控系统中去。
除此以外,你还要了解更高级别的测试架构部署和生产架构部署、你还必须对开发采用的各类技术很是熟悉。。
性能测试工程师的核心价值不在于会多少性能测试工具,而是对于性能问题的直觉和定位能力,这个须要靠扎实的基础理论知识和大量的实践才能培养出来;
小结
测试工程师按照工做内容,分为了功能测试工程师和测试开发工程师两类;
对于功能测试工程师来讲,其核心竞争力包括:测试策略设计能力、测试用例设计能力、快速学习能力、探索性测试思惟、缺陷分析能力、自动化测试技术和良好的沟通能力这七大部分,你能够有针对性地提高本身某方面的能力,去获取更大发展空间的“敲门砖”。
而对于测试开发工程师来讲,你须要具有优秀的测试系统需求分析能力和完备的知识体系,这样才能保证你设计的测试工做和平台,能够更好地知足提高测试效率的要求。
历来没有见过开发会迷茫,每每是测试在迷茫,想了好久,也许是这些缘由吧:
开发工程师一般是深度遍历,关注的是点; 而测试工程师一般是广度遍历,关注的是面;
基本上看,全部都覆盖到了。。但人的时间是有限的,确定不会这样逐个介绍,所以调了点占做比较重要的;
除了功能测试,还要性能测试、稳定性测试、全链路压测、故障切换测试、动态集群容量伸缩测试、服务降级测试和安全渗透测试;
对测试开发工程师来讲,须要应用容器的场景就更多了。好比,目前主流的 Selenium Grid 就已经提供了官方 Docker 版本,能够直接以容器的方式创建测试执行环境,也能够很方便地在 Pivotal Cloud Foundry 和 Google Cloud Platform 等云计算平台上快速创建测试执行环境。
基于 Docker 的 Selenium Grid 大大减轻了批量虚拟机节点上 Web Driver、浏览器版本和守护者进程版本等升级维护的工做量。
测试开发工程师还能够经过 Docker Image 的形式,提供某些测试工具,而不是以传统的安装包或者 JAR 文件的形式,能够实现测试工具开箱即用。
对于云计算的学习,侧重点应该是如何使用云提供的基础设施以及服务;
能够尝试用云服务去部署本身的应用,同时还能够结合云平台提供的各种服务(配置服务,数据库服务)和你的应用作集成;
DevOps强调的是,开发、测试和运维等组织团队之间,经过高效自动化工具的写做和沟通,来完成软件的全声明周期管理,从而实现更频繁持续交付高质量的软件,根本目的是要提高业务的交付能力;
DevOps的具体表现形式能够是工具、方法和流水线,但起更深层次的内涵仍是在思想方法,以敏捷和精益为核心,经过发现问题,以系统性的方法或者工具来解决问题,从而实现持续改进;
对于 DevOps,我建议的学习路径是,你能够从深刻掌握 Jenkins 之类的工具开始,到熟练应用和组合各类 plugin 来完成灵活高效的流水线搭建,以后再将更多的工具逐渐集成到流水线中以完成更多的任务。
从测试工程师的角度来说,若是你可以掌握前端开发技术,也就意味着你能够更高效地作前端的测试,更容易发现潜在缺陷。同时,你还能够本身构建测试页面,来完成各种前端组件的精细化测试,大大提升测试覆盖率和效率。
关于前端技术的学习路径,一般你首先须要掌握最基本的 JavaScript、CSS、JQuery 和 HTML5 等知识,而后再去学习一些主流的前端开发框架,好比 Angular.js、Backbone.js 等。 固然如今的 Node.js 的生态圈很是发达,你若是可以掌握 Node.js,那么不少东西实现起来均可以驾轻就熟。
软件测试工程师须要掌握很是多的非测试专业知识,包括:网站架构、容器技术、云计算技术、DevOps 思惟,以及前端开发技术的核心知识以及实践。
传统产品跟互联网产品的研发自己最大的不一样就是“快”;
发布周期的巨大差别决定了,传统软件产品的测试策略必然不适用于互联网产品的测试,二者的测试策略必然在测试执行时间和测试执行环境上有巨大差别;
发布流程一般包含了静态代码扫描、单元测试、编译、打包、上传、下载、部署和测试的全流程;
那如何在保证测试质量和测试覆盖率的前提下,有效缩短测试执行时间?
传统软件产品的测试策略,就以下图的金字塔模型,在很长一段时间内,该金字塔模型都被认为是测试策略设计的最佳实践;
金字塔最底部是单元测试,属于白盒测试的范畴,通常由开发工程师本身完成,因为越早发现缺陷其修复成本越低,全部传统软件产品的测试策略提倡对单元测试的高投入;
金字塔中部是API测试,主要针对的是各模块的暴露接口,一般采用灰盒测试方法;
灰盒测试方法是介于白盒测试和黑盒测试之间的一种测试技术,其核心思想是利用测试执行的代码覆盖率来知道测试用例的设计;
以API接口测试为例,首先以黑盒方式设计如何调用API的测试用例,同时在测试执行过程当中统计代码覆盖率,而后根据代码覆盖率状况来补充更多、更有针对性的测试用例;
金字塔最上层的是GUI测试,也成为端对端(E2E,end-to-end)测试,是最接近软件真是用户使用行为的测试类型;
一般是模拟真是用户使用软件的行为,即模拟用户在软件界面上的各类操做,并验证这些操做对应的结果是否正确;
GUI测试的优势是,可以实际模拟真实用户的行为,直接验证软件的商业价值; 缺点是执行的代码比较大,既然使用自动化,用例的维护和执行代码依然很大;
另外,GUI测试的稳定性问题,是长期以来阻碍GUI测试发展的重要缘由; 即时采用了不少诸如retry机制以及异常场景恢复机制等方式,GUI测试的随机失败率高居不下;
对于互联网产品来讲,金字塔模型已经不适用了;
互联网产品的上线周期,决定GUI测试不能大范围开展;
所以,互联网产品的GUI测试一般采用手工为主,自动化为辅的测试策略;
手工测试每每利用探索性测试思想,针对新开发或者新修改的界面功能进行测试,而自动化测试的关注点主要放在相对稳定且核心业务的基本功能验证上;
因此,GUI的自动化测试每每只覆盖最核心且直接影响主营业务流程的场景;
从用例数量来看,传统软件的GUI测试是重量级的,由于测试周期长;而互联网的GUI测试是轻量级的,毕竟上线周期过短了;
对于互联网产品,把测试重点放在API测试上,才是最明智的选择;
互联网产品的这些特性决定了,API 测试能够实现良好的投入产出比,所以应该成为互联网产品的测试重点。这也就是为何互联网产品的测试策略更像是个菱形结构的缘由。
下图就是菱形的测试策略,遵循“重量级 API 测试,轻量级 GUI 测试,轻量级单元测试”的原则;
互联网产品一般会分为应用层和后端服务,后端服务又能够进一步细分为应用服务和基础服务;
后端基础服务和一些公共应用服务相对稳定,并且对于系统全局来讲是“牵一发而动全身”,因此后端服务颇有必要开展全面的单元测试; 而对于变更很是频繁的客户端应用和非公用的后端应用服务,通常不多会去作单元测试。
另外,对于一些核心算法和关键应用,好比银行网关接口,第三方支付集成接口等,也要作比较全面的单元测试。
总结来说,互联网产品的全面单元测试只会应用在那些相对稳定和最核心的模块和服务上,而应用层或者上层业务服务不多会大规模开展单元测试。
小结
传统软件一般采用金字塔模型的测试策略,而如何的互联网产品每每采用菱形模型;
菱形模型有如下4个关键点:
本章主要介绍自动化的思想及selenium的原理,这里很少说,感兴趣的同窗可点击这里阅读;
问题:测试脚本中既有测试数据又有测试操做,全部操做都集中在一个脚本
测试输入数据单独保存,测试脚本的输入数据采用变量代替;
常见的就是csv,每行读取;
复制代码
这种模式叫数据驱动;
好处在于:
页面对象模型”的核心理念是,以页面为单位来封装页面上的控件以及控件的部分操做。
而测试用例使用页面对象来完成具体的界面操做。
复制代码
操做函数的粒度是指,一个操做函数到底应该包含多少操做步骤才是最合适的;
复制代码
通常会以完成一个业务流程为主线,抽离出高内聚低耦合
的操做步骤集合;
业务流程抽象是,基于操做函数的更接近于实际业务的更高层次的抽象方式。
基于业务流程抽象实现的测试用例每每具备较好的灵活性,能够根据实际测试需求方便地组装出各类测试用例;
复制代码
业务流程的核心思想是,从业务的维度来指导测试业务流程的封装;
从建立的技术手段上来说,建立测试数据的方法主要分为三种:
从建立的时机来说,建立测试数据的方法主要分为两种:
GUI 测试数据自动生成,主要是基于测试输入数据的类型以及对应的自定义规则库实现的,而且对于多个测试输入数据,能够基于笛卡尔积来自动组合出完整的测试用例集合;
无头浏览器,就是在执行过程当中看不到运行的界面,优势在于速度快,简化环境搭建;
页面对象自动生成技术,基本思路是,不用再手工维护Page Class
了,只须要提供 Web
的 URL
,就会自动生成这个页面上全部控件的定位信息,并自动生成 Page Class
,目前暂无开源,商业工具较多;