目录
ANR(Application Not responding)
测试基础
为什么选择测试
-
现在的环境下各种软件产品在功能上已经可以满足用户大部分需求,因此产品的质量和服务更加重要,而且随着云计算、物联网、大数据的发展,软件测试也是发展迅速,根据我的调查,大部分互联网企业和技术开发的单位对于测试尤其是测开都有不低的需求,所以我个人认为测试的发展前景是比较好的。
-
尤其是测开还有一部分开发工作,所需技术广度也是很高的,测试人员也因此面临着挑战,需要深入了解新场景并针对不同场景尝试新的测试方法,我个人比较倾向这样的学习工作模式。
-
在我之前的工作中,曾经经历过测试流程不明确,开发测试人员职能模糊的情况,开发人员需要负担起部分测试职能,这样导致开发过程混乱,大大影响了开发的进度。
测试的基本工作
-
测试的工作主要在于提前发现和定位错误,促进开发人员修正错误,从而保证软件质量。
-
越早发现软件中存在的问题,开发费用就越低。提前测试可在需求分析时期就发现错误,不必等到开发完成后。
-
测试工程师一般是检查软件bug、是否具有稳定性,并写出相应的测试计划、测试用例、测试报告,而测试开发需要在此基础上对测试工具以及部分功能进行二次开发。
测试的基本流程
-
需求分析评审:测试人员和产品、开发进行需求评审,对产品的功能进行整体把握,减少后期的沟通时间,根据需求写用例。
-
测试计划:根据开发计划制定测试计划。包括测试背景、测试范围、测试方式、测试资源等。
-
撰写测试用例:根据详细的需求文档,进行用例的编写,可使用边界值法、等价类划分法、错误推测法、因果图法等设计案例。保证测试用例的覆盖率。
-
测试用例评审:测试联合开发、项目经理进行测试用例评审。评审用例是否覆盖完整,用例中的前置条件、操作步骤、预期结果等是否明确。
-
执行测试用例:测试用例执行测试,发现问题记录测试方法,通知开发解决问题。
-
缺陷报告编写及提交:将发现的缺陷编写成正式缺陷报告,交给开发人员进行确认。
-
单元测试:基于白盒测试对软件基本组成单元进行的测试,发现各模块内部可能存在的各种错误。
-
集成测试:将软件集成起来进行测试,一般以模块和子系统为单位进行测试,通过黑盒和白盒结合,测试模块内各个接口间的交互集成关系。
-
系统测试:对已经集成好的软件系统进行彻底的测试,通过黑盒测试验证软件系统的正确性和性能等是否满足需求。
-
回归测试:发生修改之后重新测试先前的测试用例以保证修改的正确性。
用例回归:是过一段时间以后再回头对以前使用过的用例在重新进行测试,看看会重新发现问题。
错误回归:就是在新版本中,对以前版本中出现并修复的缺陷进行再次验证,并以缺陷为核心,对相关修改的部分进行测试的方法。
测试方法
黑盒测试
不考虑程序内部结构的基础上通过程序接口进行测试
-
等价类划分法:将系统的输入域划分为若干部分,每部分的一个典型值在测试中的作用与这一类中其他值的作用相同,从每个部分选取少量代表性数据进行测试。
假设有一个文本框要求输入10个字符的邮政编码,应该怎样划分等价类?
特殊字符,如10个*或¥;英文字母,如ABCDefghik;小于十个字符,如123;大于十个字符,如11111111111;数字和其他混合,如123AAAAAAA;空字符;保留字符
-
有效等价类:对于程序的需求规格说明来说是合理的输入数据构成的集合。
-
无效等价类:与有效等价类相反,利用无效等价类可检验程序对于无效数据的异常处理能力。
-
-
边界值分析法:因为大多数错误都在输入输出的边界上,通过选择不同等价类间的边界值覆盖有效等价类和无效等价类来进行测试。
-
因果图/判定表法:考虑输入条件的组合、输入条件与输出条件的相互制约关系,分析和表达多逻辑条件下执行不同操作的情况的测试。
-
条件桩:列出问题的所有条件
-
动作桩:列出问题中可能采取的操作
-
条件项:列出条件对应的取值,所有可能情况下的真假值
-
动作项:列出条件项的各种取值情况下应该采取的动作结果
-
-
正交表分析法:可能因为大量的参数的组合而引起测试用例数量上的激增,同时这些测试用例并没有明显的优先级上的差距,而测试人员又无法完成这么多数量的测试,就可以通过正交表来进行缩减一些用例,从而达到尽量少的用例覆盖尽量大的范围的可能性。
-
状态图法:通过输入条件和系统需求说明得到被测系统的所有状态,通过输入条件和状态得出输出条件;通过输入条件、输出条件和状态得出被测系统的测试用例。
白盒测试
检查程序内部逻辑结构,对所有的逻辑路径进行测试,是一种穷举路径的测试方法
-
语句覆盖:设计若干测试用例,每个执行语句至少执行一次。
-
判定覆盖:程序中的每个判断的”真“和”假“都至少被执行一次。
-
条件覆盖:判定中的每个条件至少有一次取真值,有一次取假值。
-
判定条件覆盖:程序中的每个判断本身的判定结果(真假)至少满足一次,每个逻辑条件的可能值也至少被满足一次。就是既满足判断覆盖,也满足条件覆盖。
-
条件组合覆盖:使得被测程序中的每个判定中条件结果的所有可能组合至少执行一次。条件组合覆盖能够满足语句覆盖、判定覆盖、条件覆盖、判定条件覆盖,但不能保证所有路径被执行。
-
路径覆盖:覆盖程序中所有可能的路径。
-
黑盒和白盒测试的区别
性能测试
通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。
-
负载测试:测试当负载逐渐增加时,系统各项性能指标的变化情况。
-
压力测试:通过确定系统的瓶颈或者不能接受的性能点,获得系统能提供的最大服务级别。
-
关注点:在客户端性能的测试、在网络上性能的测试和在服务器端性能的测试。
参数化测试
参数化是指为同一个测试用例提供不同的输入参数,并对每组参数进行测试。通常情况下会针对同一个功能或场景设计多组测试数据,通过参数化可以避免编写大量重复的测试代码,提高测试效率和覆盖率。
代码插桩
在保证被测程序原有逻辑完整性的基础上在程序中插入一些测试代码获取程序运行信息的测试方法。目标代码插桩具有3种执行模式。
即时模式:原始的二进制或可执行文件没有被修改或执行,将修改部分的二进制代码生成文件副本存储在新的内存区域中,在测试时仅执行修改部分的目标代码。
解释模式:在解释模式中目标代码被视为数据,测试人员插入的测试代码作为目标代码指令的解释语言,每当执行一条目标代码指令,程序就会在测试代码中查找并执行相应的替代指令,测试通过替代指令的执行信息就可以获取程序的运行信息。
探测模式:探测模式使用新指令覆盖旧指令进行测试,这种模式在某些体系结构(如x86)中比较好用。
QPS 和 TPS
TPS:每秒事务数。一个事务是指客户端向服务器发送请求然后服务器做出反应的过程,具体的事务可以是一个接口、一个业务流程等等。以单接口定义为事务举例,每个事务包括了3个过程:
(1)向服务器发请求
(2)服务器自己的内部处理(包含应用服务器、数据库服务器等)
(3)服务器返回结果给客户端
如果每秒能够完成 N 次以上3个过程,TPS 就是 N。
TPS 是软件测试结果的测量单位。我们在进行服务性能压测时,接口层面最常关注的是最大 TPS 以及接口响应时间,服务整体处理能力取决于处理能力最低模块的TPS值。
QPS:每秒查询率。指服务器每秒能够响应的查询次数,用于衡量特定的查询服务器在规定时间内处理流量多少,主要针对专门用于查询的服务器的性能指标,比如dns,它不包含复杂的业务逻辑处理,比如数据库中的每秒执行查询sql的次数。
QPS 只是一个简单查询的统计显然,不能描述增删改等操作,显然它不够全面,所以不建议用 QPS 来描述系统整体的性能;
QPS 基本类似于 TPS,但是不同的是,对于一个事务访问,会形成一个 “ T ”;但一次 " T " 中,可能产生多次对服务器的请求,服务器对这些请求,就可计入 QPS 之中。
区别:
(1)如果是对一个查询接口压测,且这个接口内部不会再去请求其它接口,那么 TPS = QPS,否则,TPS ≠ QPS
(2)如果是容量场景,假设 N 个接口都是查询接口,且这个接口内部不会再去请求其它接口,QPS = N * TPS
可以说TPS是完整的一次事务执行,而QPS只单纯指查询的次数,一次TPS中可能会包括多次请求,也就是QPS的次数。
测试用例
-
组成元素:包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等
-
编号;用例名称;用例说明;预置条件;输入数据;操作步骤;预期结果;实际结果;优先级;
-
编写
-
理清需求,拆分成需求点一一罗列出来作为测试点
-
清楚输入、输出的各种可能性,以及各种输入之间的关联关系,理解清楚需求的执行逻辑,通过等价类、边界值、判定表等方法找出大部分用例
-
梳理不同条件下的业务逻辑,补充对应需求点的业务逻辑测试点
-
案例(用户登录)
-
用户名和密码
-
太短或太长的处理(边界值法)
-
有特殊字符(比如空格)及其他非英文的情况
-
登陆成功,记住用户名,记住密码;登录失败后,不记录密码
-
输入密码时,大写键盘开启时是否有提示信息
-
什么都不输入,点击提交按钮,检查提示信息
-
-
登录流程:
-
正常流程(正确账号密码,点击提交,验证能否正确登录)
-
异常流程(错误的账号密码,点击提交,验证登录失败,并提示相应错误信息)
-
登录成功后能否正确跳转
-
-
性能测试:
-
打开登录界面,需要的时间是否在需求要求的时间内
-
输入正确的账号密码,点击登录,是否在需求时间内跳转成功
-
模拟大量用户同时登录,检查一定压力下能否正常跳转
-
-
安全性测试:
-
用户名或密码是否通过加密方式,发送给后端服务器
-
用户名和密码应该在前端和后端做双重验证
-
用户名和密码的输入框,应该屏蔽SQL注入攻击
-
用户名和密码的输入框,应该禁止输入脚本(防止XSS攻击)
-
防止暴力破解,检测是否有错误登录的次数限制
-
同一用户能否在多台机器上登录
-
-
可用性测试:
-
是否可以用全键盘操作,是否有快捷键
-
输入用户名,密码后按回车,是否可以登录
-
输入框是否可以Tab切换
-
-
兼容性测试:
-
不同浏览器下能否显示正常,且功能正常
-
同种浏览器下不同版本能否显示正常且功能正常
-
不同的操作系统是否能正常工作
-
移动设备上是否正常工作
-
自动化测试
意义
可以对程序的新版本自动执行回归测试,实现手工测试困难或者不可能实现的测试,如压力测试,并发测试,能够更好的利用资源,节省时间和人力。
断言
执行完测试用例后,通过断言(assert)判断测试结果是pass还是fail。不同的单元测试框架都提供了断言机制,Python中的断言类型丰富,最常用的是基础断言和集合断言。
断言设计:尽可能的验证所有返回关键数据,准确地验证预期的结果,灵活适应测试场景的变化,对于一些有规律的数据可采用正则表达式,一些可以在数据库中查询到的数据也可通过SQL查询验证。图片是否能正常打开
PO 设计模式
Jenkins
Jenkins 是一个用于自动化构建、测试和部署软件项目的开源持续集成(CI)和持续交付(CD)工具。它提供了一个易于使用的 Web 界面,允许开发团队轻松地设置、执行和监控自动化构建和部署过程。
BUG
生命周期
-
New: 新发现的bug
-
Open: 开发确认这是bug,并且认为需要进行修复
-
已修复(Fixed): 开发人员修改后,标记一下已经修复完毕,等待测试人员进行确认性测试;
-
拒绝(Rejected): 开发不认为这是个bug,拒绝修改把bug的状态制成Rejected状态;
-
延迟(Delay): 如果认为bug暂时不需要修改,就置成Delay状态 ,并且说明理由;
-
关闭(Closed): 经测试人员确认测试,并且通过测试之后,关闭bug;
-
Reopen: 修改状态的bug,经测试人员确认测试,如果仍然存在问题,把bug置成Reopen状态,开发人员需要重新去修改这个bug;
-
延期(later):下个版本再进行去修复这个bug;
BugZilla
-
Bugzilla是一种开源的缺陷管理系统,用于跟踪软件开发过程中的缺陷、错误和问题。
-
流程:测试人员发现BUG提交到Bugzilla中,状态为new,将BUG分配给相关的模块的开发人员,状态修改为已分配,开发人员和测试确认BUG,如果是本人的BUG,则设置为接收;如果是别的开发人员的问题,则转发出去,由下一个开发人员来进行此行为;如果认为不是问题,讨论并确认后拒绝这个BUG,然后测试人员关闭此问题。如果开发人员接受了BUG,并修改好以后,将BUG状态修改为已修复,并告知测试在哪个版本中可以测试。测试人员在新版本中测试,如果发现问题依然存在,则拒绝验证;如果已经修复,则关闭BUG。
问题排查
用户向客服机器人反馈服务,但是点击选项没有反应可能
-
前端:如果是在网页或者应用中使用客服机器人,可能是前端代码存在问题。可以通过浏览器的开发者工具来查看控制台输出,检查是否有报错信息。
-
后端:检查后端服务的运行状态和性能,查看输出日志确保其正常运行。
-
网络:检查网络连接是否正常,尝试重新连接或者更换网络环境。
-
兼容性:尝试在其他设备或者浏览器上进行测试,查看是否存在兼容性问题。
测试框架
TestNG
pytest
pytest是一个基于python非常成熟的单元测试框架
-
简单易用: pytest 的语法简单清晰,易于学习和使用。它支持使用简单的 assert 语句来编写测试断言,同时提供了丰富的插件和扩展功能。
-
自动发现: pytest 可以自动发现和收集项目中的测试文件和测试函数,无需显式配置。它会搜索项目目录及其子目录中的所有以 test_*.py 或 *_test.py 命名的文件,并执行其中的测试函数。
-
丰富的断言: pytest 提供了丰富的断言函数,用于验证测试结果是否符合预期。除了常规的 assert 断言之外,还提供了 assertion introspection 功能,能够更清晰地显示测试失败的原因。
-
参数化测试: pytest 支持参数化测试,可以使用
@pytest.mark.parametrize
装饰器为测试函数提供多组参数,用于测试同一个函数在不同参数下的行为。 -
fixture 功能: pytest 提供了 fixture 功能,用于在测试函数之前或之后执行一些准备和清理操作。fixture 可以帮助测试代码复用和降低重复代码量。
-
插件系统: pytest 具有丰富的插件系统,可以通过安装和配置插件来扩展 pytest 的功能。常见的插件包括测试覆盖率、测试报告、参数化测试、多线程测试等。
-
丰富的输出: pytest 提供了丰富的测试输出和报告功能,可以输出详细的测试结果、失败原因、代码覆盖率等信息,方便开发人员进行问题定位和分析。
-
与其他工具集成: pytest 可以与其他测试工具和框架集成,包括 Django、Flask、Selenium、Mock 等,实现更复杂的测试场景和自动化测试流程。
Selenium
Selenium是一个自动化测试框架,用于模拟用户在Web应用程序中的交互行为。它支持多种语言,包括Java、Python、Ruby等,Selenium由三个组件组成:Selenium IDE、Selenium WebDriver和Selenium Grid
-
Selenium IDE:一个浏览器插件,用于录制和回放用于在Web应用程序中的交互行为
-
Selenium WebDriver:一个用于编写自动化测试脚本的API,它支持多种编程语言,用于模拟用户在Web应用程序中的交互行为,如点击链接,填写表单,提交表单等。
-
Selenium Grid:一个分布式的测试工具,用于在多台计算机上并行运行测试
定位方式
id定位:id是html中的唯一标识,如果元素拥有id,可以使用id去定位它
name定位:name不具有唯一性,可以多次出现,一般用点来标识name
tag标签定位:HTML里,比较基础的Tag主要用于标题,段落和分行(input等)
class定位:class是元素的类名,也不具有唯一性
link_text定位:通过文本内容进行定位,例如下面标签里面的新闻,地图,贴吧等文本内容
partial_link_text定位:可以定位包含部分文本的元素,一般用于定位长文本内容
xpath定位:基本上可以定位到所有元素,掌握了xpath定位就没有定位不到的元素了。例如标签内的所有属性、标签内的文本(表达式较为复杂,效率不高)
css_selector定位:css_selector基本上也可以定位到所有元素,且css的性能会比xpath要好点
测试工具
postman
Postman 是一个用于 API 开发和测试的工具,它提供了丰富的功能来简化 API 测试和调试的过程。以下是一些常用的 Postman 功能:
基本功能
-
创建和发送请求:在 Postman 中可以轻松地创建各种类型的 HTTP 请求,包括 GET、POST、PUT、DELETE 等,可以指定请求的 URL、请求头、请求体等参数,并发送请求到目标服务器。
-
管理环境变量:Postman 允许创建环境变量,以便在请求中动态使用。可以创建全局环境变量或针对特定环境的环境变量,并在请求中引用这些变量,从而实现请求的动态构建和测试。
-
断言测试:Postman 提供了丰富的断言功能,可以对请求的响应进行验证。可以使用预定义的断言条件或自定义 JavaScript 断言来验证响应的状态码、响应体内容等。
-
集合和文件夹:Postman 允许将相关的请求组织成集合和文件夹,方便管理和执行。可以创建多个集合来组织不同类型的请求,并将它们放置在文件夹中进行分类。
-
测试脚本:Postman 允许编写 JavaScript 测试脚本来自动化测试过程。可以在请求的前置或后置脚本中执行各种操作,例如设置环境变量、发送额外的请求、验证响应内容等。
-
监视和调试:Postman 提供了监视和调试功能,可以查看请求和响应的详细信息,并进行调试和排查问题。可以查看请求的历史记录、响应时间、请求大小等信息。
参数化
在实际的接口测试中,部分参数每次发送请求时都要唯一(比如注册), 这时可采用postman把测试数据进行参数化处理
-
内建变量实现
-
Pre-request Script页签中使用代码实现 (推荐)
-
外部文件的方式实现;如csv文件/json格式文件
Jmeter
Jmeter是一款基于Java开发的开源压力测试工具。
基本功能
1.测试计划(Test Plan):是使用 JMeter 进行测试的起点,它是其它 JMeter 测试元件的容器。
2.线程组(Thread Group):代表一定数量的并发用户,它可以用来模拟并发用户发送请求。
3.取样器(sampler):定义实际的请求内容,被线程组包含,向被测试系统发出Http请求或者Java请求等,主要用HTTP请求。
4.监听器(Listener):收集JMeter的测试结果,JMeter的监听器有两个任务:添加结果监听,并且可以保存测试结果到文件,这些结果数据可以供再次分析使用。展示结果,JMeter可以以表格及图形的形式展示结果,方便测试人员分析测试结果。在开发测试脚本时,(比如查看结果树,可以在其中看到请求与响应的数据)
5.逻辑控制器(Logic Controller):
6.断言(Assertions):常用的是响应断言,对于复杂的断言可以通过BeanShell脚本来完成。
7.配置元件(Config Element):为取样器提供预备数据、然后由取样器发出请求;还可以用来记录服务器的返回数据。
8.前置处理器(Pre Processors):在取样器发送请求之前做一些环境或参数的准备工作,比如在对数据进行操作前建立一个数据库连接
9.定时器(Timer):
性能指标
-
TPS:每秒处理事务数,是性能测试中最重要的两个指标之一。事务数/平均响应时间
-
QTP:每秒查询服务器次数,在只有一个请求接口的情况下,等价于TPS。并发数/平均响应时间
-
TPS和QTP都是衡量系统处理能力的重要指标,一般情况下用TPS来衡量整个业务流程,用QPS来衡量接口查询次数。实际场景中可能是多个接口组成一个事务,比如一个保存事务,可能包括校验+保存两个接口请求,这时候一个TPS就等于两个QPS(jmeter中可以配置事务控制器,里面包括多个接口)。
-
并发数:系统能同时处理的请求数。QPS*平均响应时间
-
响应时间:系统对请求作出响应的时间,客户端发出请求开始计时,收到服务端响应后结束计时,是性能测试中最重要的两个指标之一
-
吞吐量:系统的吞吐量通常是由TPS(QTP)、并发数指标决定,在性能测试中,只要某一项达到系统的最高值,吞吐量就上不去,如果持续加压,即超负荷状态,吞吐量反而会下降。对于单用户的情况下,也就是并发数是1的时候,直接用响应时间来度量系统的性能
-
错误率:系统在负载情况下,失败交易的概率
Fiddler
Fiddler是一个抓包工具,通过改写HTTP代理,让数据从它那通过,可以将网络传输发送与接受的数据包进行截获、重发、编辑、转存等操作。使用代理地址:127.0.0.1,端口默认:8888
弱网测试
Fiddler可以通过设置模拟慢速网络来进行弱网测试。
修改参数模拟测试场景
平时测试往往不能够模拟所有场景。例如登录功能,输入超出长度的账号密码时,在前端页面就提示错误了,就不能够测试服务端接收到超长请求的处理场景了。利用Fiddler的AutoResponsder功能,可以通过修改requset或者response的参数,来实现构建模拟测试场景。
定位bug
例如在APP界面输入数据时提示错误;这时候不能判断问题是前端页面作限制导致?还是前端request的参数问题,是后台程序挂了?就可以通过fiddler抓包,分析request、response来判断问题。如果接口响应数据不正确,那很可能是后端的问题,如果请求参数不正确或者接口响应数据正确就是前端的问题;
Python
Python 是一种解释型语言(代码在运行时逐行解释执行,而不需要事先编译成机器码),具有语法简单易懂,可读性强,扩展库很多的优点,但是可解释特征使其运行速度变慢,且动态语言的特点可能会增加运行时错误。
Python也是一种面向对象的语言。不需要在声明变量时指定类型,变量的类型会在运行时根据赋值自动确定。
App测试
安卓测试和 iOS 测试
安卓测试和 iOS 测试的主要区别在于它们针对不同的移动操作系统进行测试。
-
操作系统和开发语言:
-
安卓测试针对的是基于 Android 操作系统的应用程序,使用 Java、Kotlin 等语言进行开发。
-
iOS 测试针对的是基于 iOS 操作系统的应用程序,使用 Swift、Objective-C 等语言进行开发。
-
-
测试工具:
-
安卓测试通常使用 Android Studio 自带的测试工具,如 Espresso、UI Automator 等,也可以使用第三方测试框架,如 Appium、Robot Framework 等。
-
iOS 测试通常使用 Xcode 自带的测试工具,如 XCTest、XCUITest 等,也可以使用第三方测试框架,如 Appium、Calabash 等。
-
-
设备和模拟器:
-
安卓测试中可以使用各种安卓设备和模拟器进行测试,涵盖了多种尺寸、分辨率和版本的设备。
-
iOS 测试中需要使用 iOS 设备或者 Xcode模拟器进行测试,涵盖了不同型号和版本的 iOS 设备。
-
-
发布流程:
-
安卓应用通常发布到 Google Play 商店,需要遵循 Google Play 的审核和发布流程。
-
iOS 应用通常发布到 App Store,需要遵循苹果的审核和发布流程。
-
-
用户群体:
-
安卓系统的用户群体更加广泛,设备和版本的碎片化也更高,需要考虑不同设备和版本的兼容性。
-
iOS 系统的用户群体相对统一,设备和版本的碎片化相对较低,但需要考虑不同型号和屏幕尺寸的适配。
-
app专项测试数据
-
app耗电量测试
-
app流量测试
-
app内存占用
-
app的cpu占用
-
游戏app测试关注帧率
-
电池温度测试
ANR(Application Not responding)
是指应用程序未响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。ANR由消息处理机制保证,Android在系统层实现了一套精密的机制来发现ANR,核心原理是消息调度和超时处理。
ANR的实质是主线程失去在限定的时间内处理完一些最常见的操作(启动服务、处理广播、处理输入)的能力,前置条件有新的操作需要主线程进行响应,而造成主线程失去响应能力的往往是一些主线程中的耗时操作,譬如密集CPU运算、大量IO、复杂界面布局,都会降低应用程序的响应能力。