1.一个优秀的软件测试人员具备的素质
- 综合能力
- 沟通能力
- 快速学习的能力
- 开发能力
- 文字能力
- 掌握自动化测试技术
- 掌握自动化测试技术,可以把你从大量重复性劳动中解脱出来,这样可以把更多的经历都花在更多类型的测试上
- 优秀的测试用例设计能力
- 测试用例设计能力是指,无论对于什么类型的测试,都能够设计出高效的发现缺陷,保证产品质量的优秀设计用例
如何提高测试用例设计的能力
1、掌握设计测试用例的方法
2、积累,总结
3、阅读好的测试用例设计案例
- 探索性思维
- 责任感
2. 衡量软件测试结果的依据–需求
需求的概念
满足用户期望或正式规定文档(合同、标准、规范)所具有的条件和权能,包含用户需求和软件需求)
用户需求:可以简单理解为甲方提出的需求,如果没有甲方那么就是终端用户使用产品时必须要完成的任务。该需求一般比较简略。
软件需求:或者叫功能需求,该需求会详细描述开发人员必须实现的软件功能。
大多数公司在进行软件开发的时候会把用户需求转化为软件需求,开发人员和测试人员工作的直接依据就是软件需求。软件需求是测试人员进行测试工作的基本依据。
3.软件错误(bug)的概念
当且仅当规格说明是存在的并且正确,程序与规格说明之间的不匹配才是错误
当规格说明书没有提到的功能,判断标准以最终用户为准:当程序没有实现其最终合理预期的功能要求时,就是软件错误。
4.软件的生命周期
软件生命周期是指从软件产品的设想开始到软件不再使用而结束的时间。
软件的生命周期可以分为6个阶段,即需求分析、计划、设计、编码、测试、运行维护。
5.开发模型
瀑布模型(Waterfull Mode)
优点:
1、强调开发的阶段性;
2、强调早期计划及需求调查;
3、强调产品测试。
缺点:
1、依赖早期进行的惟一一次需求调查,不能适应需求的变化;
2、由于是单一流程,开发中的经验教训不能反馈应用于本产品的过程;
3、风险往往迟至后期的测试阶段才显露,因而失去及早纠正的机会。
使用的项目:小型的项目
在瀑布模型中,测试阶段处于软件实现后,这意味着必须在代码完成后有足够的时间预留给测试活动,否则将导致测试不充分,从而把缺陷直接遗留给用户。
螺旋模型(Spiral Model)
优点:
1、强调严格的全过程风险管理
2、强调各开发阶段的质量
3、提供机会检讨项目是否有价值继续下去
缺点:
1、引入非常严格的风险识别、风险分析和风险控制,这对风险管理的技能水平提出了很高的需求,这需要人员、资金和时间的投入
适用项目:这对于那些规模庞大、复杂度高、风险大的项目尤其适合。这种迭代开发的模式给软件测试带来了新的要求,他不允许有一段独立的测试时间和阶段,测试必须跟随开发的迭代而迭代。因此回归测试的重要性就不言而喻了。
增量、迭代
增量是逐块建造的概念,例如画一幅人物画,增量开发就是先画人的头部,再画身体,再画手脚……
迭代是反复求精的概念,同样是画人物画,迭代就是先画整体轮廓,再勾勒出基本雏形,再细化、着色。
敏捷
个体与交互重于过程和工具(个体之间面对面沟通)
可用的软件重于完备的文档(文档:开发文档、软件需求文档)
客户协作重于合同谈判(时刻关注了解用户需求)
响应变化重于遵循计划(拥抱变化)
在每对对比中,后者并非全无价值,但我们更看重前者
scrum
三大角色:
- product owner(产品经理)
产品经理负责整理user story(用户故事),定义其商业价值,对其进行排序,指定发布计划,对产品负责。 - scrum master(项目经理)
项目经理负责召开各种会议,协调项目,为研发团队服务。 - team(研发团队)
研发团队则由不同技能的成员组成,通过紧密协同,完成每一次迭代的计划。
敏捷中的测试
挑战一:轻文档
挑战二:快速迭代
- 测试工作的核心内容是没有变的,就是不断地找Bug,只是要调整好自己的心态,一切以敏捷的原则为主
- 测试人员不能依赖文档,测试用例作用减弱,更多的采用思维导图,探索性测试(强调自由度,设计和执行同时执行,根据测试结果不断调整计划)、自动化测试
- 敏捷讲求合作,在敏捷项目组中,测试人员应该更主动些,多向开发人员了解需求,讨论设计,一起研究Bug出现的原因
五个重要会议
- 发布计划会议
- 迭代计划会议
- 每日例会
- 昨天做了什么
- 今天做什么
- 期间遇到了什么问题
- 演示会议
- 回顾会议
软件测试V模型
特点:左边是开发,右边是测试(类似于瀑布模型)
优点:测试被划分成许多类型
缺点:测试人员介入太晚,发现问题时机太晚
软件测试W模型
特点:开发一个V,测试一个V,测试与开发是同步进行的。
优点:测试人员尽早介入了需求,有利于尽早地发现问题
缺点:测试人员和开发人员一定程度上还是串行的;需求文档在项目最初就已经确定,不能拥抱变化。
软件声明周期:需求分析->计划->设计->编码->测试->运行维护
软件测试的生命周期:需求分析->测试计划->测试设计、测试开发->测试执行->测试评估
- 需求分析
需求是否完整,需求是否正确 - 测试计划
确定软件由谁测试
什么时候开始测试,什么时候结束测试
测试哪些模块 - 测试设计、测试开发
写测试用例(手工测试用例,自动化测试用例) - 测试执行
执行测试用例 - 测试评估
测试人员产生测试报告
如果描述一个Bug
- 发现问题的版本
开发人员需要知道出现问题的版本,才能够获取对应版本的代码来重现故障。并且版本的表示也有利于统计和分析每个版本的质量。 - 问题出现的环境
环境分为硬件环境和软件环境,如果是web项目,需要描述浏览器版本,客户机操作系统等,如果是app项目,需要描述机型、分辨率、操作系统版本等。详细的环境描述有利于故障的定位。 - 错误重现的步骤
描述问题重现的最短步骤 - 预期行为的描述
要让开发人员知道怎么样才是正确的,尤其要以用户的角度来描述程序的行为是怎样的。如果是宜居需求提出的故障,即写明需求的来源是最好的。 - 错误行为的描述
描述错误的现象。crash等可以上传log,UI问题可以有截图 - 其他
某些公司会有一些其他的要求,例如故障的分类:功能故障,界面故障等。有些有优先级的分类,严重影响测试需要开发人员优先修改的,可以设置优先级为高 - 不要把多个bug放到一起
在无法确认是同一段代造成的故障时,不要将bug放在一起提交。
如何定义bug的级别
- Bloker(崩溃)
阻碍开发或测试工作的问题;造成系统崩溃、四级、死循环,导致数据刻苦数据丢失,与数据库连接错误,主要功能丧失,基本模块丧失等问题。如:代码错误、死循环、数据库发生死锁、重要的一级菜单功能不能使用 - Crirical(严重)
系统主要功能部分丧失,数据库保存调用错误、用户数据丢失,以及功能菜单不能使用但------功能的测试。功能设计与需求严重不符,模块无法启动或调用,程序重启、自动退出,关联成功续建调用冲突,安全问题、稳定性等。如:软件中数据保存后数据库中显示错误,用户所要求的功能丧失,程序接口错误,数值计算统计错误等。 - Major(一般)
功能没有完全实现但是不影响使用,功能菜单存在缺陷但不会影响系统稳定性,如:操作时间长、查询时间长、格式错误、边界条件错误、删除没有确认框、数据库表中字段过多等(该问题实际测试中存在最多) - 次要
界面、性能缺陷,建议类问题,不影响功能的执行,可以优化性能的方案等,如:错别字、界面格式不规范,界面显示重叠、不该显示的要隐藏、描述不清楚、提示语丢失、文字排列不整齐、光标位置不正确,用户体验敢不好,可以优化性能的方案(此类问题在测试初期较多,优先程度较低;在测试后期出现较少,应及时处理)
bug的生命周期
在测试过程中与开发产生争执
好好沟通
①确保操作没有问题,确保对需求的理解没有问题
②站在用户角度考虑问题
③不光要发现问题,最好是提出解决问题的方案
④第三方会议
开会之前:一定明确问题是什么、问题产生原因、解决方案是什么?
开会之后:问题要不要解决,什么时候解决,谁去解决?
如何开始第一次测试
- 充分理解需求
文档(产品文档+技术文档) - 确定测试计划
- 执行测试
bug开发修复之后一定要验收 - 项目上线+维护
如何发现更多的bug
- 软件测试同样存在二八原则,80%的故障集中于20%的模块,如果某部分问题较多,加强测试的广度和深度
- 开发人员也存在二八原则,80%的故障集中于20%的开发人员,如果某些开发人员的bug较多,加强他开发模块的测试广度和深度
- 多进行逆向思维和发散性的思维
- 不要局限于用例和需求文档
- 尽早介入项目,不要等到开发地差不多了再介入项目
6.软件测试用例
测试用例的好处
- 提高测试效率,节省测试时间
- 测试用例是自动化测试用例的前提
测试用例的设计方法
黑盒测试
- 测试用例的基本要素
- 测试环境
- 操作步骤
- 测试数据
- 预期结果
- 基于需求的设计方法
需求文档->梳理需求->针对文档设计测试用例
- 等价类
- 无效等价类
- 有效等价类
从等价类中选出一个测试用例,通过就代表整个类通过,这样就可以用较少的测试用例达到尽量多的功能覆盖,解决了不能穷举测试的问题 - 等价类思想设计测试用例步骤
- 1、充分理解需求
6~15位 - 2、划分有效等价类、无效等价类
- 3、从有效等价类抽取其中一个数据设计测试用例;从无效等价类抽取其中一个设计测试用例
-
边界值
-
上点 :边界上的点
-
内点:边界内的点
-
离点:边界值附近的一个点(闭区间区间外距离上点最近的点,开区间区间内距离上最近的点)
-
边界值设计测试用例方法
-
1、充分理解需求
6~15位 -
2、找边界
-
3、针对边界点设计测试用例
通常会结合等价类来一起设计测试用例
-
-
因果图
判定表(Decision table)是另一种表达逻辑判断的工具
关系-
关系
- 与:所有都满足
- 或:满足一个
- 非:条件为假,结果才为真
- 恒等:小可以推大(女人->人)
-
设计测试用例
-
1、分析所有可能的输入和输出
-
2、找出输入与输出之间的对应关系
-
假设业务单据的处理规则为:“淘宝618活动,订单已经提交,订单合计金额大于300元或有红包,则优惠”。
输入:订单已提交,订单金额>300,有红包
输出:优惠,不优惠
- 订单已提交,金额大于300,有红包,优惠
- 订单已提交,金额大于300,没有红包,优惠
- 订单已提交,金额小于300,有红包,优惠
- 订单已提交,金额小于300,没有红包,不优惠
- 订单不提交,金额大于300,有红包,不优惠
- 订单不提交,金额大于300,没有红包,不优惠
- 订单不提交,金额小于300,有红包,不优惠
- 订单不提交,金额小于300,没有红包,不优惠
- 正交排列
正交实验设计是研究多因素多水平的一种设计方法,1它是根据正交性,由试验因素的全部水平组合中挑选出部分有代表性的点进行试验,通过对这部分试验结果的分析,了解全面试验的情况,找出最优的水平组合,正交试验设计是一种基于正交表的、高效率、快速、经济的试验- 正交表的两条性质
- 每一列中各数字出现的次数都一样多
- 任何两列中的各有序数对出现的次数都一样多
- 正交法设计测试用例的步骤
- 1、有哪些因素(变量)
- 2、每个因素有哪几个水平(变量的取值)
- 3、选择一个合适的正交表
- 4、把变量的值映射到表中
- 5、把每一行的各因素水平的组合作为一个测试用例
- 6、加上你认为可以并没有在表中出现的用例组合
- 正交表的两条性质
继续以注册为需求,姓名、邮箱、密码、确认密码、验证码必须全部输入才能进行注册
- 因素:姓名、邮箱、密码、确认密码、验证
- 水平:填写、不填写
- 在 excel 表格中,把因素数和水平数写好,每个因素数都有两种不同的水平数。
- 直接复制到 allparis 工具的目录下,创建个的 txt 文本文件,然后保存
- 打开 cmd 窗口,进入到该目录下,输入命令 allpairs.exe 0204.txt>0204_result.txt
- 增补测试用例
姓名、邮箱、密码、确认密码、验证码都不填写
- 场景设计法
- 错误猜测法
- 如何模拟弱网
可以借助fiddler、chales
- 如何模拟弱网
-
接口如何测试
- 借助postman
-
测试用例设计万能公式
-
水杯测试用例
7.测试的分类
按照测试对象分
-
界面测试
页面测试(简称UI测试),指按照界面的需求(一般是UI设计稿)和界面的设计规则,对我们软件界面所展示的全部内容进行测试和检查,一般包括如下内容- 验证界内容的完整性、一致性、准确性友好性。比如界面内容对屏幕大小的自适应,换行,内容是都全部清晰展示
- 验证整个页面布局和排版是否合理,不同板块字体的设计,图片的展示是否符合需求
- 对页面不同控件的测试,比如,对话框,文本框,滚动条,选项按钮是否可以正常使用,有效和无效的状态是否设计合理
- 页面的布局和色调符合当下时事的发展
-
可靠性测试
可靠性即可用性,是指系统正常运行的能力或者程度,一般用正常向客户提供软件服务的时间占总时间的百分比- 可靠性 = 正常运行时间/(正常运行时间+非正常运行时间)* 100%
- 系统非正常的运行时间可能是由于硬件,软件,网络故障或其他任何因素(如断电)造成的,这些因素能让系统停止工作,或者连接中断不能被访问,或者性能急剧降低导致不能使用软件现有的服务等
- 可用性指标一般达到4个9或5个9
-
容错性测试
容错性测试是指系统能够处理异常,用户的错误操作而不至于系统崩溃,从而能够提高系统的可用性,容错性测试包含以下方面: -
输入异常数据或进行异常操作,以检验系统的保护性,如果系统的容错性好,系统只给出提示或内部消化掉,而不会导致系统出错甚至崩溃
比如数据级测试、校验测试、环境容错性测试、界面容错性测试 -
灾难恢复性手段,通过各种手段,让软件强制性的发生故障,然后验证系统以保存的用户数据是否丢失,系统和数据是否能尽快恢复
-
文档测试
在实际的测试中,最常见的是用户文件的测试,例如:手册说明书等。也会有一些公司对需求文档进行测试,来保证需求文档的质量 -
文档测试的关注点
- 文档的术语
- 文档的完整性
- 文档的一致性
- 文档的易用性
-
兼容性测试
兼容性测试需求是指明确要测试的兼容环境,考虑软、硬件的兼容,就软件兼容来说,主要考虑以下几个方面- 系统自身版本的兼容,用户已有数据的兼容,数据兼容是重中之重,对用户来说,数据是最优价值的
- 测试与应用环境的兼容性,比如操作系统,应用平台,浏览器的兼容
- 测试与第三方系统以及第三方数据的兼容性
-
易用性测试
易用性包含七个要素:符合标准和规范,直观性,一致性,灵活性,舒适性,正确性和实用性 -
标准型和规范性
对于现有的软件运行平台,通常其UI标准已经不知不觉地被确立了,成为大家的共识。所以用户界面上的各种信息应该符合规范和习惯,否则用户使用起来会不舒适,并得不到用户的认可。测试人员需要把标准规范,习惯不一致的问题报告为缺陷。 -
直观性
用户界面的直观性,要求软件功能特性易懂、清晰、用户界面布局合理,对操作的响应在用户的预期之中,比如数据统计结果用报表的形式展示清晰直观;现在主流的很多搜索引擎和日历的设计也有直观性的特点 -
灵活性
软件可以有不同的选项以满足不同使用习惯的用户来完成相同的功能。但是灵活性的设计要把握好度,不然可能会增加软件设计的复杂度,和程序实现的难度
例如:手机键盘有九宫格和全键盘,还支持手写,满足了不同用户的需求
-
舒适性
舒适性主要强调界面友好,美观,操作过程顺畅,色彩运用恰当,按钮的立体感等。 -
安装卸载测试
应用的安装和卸载在任何一款APP中都属于是最基本的功能。一旦出错,就属于优先级为既要Critical的缺陷。主要考虑一下方面 -
软件不同的安装和卸载方式
-
应用是否可以在不同的系统、版本下安装(安装兼容性)
-
安装或者卸载过程中是否可以手动暂停,或者取消
-
安装空间不足的时候系统是否有提示
-
是否可以正常的卸载,以及应用软件的各种卸载方式
-
卸载和安装过程中出现环境问题,软件是否可以正常并且合理的应对,比如四级、断电、断网等
-
安全测试
安全性是指信息安全,是指计算机系统或网络保护用户数据隐私,完整,保护数据正常传输和抵御黑客,病毒攻击的能力。安全测试属于非功能性测试很重要的一个方面,系统常见的安全楼栋和威胁如下: -
输入域,如输入恶性或者带有病毒的脚本或长字符串
-
代码中的安全性问题,如SQL/XML注入\XSS漏洞
-
不安全的数据存储或者传递
-
数据文件,邮件文件,系统配置文件等里面有危害系统的信息或者数据
-
有问题的访问控制,权限分配等
-
假冒ID:身份欺骗
-
篡改,对数据的恶意修改,破坏数据的完整性
安全性测试的方法有代码评审,渗透测试,安全运维等,常用的静态安全测试工具有,Coverity,IBM Appscan Source,HPFortify,常用的动态安全测试有OWASP的ZAP,HP WebInspect等。其中静态安全测试是常用的安全性测试的方法。
- 性能测试
要进行软件产品的性能测试,要对产品的性能需求进行分析,然后基于系统的性能需求和系统架构,完成性能测试的设计和执行,最后要进行持续的性能调优。常见的性能问题如下: - 资源泄漏
- 资源瓶颈
- 线程死锁,线程阻塞
- 查询速度慢或效率低
- 受外部系统影响越来越大
衡量一个系统性能好坏的关键性指标有,用户响应时间,事务平均响应时间(TPS),吞吐率,每秒点击次数,内存和CPU使用率
- 内存泄漏测试
造成内存泄漏的原因有很多,最常见的有以下几种 - 分配完内存之后忘了回收
- 程序写法有问题,造成没办法回收(如死循环造成无法执行到回收步骤)
- 某些API函数的使用不正确,造成内存泄漏
内存泄漏的检测方法
- 人工静态法:代码走读,人工查找未被回收的内存
- 自动工具法:借助相应测试内存泄漏的工具,如Visual Leak Detector,记录每次内存分配,清除告诉用户内存是如何泄漏的
按照是否查看代码划分
- 黑盒测试
黑盒测试就是在完全不考虑程序逻辑和内部结构的情况下,检查系统功能是否按照需求规格说明书的规定正常使用、是否能适当的接收输入数据而输出正确的结果,满足规范需求
所以黑盒测试又被称为数据驱动测试,只注重软件的功能 - 黑盒测试的优点
- 不需要了解程序内部的代码以及实现,不关注软件内部的实现
- 从用户角度出发设计测试用例,很容易的知道用户会用到哪些功能,会遇到哪些问题,锻炼测试人员的产品思维
- 测试用例是基于软件需求开发文档,不容易一楼软件需求文档中需要测试的功能
黑盒测试的缺点是不可能覆盖所有代码
黑盒测试用到的测试方法有:等价类、边界值、因果图、场景法、错误猜测法等
- 白盒测试
- 白盒测试又称为结构测试或逻辑测试,它一般用来分析程序的内部结构,针对程序的逻辑结构来设计测试用例进行测试
- 白盒测试的测试目的是,通过检查软件内部的逻辑结构,对软件中的逻辑路径进行覆盖测试;在程序不同地方设立检查点,检查程序的状态,以确定实际运行状态与预期是否一致
- 主要包含六种测试方法:语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、条件组合覆盖、路径覆盖
- 白盒测试缺点:关注的是代码逻辑,对业务功能有一定的忽视
- 白盒测试优点:代码覆盖率较高
- 灰盒测试
灰盒测试,是介于白盒测试与黑盒测试之间的一种测试,灰盒测试多用于集成测试阶段,不仅关注输出,输入的正确性,同时也关注程序内部的情况
按照开发阶段划分
- 单元测试
单元测试是对软件组成单元进行测试,其目的是检验软件基本组成单位的正确性。测试的对象是软件设计的最小单位:模块。又称为模块测试- 测试阶段:编码后或者编码前(TDD)
- 测试对象:最小模块
- 测试人员:白盒测试工程师或开发工程师
- 测试依据:代码和注释+详细设计文档
- 测试方法:白盒测试
- 测试内容:模块接口测试。局部数据结构测试,路经测试,错误处理测试,边界测试。
- 集成测试
集成测试也称为联合测试(联调)、组装测试,将程序模块采用适当的集成策略组装起来,对系统的接口及集成后的功能进行正确性检测的测试工作。集成主要目的是检查软件单位之间的接口是否正确。- 测试阶段:一般单元测试之后进行
- 测试对象:模块间的接口
- 测试人员:白盒测试工程师或开发师
- 测试依据:单元测试的模块+概要设计文档
- 测试方法:黑盒测试与白盒测试相结合
- 测试内容:模块之间数据传输、模块之间功能冲突、模块组装功能正确性、全局数据结构、单模块缺陷对系统的影响
- 回归测试
回归测试是指修改了旧代码后,重新进行测试以确认修改没哟兦新的错误或导致其他代码产生错误
在整个软件测试过程中占有很大的工作量比重,软件开发的各个阶段都会进行多次回归测试。随着系统的庞大,回归测试的成本越来越大,通过选择正确的回归测试策略来改进回归测试的效率和有效性是很有意义的。(采用自动化测试可以提高检测效率) - 冒烟测试(在系统测试之前)
冒烟测试的对象是每一个新编译的需要正式测试的软件版本,目的是确认软件主要功能和核心流程正常,在正式进行系统测试之前执行。冒烟测试一般在开发人员开发完毕后提交给测试人员来进行测试时,先进行冒烟测试,保证基本功能正常,不阻碍后续的测试 - 系统测试
购买手机都会有一个合格标签,在出厂前手机厂会将某型号手机上的功能全部测试一遍,包括手机硬件本身,手机上自带的APP
- 将软件系统看成一个系统的测试。包括对功能、性能以及软件所运行的软硬件环境进行测试
- 测试阶段:集成测试通过之后
- 测试对象:整个系统(软、硬件)
- 测试人员:黑盒测试工程师
- 测试依据:需求规格说明文档
- 测试方法:黑盒测试
- 测试内容:功能、界面、可靠性、易用性、性能、兼容性、安全性
- 验收测试
验收测试是部署软件之前的最后一个测试操作,它是技术测试的最后一个极端,也称为交付测试。验收测试的目的是确保软件准备就绪,按照项目合同、任务书,双方约定的验收依据文档,向软件购买都展示该软件系统满足原始需求 - 测试阶段:系统测试通过之后
- 测试对象:整个系统(包括软硬件)
- 测试人员:主要是最终房或者需求方
- 测试依据:用户需求、验收标准
- 测试方法:黑盒测试
- 测试内容:同系统测试(功能…各类文档等)
按照实施组织划分
- α测试
- β测试
- 第三方测试
- α测试和β测试的区别
- 环境:α测试是在公司内部进行测试,β测试环境不确定
- 测试人员类型:α测试是公司内部人员,β测试是用户
- 测试人员数量: α测试人员数量较少,β测试人员较多
- 阶段:α测试在β测试之前测试
- 测试周期:α测试周期较短,β测试周期较长
按照是否运行代码划分
- 静态测试
所谓静态测试,就是不实际运行被测软件,而只是静态地检查程序代码、界面或文档中可能存在的错误的过程。不以测试数据的而是对测试对象的分析过程,仅通过分析或检查源程序的设计、内部结构、逻辑、代码风格和规格等来检查程序的正确性 - 动态测试
按照是否手工划分
-
手工测试
手工测试就是由人一个一个的去输入用例,然后观察结果,和机器测试相对应,属于比较原始但是必须的一个步骤。总结优缺点:- 优点:自动化无法替代探索性测试、发散思维结果的测试
- 缺点:执行效率慢,量大易错
-
自动化测试
自动化测试就是把以人为驱动的测试行为转化为机器执行的一种过程
自动化测试比如:功能测试自动化、性能测试自动化、安全测试自动化
自动化测试按照测试对象来分,还可以分为接口测试、UI测试等。接口测试的ROI(产出投入比)要比UI测试高
自动化实施步骤:
1、完成功能测试,版本基本稳定
2、根据项目特性,选择适合项目的自动化工具,并搭建环境
3、提取手工测试的测试用例转换为自动化测试的用例
4、通过工具、代码实现自动化的构造输入,自动检测输出结果是否符合预期
5、生成自动测试报告
6、持续改进,脚本优化
按照地域划分
-
国际化测试
软件的国际化和软件的本地化是开发面向全球不同地区用户使用的软件系统的两个过程。而本地化测试和国际化测试则是针对这类软件产品进行的测试。
测试要点: -
1、本地化后的软件在外观上与原来版本是否存在很大的差异,外观是否整齐、不走样
-
2、是否对所有页面元素都进行了本地化处理,包括对话框、菜单、工具栏、状态栏、提示信息(包括声音的提示)、日志等
-
3、在不同的屏幕分辨率下界面是否正常显示
-
4、是否存在不同的字体大小,字体设计是否恰当
-
5、日期、数字格式、货币等是否能适应不同国家的文化习俗
-
6、排序的方式是否考虑了不同语言的特点
-
7、在不同的国家采用不同的度量单位,软件是否能自适应和转换
-
8、软件是否能在不同类型的软件上正常运行,特别是在当地市场上销售的流行硬件上
-
9、软件是否能在windows或者其他操作系统的当地版本上正常运行
-
10、联机帮助和文档是否已经翻译,翻译后的链接是否正常。正文翻译是否正确、恰当,是否有语法错误。
软件本地化和国际化测试是一个综合了翻译行业和软件测试行业的测试类型,它要求测试人员具备一定的翻译能力、语言文化,同时具备测试人员的基本技能 -
本地化测试
1.什么是自动化测试
自动化测试介绍
自动化测试指软件测试的自动化,在预设状态笑运行程序或者系统,预设条件包括正常和异常,最后评估运行结果。将人为驱动的测试行为转化为机器执行的过程。
自动化测试包括UI自动化,接口自动化,单元测试自动化。按照这个金字塔模型来进行自动化测试规划,可以产生最佳的自动化测试产出投入比,可以用较少的投入获得很好的效益
单元测试
最大的投入应该在单元测试上,单元测试运行的效率也更加高
java的单元测试是junit
接口自动化测试
UI自动化测试
2.selenium3介绍
2.1 selenium是什么
selenium是用来做web自动化测试的框架
2.2 selenium特点
支持各种浏览器,支持各种平台支持各种语言,有丰富的API
2.3 selenium工作原理
2.3.1 webdriver API
-
元素的定位
css选择语法
- id选择器
#id - 类选择器
.classname - 标签选择器
标签名 - 后代选择器
标签名 后代标签
- id选择器
-
name定位
-
XPath定位
- 绝对路径
/html/head/title(不常用) - 相对路径
-
相对路径+索引
//form/span[1]/input
注意:这里的索引是从1开始的 -
相对路径+属性值
//input[@class=“s_ipt”] -
相对路径+通配符
//* [ @ * = " s_ipt "] -
相对路径+文本匹配
//a[text()=“新闻”]
-
- 绝对路径
操作测试对象
webdriver中比较常用的操作对象的方法有下面几个
- click点击对象
- sendKeys在对象上模拟按键输入
- clear清除对象输入的文本内容
- submit提交
如果点击的元素放在form标签中,此时使用submit实现的效果和click是一样的;
如果点击的元素放在非form标签中,此时使用submit会报错 - text用于获取元素的文本信息
- getAttribute获取元素的属性
添加等待
- sleep休眠
import time
time.sleep(3)
- 隐式等待
webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.Days);//等待三天
假设等待三天时间
隐式等待最长等待3天时间,如果三天内获取到了页面上的元素,就执行下面的代码
如果等待三天时间还是没有找到这个元素此时报错
- 显示等待
private static void test() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--romote-allow-origins=*");//允许所有的请求
WebDriver webDriver = new ChromeDriver(options);
//打开百度首页
webDriver.get("https://www.baidu.com");
//判断元素是否可以被点击
WebDriverWait wait = new WebDriverWait(webDriver,1);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@id=\"bottom_layer\"]/div/p[9]/span")));//等待1s括号里的值还是为假就报错
}
获取信息
打印title
- getTitle();
- getCurrentUrl()
- getAttribute()
浏览器的的操作
- 浏览器最大化
browser.maxmize_window()
- 设置浏览器宽、高
browser.set_windows_size(width,height)
- 浏览器的前进、后退、刷新
webDriver.navigate().forward();
webDriver.navigate().back();
webDriver.navigate().refresh();
- 控制浏览器滚动条
将浏览器滚动条滑倒最顶端
document.documentElement.scrollTop=0
将浏览器滚动条滑倒最底端
document.documentElement.scrollTop=10000
键盘事件
//control+A
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A");
sleep(2000);
//control+X
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"x");
sleep(2000);
//control+V
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"v");
鼠标事件
ActionChains(driver)
生成用户的行为。所有的行动都存储在actionchains对象。通过perform()存储的行为。
perform()
执行所有存储的行为
ActionChains类
- contextClick()
- doubleClick()
- moveToElement()
private static void test09() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("520");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(2000);
//找到图片按钮
WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-pic"));
Actions actions =new Actions(webDriver);
sleep(2000);
//点击
webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-pic")).click();
// actions.moveToElement(webElement).click().perform();
右击
// actions.moveToElement(webElement).contextClick().perform();
双击
// actions.moveToElement(webElement).doubleClick().perform();
//拖动
// actions.moveToElement(webElement).doubleClick().dragAndDrop();
}
多层框架/窗口定位
- 定位一个frame: webDriver.switchTo().frame(name_or_id_or_frame_element);
- 定位一个窗口window:webDriver.switchTo().window(name_or_id_or_frame_element)
多层框架
private static void page01() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("http://127.0.0.1:3000/page01.html");
List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
for(int i = 0;i<webElements.size();i++)
{
if(webElements.get(i).getAttribute("type").equals("checkbox")){
webElements.get(i).click();
}
else {
System.out.println(webElements.get(i).getAttribute("type"));
}
}
}
private static void page02() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("file:///C:/Users/ASUS/Desktop/page02.html");
//把当前定位的主体切换到了frame里
webDriver.switchTo().frame("f2");
webDriver.findElement(By.cssSelector("body > div > div > a")).click();
}
下拉框处理
private static void page03() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("file:///C:/Users/ASUS/Desktop/page03.html");
WebElement webElement =webDriver.findElement(By.cssSelector("#number"));
Select select = new Select(webElement);
sleep(2000);
select.selectByIndex(2);
// select.selectByValue("2");
}
运行结果:可以看到最后index是从0开始的
alert、confirm、prompt的处理
private static void page04() throws InterruptedException {
WebDriver webDriver= new ChromeDriver();
webDriver.get("file:///C:/Users/ASUS/Desktop/page04.html");
webDriver.findElement(By.cssSelector("button")).click();
sleep(2000);
//alert弹窗取消
webDriver.switchTo().alert().dismiss();
sleep(2000);
//点击按钮
webDriver.findElement(By.cssSelector("button")).click();
sleep(2000);
//输入
webDriver.switchTo().alert().sendKeys("Maria");
sleep(2000);
//alert弹窗的确认
webDriver.switchTo().alert().accept();
}
上传文件处理
1、定位上传按钮
2、通过sendKeys()添加文件的本地路径就可以了
private static void page05() throws InterruptedException {
WebDriver webDriver= new ChromeDriver();
webDriver.get("file:///C:/Users/ASUS/Desktop/page04.html");
webDriver.findElement(By.cssSelector("input")).sendKeys("F:\\Four_year\\培养计划.xlsx");
}
关闭浏览器
-
webDriver.quit()
-
webDriver.close()
quit和close之间的区别
- quit关闭整个浏览器所有标签页,close关闭当前页面句柄对应的页面
- quit清空缓存,close不会清空缓存
切换页面
- getWindowHandles获取所有的窗口句柄
- getWindowHandle获取get打开的页面窗口句柄
private static void test11() throws InterruptedException{
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
sleep(2000);
// getWindowHandles获取所有的窗口句柄
// getWindowHandle获取get打开的页面窗口句柄
Set<String> handles = webDriver.getWindowHandles();
String targetHandle= "";
for(String handle:handles)
{
targetHandle = handle;
}
// String targetHandle = webDriver.getWindowHandle();
webDriver.switchTo().window(targetHandle);
sleep(2000);
webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
sleep(2000);
webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
}
截图
private static void test12() throws InterruptedException, IOException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("测试");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(2000);
File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file,new File("C:\\Users\\ASUS\\Pictures\\Screenshots\\20240526.png"));
}
3.Junit5
Junit是Java里单元测试的框架
- 提供用例组织与执行
- 提供丰富的比较方法
- 提供丰富的日志
3.1 注解
- @Test
表示当前的代码是一个测试用例
public class JunitTest {
@Test
void test01()
{
System.out.println("这是Junit里面的Test01");
}
@Test
void test02()
{
System.out.println("这是Junit里面的Test02");
}
}
- @Disable
忽略方法
- @BeforeAll、@AfterAll、@BeforeEach、@AfterEach
如果有2个测试用例,BeforeEach跑2次,BeforeAll跑1一次
如果有2个测试用例,AfterEach跑2次,AfterAll跑1一次
BeforeEach在每个测试用例之前跑对应的方法,BeforeAll在所有测试用例之前跑对应的方法。
AfterEach在每个测试用例之后跑对应的方法,AfterAll在所有测试用例之后跑对应的方法。
参数化
- 单参数
@ParameterizedTest
@ValueSource(argument list)
@ArgumentsSource(ValueArgumentsProvider.class)
public @interface ValueSource {
short[] shorts() default {};
byte[] bytes() default {};
int[] ints() default {};
long[] longs() default {};
float[] floats() default {};
double[] doubles() default {};
char[] chars() default {};
boolean[] booleans() default {};
String[] strings() default {};
Class<?>[] classes() default {};
}
-
多参数
-
CSV获取参数
-
方法获取参数
测试用例执行顺序
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JunitTest {
@Order(2)
@Test
void test01()
{
System.out.println("这是Junit里面的Test01");
}
@Order(1)
@Test
void test02()
{
System.out.println("这是Junit里面的Test02");
}
}
断言
- Assertions.assertNull(str)
- Assertions.assertNotNull(str)
- Assertions.assertEquals(a,b)
- Assertions.assertNotEquals(a,b)
测试套件
- 通过class运行测试用例
@Suite
@SelectClasses({JunitTest01.class,JunitTest02.class}) - 通过包运行测试用例
@Suite
@@SelectPackages(value={“Test01”,“Test02”})