测试计划
目标-> 范围-> 策略 -> 资源 ->风险
1. 目标制定
错误示范:
“测试购物车功能”
正确示范:
✅ 业务目标:保障双11期间加购成功率≥99.9%
✅ 质量指标:
- 功能用例覆盖率100%
- 缺陷重开率<5%
- 核心流程通过率100%
2. 范围界定技巧
四象限法则:
| 必须测试 | 可不测试 | |
|---|---|---|
| 重要 | 商品添加/删除 | 边缘浏览器兼容 |
| 次要 | 分组管理(VIP功能) | 极端异常场景 |
3. 策略设计模型
+--------------+
| 风险驱动策略 |
+------+-------+
|
+------------+------------+
| |
+----+-----+ +-----+----+
| 功能测试 | | 性能测试 |
| 占比70% | | 占比20% |
+----------+ +----------+
白盒/黑盒测试
白盒测试
白盒测试:知道代码,主要是单元测试。
白盒测试(White-box Testing)是一种软件测试方法,其核心理念是测试人员需要了解系
统内部的代码实现和逻辑结构,并基于此设计测试用例。与之相对的黑盒测试主要关注系
统的外部行为,不需要了解代码实现。
在白盒测试中,测试人员可以查看代码的控制流、数据流、条件分支、循环结构等,确保每个部分都
得到了充分验证。因此,白盒测试也被称为结构化测试或透明盒测试。
白盒测试的特点:
- 内部视角:测试人员可以直接查看和理解源代码,并基于代码的实现设计测试用例。
- 高覆盖率:目标是确保代码中的每个语句、分支、循环和逻辑路径都被测试到,尽量减少未被测试的逻辑。
- 常用于单元测试:白盒测试最常用于开发过程中,由开发人员执行单元测试,确保每个函数、类或模块按预期工作。
白盒测试的主要技术
- 语句覆盖:确保代码中的每一行语句都被执行至少一次。
- 分支/条件覆盖:确保每个条件的所有可能结果(如if-else条件的true和false)都被测试。
- 路径覆盖:确保每个可能的执行路径都被测试,尤其是在复杂的分支和循环中。
- 数据流测试:测试变量的定义、使用和赋值过程,确保没有未初始化变量或无效的赋值操作。
白盒测试的优点
- 代码级别的覆盖:能够发现代码中的隐藏缺陷、死代码、边界情况处理不足等问题。
- 提高代码质量:通过全面的覆盖率,确保代码的各个逻辑分支都被测试。
- 易于集成到开发流程:白盒测试通常与持续集成、单元测试等自动化工具结合,能够实时发现代码中的问题。
白盒测试的缺点
成本较高:测试人员需要了解代码的实现,这对技能要求较高,同时设计和维护测试用例也更为复杂。
黑盒测试
定义
黑盒测试是一种软件测试方法,在测试过程中,测试人员不需要了解软件的内部实现细节(如代码、
算法、数据结构等),只需从外部用户的角度来操作系统,基于输入和输出结果来验证系统是否符合预期。
测试人员视角: 将系统视为一个“黑盒”,只知道其功能和预期输出,但不知道内部如何实现。
目标: 验证软件的功能是否正确工作,找到在系统中可能存在的缺陷。
黑盒测试的主要特点
- 无需了解内部实现: 测试人员无需了解系统的内部代码或结构,只关注输入和输出。
- 面向用户需求: 测试过程以用户需求为基础,确保系统满足用户的功能需求。
- 基于功能验证: 黑盒测试的重点是验证功能模块是否按照预期工作,适合用于功能性测试、性能测试、兼容性测试等。
黑盒测试的优点
- 用户视角: 以用户的角度进行测试,能更好地模拟用户的实际操作行为,确保用户的功能需求得到满足。
- 容易编写测试用例: 测试人员不需要编写复杂的代码,只需基于需求和功能说明书设计测试用例。
- 适合大规模测试: 黑盒测试方法容易扩展,适合用于对大规模系统或功能模块进行测试。
黑盒测试的缺点
- 覆盖率有限: 黑盒测试只能测试系统的功能性表现,无法深入到代码的逻辑或内部错误,可能遗漏一些边缘问题。
- 无法测试系统的非功能性特征: 黑盒测试无法测试系统的内部实现细节,测试人员不能评估代码的性能、可维护性等非功能性特征。
- 容易遗漏一些缺陷: 如果测试用例设计不周全,黑盒测试可能会遗漏一些隐藏的缺陷。
黑盒测试的应用场景
- 功能性测试: 验证系统的每个功能模块是否正常工作,适用于所有用户操作接口。
- 兼容性测试: 验证系统在不同的设备、浏览器、操作系统等环境下是否表现一致。
- 安全性测试: 通过输入各种非法数据,验证系统能否抵抗攻击或未授权访问。
- 性能测试: 对系统进行高负载、并发测试,观察系统是否在高压力下保持稳定。
常见测试用例设计方法
1. 等价类划分
解释: 等价类划分将输入划分为多个子集,每个子集中的数据被认为对测试同样有效。只需对每个子集的一个代表值进行测试,而不必测试子集中的每个值。
示例: 用户名长度要求在1到20个字符之间,则可以划分为:
合法等价类:1到20字符长度的用户名
非法等价类:0个字符或超过20字符的用户名
测试用例:
输入合法的用户名长度:输入 "testuser"(预期成功)
输入空用户名:输入 ""(预期失败)
输入超过20字符的用户名:输入 "thisisaverylongusername"(预期失败)
2. 边界值分析
解释: 边界值分析是在输入值的边界附近测试,以发现软件在极限情况下的表现。
示例: 针对年龄输入框,允许输入18到65岁之间的年龄,则测试用例会集中在边界值附近:
测试用例:
输入 17(预期失败)
输入 18(预期成功)
输入 65(预期成功)
输入 66(预期失败)
保险项目,当前投保日期时满18岁才能投保,用户需要提交身份证号,根据身份证号来判断当天是否满18
岁
3. 决策表
解释: 适用于逻辑复杂的系统,根据输入条件列出所有可能的组合,然后设计对应的测试用例。
示例: 某电商网站允许用户使用优惠券和会员折扣,但条件是不能同时使用。决策表设计:
4. 状态转换测试
解释: 状态转换测试适用于状态驱动的系统,通过测试不同状态之间的转换来验证系统是否正常.
示例: 电商应用的订单状态流转:
下单 -> 待付款
付款 -> 已付款
发货 -> 已发货
收货 -> 已完成
5. 场景测试(Scenario Testing)
定义
场景测试是一种基于用户实际使用场景的测试方法,主要通过模拟用户在真实业务场景中的操作,验证系统在这些复杂操作中的表现。场景测试通常覆盖多个功能模块,通过这个模块间的交互来确保系统能在用户的实际使用过程中表现正常。
- 测试人员视角: 测试人员从用户的视角出发,模拟用户执行的特定任务或场景操作,涵盖多个功能的集成测试。
- 目标: 通过模拟真实业务场景,发现功能模块之间的交互问题、隐藏的系统缺陷,以及测试系统在复杂场景下的稳定性。
场景测试的特点
- 业务导向: 测试是基于用户的实际业务流程或使用场景,注重系统的集成功能验证。
- 全流程验证: 涉及多个模块,测试用例覆盖的场景通常是多个步骤组合而成的完整流程,确保系统在这些流程中的正确性和稳定性。
- 用户体验验证: 通过模拟用户行为,确保用户在实际操作中不会遇到功能缺陷或体验问题。
测试用例
是为了验证某个功能或特定场景是否按照预期工作所编写的一组条件、输入、步骤和预期结果的文档。每个测试用例都以明确的目标为导向,确保软件系统在特定条件下能正确地执行功能,并验证其满足需求规范。
禅道
- 添加测试用例
- 添加套件(用于测试某个功能,需要哪些用例,把这些用例添加到套件里)
套件关联用例
- 在套件中执行用例
- 失败提交bug
- 在bug栏目查看
测试用例的结构组成
-
测试用例编号
每个测试用例都需要有唯一的编号,便于在测试执行和管理过程中进行追踪。
例如:TC_001, TC_002 等。 -
测试标题/名称
简要描述该测试用例的测试内容或目标。它应该清晰简洁,让人一目了然地了解测试目的。 -
测试描述(可选)
详细描述测试用例要测试的功能或场景。
例如:验证用户登录功能的正确性。 -
前置条件
测试用例执行前必须满足的条件,例如登录状态、系统配置或数据初始化。
例如:用户已注册,测试环境已启动。 -
测试输入/步骤
按照执行测试的步骤,逐步描述如何操作,包括输入数据、用户操作等。每个步骤应详细到每一动作,以确
保测试的可重复性。
例如:输入用户名和密码,点击登录按钮。 -
预期结果
在执行测试步骤后,系统应该呈现的结果。预期结果应尽可能明确,以便测试人员能确定测试是否成功。 例如:登录成功后,显示用户主页。(同时验证左上角的用户名是正确的) 新增一些断言条件 -
实际结果
执行测试后,系统返回的实际结果,填写时测试人员根据实际执行情况记录。 -
优先级
指出测试用例的优先级,通常分为高、中、低,用于判断在测试执行中的重要性。(高优先级的用例可以在冒烟测试或者自动化测试中优先被考虑)
例如:高优先级的测试用例应尽快执行,以确保核心功能的正常运行。 -
测试状态 用来标记该测试用例的执行状态,如“通过”、“失败”、“未执行”、“被阻塞”等,方便后续的结果统计与分析
测试流程
CD(Code Development)代码开发
- 开发人员将代码推送到git仓库
- 进行静态代码分析,确保代码质量
CI(Continuous Integration)持续集成
- 当代码被推送到git仓库后,CI工具(如Jenkins)会触发构建(Build Triggers)
- CI工具执行构建操作(CI performs Builds post trigger)
- 执行构建测试(Perform Build Tests),确保构建的正确性
- 将构建结果存储在ArtiFactory存储管理系统中(selenium\jmeter\postman自动化测试)
- 构建完成后,触发烘焙操作
CD持续部署
- 烘焙并发布构建结果到ArtiFactory
- 进行部署测试(Deployment Testing),确保部署的正确性
- 通过Spinnaker进行持续部署,将软件部署到生产环境或测试环境
一、前置阶段
- 需求评审后,需要进行需求文档验证,保证产品需求逻辑全部可走通才可进行用例编写
- 编写用例测试人员需要提供冒烟用例和全功能用例
- 所有人员必须重视用例评审,参与评审人员必须对用例覆盖度进行评估与负责
二、测试准入标准
- 开发人员编码结束、并完成单元测试
- 测试人员提供冒烟用例,开发执行通过率在95%以上,冒烟用例要覆盖所有功能点,简单正向测试,能执行基本的功能
- 需求规定的功能或开发人员提交的功能说明书或者禅道上建立的任务功能均已实现
- 被测系统的基本流程可以走通,界面上的功能均已实现,符合设计文档的功能
- 测试范围与需求规格说明书或者原型相符,如不相符、需先更新原型或者相关说明文档,并钉钉项目大群同步给所有参与该项目的人员
- 开发提测需明确提测时间,并由开发人员落实到提测时间表
- 开发人员优化底层逻辑、框架、更换组件等,需同步测试影响范围,未同步相应人员承担对应责任
三、软件暂停、停止测试标准
-
被测系统在进行系统测试时,发现程序存在重大bug(1级阻碍bug超过1个),或者bug过多(2级以上bug超过4个),测试无法正常进行,可以暂停测试返给开发
备注:按照禅道标准分为1-4级,1级级别最高
-
开发提测后测试人员冒烟用例执行通过率满足95%以上,如不满足,可以暂停测试返给开发,并在提测时间表上增加说明
-
被测项目需暂停以进行调整时,测试应随之暂停
-
存在其他优先级任务
-
被测系统经过系统测试、并达到系统准出标准,可以在测试环境停止测试
-
被测系统经过系统测试、达到上线标准,可以在预发环境停止测试
四、恢复标准
- 重大bug被解决
- 优先级更高任务已经被完成
- 软件项目被调整后,重新启动,测试应随之启动
五、测试准出标准
- 被测项目满足产品原型需求
- 与需求不符合项,总结后提交给相关产品开发人员再次确认
- 遗留问题全部与技术负责人、产品相关人员、测试负责人、相关开发核对完毕,确定本期暂不更改,后期遗留优化
- 所有测试用例执行覆盖率100%,1、2级bug解决率100%,3级bug解决率95%,4级优化类bug解决率90%以上
- 需求测试覆盖率100%,部分无法测试情况需软件报告中说明,并及时同步给相应开发、技术&产品负责人(上线后持续跟进)
- 最后版本全量回归时,不能出现严重bug、3级bug不能超过5个
- 预发环境全量回归时,原则上不能出现bug或者1、2级bug不能出现,除环境等客观因素外3级bug不能超过3个
提交缺陷
在软件测试过程中,提交缺陷是测试工程师的重要职责之一。高质量的缺陷报告不仅能够帮助开发人员快速定位问题,还能提升团队的工作效率,减少沟通成本。下面是如何正确提交缺陷的详细指南。
缺陷提交的基本步骤
1. 确认缺陷是否真实存在
- 操作:在提交缺陷之前,测试人员首先需要确保问题的存在,并且能够稳定复现。缺陷的出现可能是由于配置问题、环境不同或误操作引起的,因此在提交之前需要验证该缺陷是否在正确的测试环境下出现。
- 措施:
- 仔细检查缺陷是否稳定重现。
- 在相同环境下再次执行测试步骤,确保问题确实存在。
- 示例:你发现用户在提交订单时,页面显示错误。你需要再次执行相同的操作,确保问题每次都能复现。
2. 收集详细的缺陷信息
- 操作:为了帮助开发人员迅速理解并修复缺陷,测试人员需要收集并提供完整的信息。这包括缺陷发生的详细环境、复现步骤、期望结果和实际结果等。
- 信息包括:
- 缺陷标题:简洁且明确,能够直接表明问题所在。
- 缺陷描述:描述缺陷的具体表现和影响,确保开发人员可以理解问题的影响范围。
- 复现步骤:逐步列出重现该缺陷的具体操作步骤,确保开发人员能够完全复现问题。
- 期望结果:测试人员期望系统如何正常运行。
- 实际结果:缺陷发生时系统的实际表现,包括错误提示、崩溃情况等。
- 示例:
- 缺陷标题:支付页面无法加载支付选项。
- 缺陷描述:用户在提交订单后,跳转到支付页面时,支付选项无法显示,无法进行支付操作,影响订单流程。
- 复现步骤:
- 选择商品,点击“立即购买”。
- 填写收货信息,点击“提交订单”。
- 跳转至支付页面,页面空白无任何支付选项。
- 期望结果:跳转至支付页面时,支付选项(如支付宝、微信支付)应正常加载。
- 实际结果:页面空白,无支付选项。
3. 提供必要的附加信息
- 操作:在某些情况下,简单的文字描述不足以解释缺陷的细节,特别是复杂的缺陷。测试人员可以附加更多有用的信息,如截图、日志文件、视频录制等,帮助开发人员更好地理解问题。
- 信息包括:
- 截图:展示页面错误的具体位置、错误提示信息等。
- 日志文件:在后端日志中找到与该缺陷相关的异常信息,并附上日志片段。
- 视频:对于交互复杂的缺陷,可以录制视频展示整个缺陷的发生过程。
- 网络请求:如果是前后端交互问题,提供网络请求的详细信息(如HTTP请求和响应)会非常有帮助。
- 示例:
- 附上支付页面加载失败时的控制台日志,标出请求错误的具体代码和状态信息。
4. 选择正确的优先级和严重性
- 操作:根据缺陷对系统的影响程度,测试人员需要为缺陷设置合理的优先级和严重性。优先级是指该缺陷修复的紧急程度,严重性是指缺陷对系统功能或用户的影响程度。
- 优先级示例:
- P1(高优先级):影响核心功能,系统不可用(如支付失败、无法登录)。
- P2(中优先级):影响主要功能,但有替代解决方案(如某个功能模块存在问题,但不影响整个系统)。
- P3(低优先级):影响次要功能或界面显示,不影响用户使用(如UI不一致)。
- 严重性示例:
- S1(高严重性):系统崩溃、数据丢失或核心业务无法完成。
- S2(中严重性):功能受限,但系统可继续运行。
- S3(低严重性):用户体验不佳,次要功能受到影响。
- 示例:
- 支付页面加载失败属于高优先级(P1)和高严重性(S1),因为它影响了核心支付功能,阻碍了用户下单。
5. 提交缺陷到缺陷管理工具
- 操作:使用团队的缺陷管理工具(如Jira、禅道、Bugzilla)提交缺陷。测试人员需要在工具中选择相关模块,填 写详细信息,并分配给适当的开发人员或团队。
- 工具设置:
- 选择缺陷对应的模块(如“支付模块”)。
- 指定开发人员:确保将缺陷分配给负责该模块的开发人员。
- 设置目标版本:明确修复缺陷的目标版本。
- 示例:
-在Jira中,选择“支付模块”,将缺陷分配给负责支付功能的开发人员,并设置优先处理。
提交缺陷的常见问题与避免方法
- 复现步骤不清晰
避免方法:提供详细、明确的复现步骤,包括每一步的操作和预期结果。 - 缺少附加信息
避免方法:提交前尽可能附加相关的截图、日志或网络请求数据,帮助开发人员更好理解问题。 - 优先级设置不合理
避免方法:根据问题的实际影响范围合理评估优先级和严重性,避免所有问题都设为高优先级。
测试报告
测试报告的组成部分与作用
测试报告通常包含以下几个组成部分,每个部分有其特定的作用:
- 标题
- 包含项目名称、测试类型(如功能测试、性能测试)、版本号、报告日期等。
- 作用:帮助读者快速识别该报告所针对的项目和测试范围。
- 测试概述
- 描述测试的目的、范围、环境、工具和策略。
- 作用:让读者了解测试的背景和前提条件,明确测试工作所覆盖的内容。
- 测试环境
- 包括硬件配置、软件版本、浏览器类型、网络环境等。
- 作用:明确测试在什么条件下进行,确保报告的可复现性。
- 测试范围
- 列出测试覆盖的功能模块、接口、业务场景等。
- 作用:清楚地展示测试的范围,防止遗漏重要模块。
- 测试执行
- 列出执行的测试用例、测试结果和执行情况(通过、失败、阻塞)。
- 作用:展示具体的测试工作,帮助读者了解哪些功能通过测试,哪些有问题。
- 缺陷分析
- 描述的缺陷,按优先级进行分类(P1、P2、P3),并记录其当前状态(未修复、已修复等)。
- 作用:为开发团队提供修复方向,并帮助管理层了解系统的风险。
- 测试总结与评估
- 包含测试结果的总结、主要问题的汇总、系统质量评估。
- 作用:概括性地评估软件质量,帮助做出上线或延期决策。
- 上线建议
- 根据测试结果,提出是否建议该版本上线的意见。
- 作用:为项目管理层提供决策参考,是测试报告中最关键的部分之一。
- 附件
- 详细的测试数据、执行的测试用例列表、日志文件等。
- 作用:为报告提供补充信息,便于后续查阅。
探索测试
较复杂的探索测试方法练习
http四种请求
http默认端口:80,https默认商品:443
Get请求
从服务器获取资源,参数通过url拼接。
Post请求
向服务器提交新资源或数据,有请求体(如表单),无长度限制,适合传输大量数据。
Put请求
向服务器更新资源
Delete请求
请求服务器删除指定资源
Web测试
功能测试
- 测试输入输出:确保系统能正确处理各种输入,并返回正确结果。
- 主要功能流程:如用户注册、登录、添加购物车、支付等核心功能的测试。
- 边界条件和异常处理:测试各种边界输入(如空值、超长值、非法字符)和错误处理(如登录失败时的提示)
- 表单验证:验证表单提交和数据验证的逻辑是否符合预期。
- 数据一致性:确保数据在前端和后端同步,提交的数据在后端保存并显示正确
用户界面(UI)测试
- 界面布局:检查页面布局是否正确,特别是在不同分辨率、浏览器是否有错位或排版问题。
- 按钮、链接、输入:确保所有按钮、链接、输入框都能正常使用,并且有良好的交互反馈。
- 图像和文本展示:确保页面中的图片、文本按设计要求显示,图片没有加载错误,文本没有错别字或格式问题。
- 可用性:检查页面元素是否清晰易用,用户是否能够直观地完成操作。
- 响应式测试:测试页面在不同设备(如手机、平板、PC)的显示效果,确保兼容性。
兼容性测试
- 浏览器兼容性:测试Web应用在不同浏览器(如Chrome,Firefox,Safari,Edge)上的显示和功能是否一致,是否有UI错位或功能异常。
- 操作系统兼容性:检查在不同操作系统 (如Windows,maxOS,Linux)上的表现是否一致。
- 设备兼容性:在不同设备(如PC、平板、智能手机)上测试应用,尤其是响应式设计的表现。
- 分辨率测试:测试应用在不同屏幕分辨率下的布局和功能,特别是在极小和极大窗口的适应情况。
性能测试
- 响应时间:测试关键操作(如登录、提交订单)是否有明显的延迟。
- 1秒内完成页面加载,优秀
- 3秒内完成页面加载,一般
- 5秒内完成页面加载,不合格
- 页面加载速度:观察页面是否能够在合理时间内加载完成,特别是首屏加载速度。
- 资源使用情况:观察页面是否占用过多的内存或消耗过多的CPU资源。(任务管理器查看内存,CPU哈克特情况)
- 负载测试(手工模拟):在多人操作的情况下,手工测试系统的稳定性,查看是否存在页面卡顿或崩溃。
易用性测试
- 导航和可访问性:检查页面的导航是否清晰,用户能否快速找到所需功能或信息。
- 提示信息:错误提示和帮助提示是否清晰易懂,能否有效引导用户完成操作。
- 用户操作流程:确保操作步骤简便,避免用户在流程中迷失或遇到不合理的设计。
- 移动设备体验:确保在手机、平板设备上有良好的用户体验。
可维护性测试
- 代码可读性:通过查看页面源代码 ,检查是否符合开发规范,便于后续开发和维护。
- 日志输出和错误捕捉:检查系统是否有效的日志记录功能,错误是否能 及时捕获并输出到日志。
- 可扩展性:观察系统是否能便捷地添加新的模块或功能,设计是否有足够的扩展性。
数据完整性测试
- 数据提交与存储:检查用户提交的数据是否能被正确存储,且没有数据丢失或篡改的情况。
- 并发处理:测试多个用户同时操作同一数据时,系统是否能处理并发操作,防止数据冲突。
- 数据库一致性:确保前端操作的数据与后端数据库中的数据保持一致,避免出现前后端数据不一致的情况。
国际化与本地化测试
- 多语言切换:检查在不同语言环境下,页面的内容是否正确显示。
- 日期、货币等格式:验证不同语言设置下的日期格式、货币符号是否符合当地规范。
- 文字排版:确保多语言环境下,文字的显示没有出现断行、排版错误等问题。
应用程序里清除缓存
判断bug是前端还是后端问题
- 显而易见的前端问题情况
前端页面布局问题,图片排版不合理,文字太长显示不合理,不同分辨率下的布局有问题。字体大小 字体样式有问题 和设计图不一致
- 不好判断的
一种场景: 商城页面,搜索一个商品,结果页面返回一个商品不存在的情况? (我确定这个商品是的的确确存在的)
查看数据库,字段名称,然后查看接口文档,发现了接口如下GET /search?pid=100 200 OK,返回数据为null。
首先你可以通过数据库去确定 是否存在pid=100的商品 id 100 iphone
接口文档说明 该接口需要传递参数 ProudctId(int)
以上可以判断此次bug属于前端请求时的参数使用错误 修改为 GET /search?ProudctId=100 200 OK
返回数据为 {"pname":"iphone16"}
APP测试
兼容性测试
一般是第一次上线进行测试,不一定每次更新需要测试,首先是公司里的主要机型进行测试,然后是云平台。
- 定义与重要性:兼容性测试确保 App 在不同设备、操作系统、网络等条件下正常运行。
- 案例分析:通过实例展示兼容性问题对用户体验和应用声誉的影响。
- 兼容性测试维度:
- 设备维度:品牌、型号、屏幕尺寸、分辨率、硬件配置。
- 操作系统维度:Android 和 iOS 版本。
- 网络环境维度:3G/4G/5G、Wi-Fi 等。
- 软件环境维度:特定软件(如定制系统)对 App 的影响。
兼容性测试主要测试安装、启动、覆盖安装、主要流程、主要页面打开,页面正常跳转、页面展示。主要问题是安装不了,启动不了,闪退,覆盖不成功,主页面打不开,卡顿,内存不足,存在于低端机。
制定覆盖策略
- 分层抽样策略:按品牌、操作系统等特征分层抽样测试。
- 例如:按品牌分层,再按 Android 和 iOS 分层后抽样。
- 边界值覆盖策略:选择维度的边界值进行测试。
- 屏幕尺寸:最小(如 5 寸)和最大(如 7 寸)。
- 操作系统:最低支持版本和最新版本。
- 组合覆盖策略:测试不同维度组合,如:
- 不同品牌在不同操作系统版本及网络环境下的表现。
具体覆盖方案示例
设备维度
- 屏幕尺寸:选择 5 寸(如 iPhone SE)、6 寸(如华为 P40)、7 寸(如华为 MatePad Pro)等代表性机型。
- 分辨率:包含 1080×1920(高清)和 2560×1440(超清)等常见分辨率。
- 硬件配置:不同 CPU(如骁龙 888、麒麟 9000、苹果 A14)、内存(4GB、6GB、8GB)和存储容量(64GB、128GB、256GB
操作系统维度
- 安卓系统:测试最新的安卓 11 和安卓 12 系统版本。
- iOS 系统:测试最新的 iOS 15 以及上一个主要版本 iOS 14。
- ui系统
网络环境维度
- 网络类型:涵盖 2G、3G、4G、5G 及 Wi-Fi 环境
- 网络运营商:涵盖中国移动、中国联通、中国电信等主要运营商。
- 不同网络下主流程过一遍。
内存维度
2g,4g,8g
原生 APP(Native App)
-
技术栈:使用平台专属的编程语言和框架开发:
- iOS:Objective-C、Swift(配合 iOS SDK)
- Android:Java、Kotlin(配合 Android SDK)
- 其他平台(如鸿蒙):对应平台的专属语言
-
原理:直接调用系统底层 API(如相机、传感器、通知等),编译为平台可直接运行的二进制文件(.ipa 或 .apk)。
混合 APP(Hybrid App)
-
技术栈:结合了网页技术(HTML5、CSS、JavaScript) 和原生技术:
- 核心业务逻辑通过网页技术实现(运行在 APP 内置的浏览器内核中)
- 需调用系统功能(如相机)时,通过 “桥接层”(如 Cordova、Ionic 框架)转换为原生 API 调用
-
原理:本质是 “原生壳 + 网页内容”,用户看到的界面是网页渲染的,但外层包裹了原生应用的壳,可在应用商店发布。
APP测试方法
1. 功能模块测试
1.1 运行
- App 安装完成后的试运行,可正常打开软件。
- App 打开测试,是否有加载状态进度提示。
- App 打开速度测试,速度是否可观。
- App 页面间的切换是否流畅,逻辑是否正确。
注册
- 用户名密码长度。
- 注册后的提示页面。
- 前台注册页面和后台的管理页面数据是否一致。
- 注册后,在后台管理中页面提示。
登录
- 使用合法的用户登录系统。
- 系统是否允许多次非法的登录,是否有次数限制。
- 使用已经登录的账号登录系统是否正确处理。
- 使用禁用的账号登录系统是否正确处理。
- 用户名、口令(密码)错误或漏填时能否登录。
- 删除或修改后的用户,原用户登录。
- 不输入用户口令和用户名、重复点(确定或取消按钮)是否允许登录。
- 登录后,页面中登录信息。
- 页面中有注销按钮。
- 登录超时的处理。
注销
- 注销原模块,新的模块系统能否正确处理。
- 终止注销能否返回原模块,原用户。
- 注销原用户,新用户系统能否正确处理。
- 使用错误的账号、口令、无权限的被禁用的账号进行注销。
1.2 应用的前后台切换
- APP 切换到后台,再回到 App,检查是否停留在上一次操作界面。
- APP 切换到后台,再回到 App,检查功能及应用状态是否正常。
- App 切换到后台,再回到前台时,注意程序是否崩溃,功能状态是否正常,尤其是对于从后台切换回前台数据有
- 自动更新的时候。
- 手机锁屏解屏后进入 App 注意是否会崩溃,功能状态是否正常,尤其是对于从后台切换回前台数据有自动更新的
- 时候。
- 当 App 使用过程中有电话进来中断后再切换到 App,功能状态是否正常。
- 当杀掉 App 进程后,再开启 App,App 能否正常启动。
- 出现必须处理的提示框后,切换到后台,再切换回来,检查提示框是否还存在,有时候会出现应用自动跳过提示
- 框的缺陷。
- 对于有数据交换的页面,每个页面都必需要进行前后台切换、锁屏的测试,这种页面最容易出现崩溃。
1.3 免登录
- App 有免登录功能时,需要考虑 OS 版本差异。
- 考虑无网络情况时能否正常进入免登录状态。
- 切换用户登录后,要校验用户登录信息及数据内容是否相应更新,确保原用户退出
- 根据 MTOP(淘宝无线开放平台)的现有规则,一个帐户只允许登录一台机器。所以,需要检查一个帐户登录多
- 台手机的情况。原手机里的用户需要被踢出,给出友好提示。
- App 切换到后台,再切回前台的校验。
- 密码更换后,检查有数据交换时是否进行了有效身份的校验。
- 支持自动登录的应用在进行数据交换时,检查系统是否能自动登录成功并且数据操作无误。
- 检查用户主动退出登录后,下次启动 App,应停留在登录界面。
1.4 数据更新
- 需要确定哪些地方需要提供手动刷新,哪些地方需要自动刷新,哪些地方需要手动+自动刷新。
- 确定哪些地方从后台切换回前台时需要进行数据更新。
- 根据业务、速度及流量的合理分配,确定哪些内容需要实时更新,哪些需要定时更新。
- 确定数据展示部分的处理逻辑,是每次从服务端请求,还是有缓存到本地,这样才能有针对性的进行相应测试。
- 检查有数据交换的地方,均有相应的异常处理。
1.5 离线浏览
- 在无网络情况可以浏览本地数据。
- 退出 App 再开启 App 时能正常浏览。
- 切换到后台再切回前台可以正常浏览。
- 锁屏后再解屏回到应用前台可以正常浏览。
- 在对服务端的数据有更新时会给予离线的相应提示。
1.6 App 更新
- 当客户端有新版本时,有更新提示。
- 当版本为非强制升级版时,用户可以取消更新,老版本能正常使用。用户在下次启动 App 时,仍能出现更新提
- 示。
- 当版本为强制升级版时,当给出强制更新后用户没有做更新时,退出客户端。下次启动 App 时,仍出现强制升级
- 提示。
- 当客户端有新版本时,在本地不删除客户端的情况下,直接更新,检查是否能正常更新。(覆盖安装,本地1.0
- 推送更新到1.5)
- 当客户端有新版本时,在本地不删除客户端的情况下,检查更新后的客户端功能是否具有了新版本的功能。
- 当客户端有新版本时,在本地不删除客户端的情况下,检查资源同名文件如图片是否能正常更新成最新版本。如
- 果以上无法更新成功的,也都属于缺陷。
- 升级后可以正常使用。
- 在线跨版本升级。(1.3.1 ,1.4.1,1.6.7,1.7.5 ->1.7.6)(1.3.1->1.7.6, 1.4.1->1.7.6)
1.7 定位、照相机服务
- App 有用到相机,定位服务时,需要注意系统版本差异。(app 做手机系统上的软件,是可以申请手机系统的权限,摄像头,定位,陀螺仪)
- 有用到定位服务、照相机服务的地方,需要进行前后台的切换测试,检查应用是否正常。
- 当定位服务没有开启时,使用定位服务,会友好性弹出是否允许设置定位提示。当确定允许开启定位时,能自动跳转到定位设置中开启定位服务。
- 测试定位、照相机服务时,需要采用真机进行测试。
1.8 时间测试
- 客户端可以自行设置手机的时区、时间,因此需要校验该设置对 App 的影响。
- 中国为东 8 区,所以当手机设置的时间非东 8 区时,查看需要显示时间的地方,时间是否展示正确,应用功能是否正常。时间一般需要根据服务器时间再转换成客户端对应的时区来展示,这样的用户体验比较好。
- 比如发表一篇微博在服务端记录的是 10:00,此时,华盛顿时间为 22:00,客户端去浏览时,如果设置的是华盛顿时间,则显示的发表时间即为 22:00,当时间设回东 8 区时间时,再查看则显示为 10:00。
1.9 PUSH 测试
- 检查 PUSH 消息是否按照指定的业务规则发送。(PUSH后台管理系统)
- 检查不接受推送消息时,检查用户不会再接收到 PUSH。
- 如果用户设置了免打扰的时间段,检查在免打扰时间段内,用户接收不到 PUSH。
- 在非免打扰时间段,用户能正常收到 PUSH。
- 当 PUSH 消息是针对登录用户的时候,需要检查收到的 PUSH 与用户身份是否相符,没有错误地将其它人的消
- 息推送过来。一般情况下,只对手机上最后一个登录用户进行消息推送。
- 测试 PUSH 时,需要采用真机进行测试。
2. 交叉事件测试
- 又叫事件冲突测试,是指一个功能正在执行过程中,同时另外一个事件或操作对该过程进行干扰测试。如:App在前后台运行状态时与来电、文件下载、音乐收听等关键运用的交互情况测试等。
- 执行干扰的冲突事件不能导致软件应用软件异常、手机死机或者花屏等严重问题。
- 多个 App 同时运行是否影响正常功能。
- App 运行时前/后台切换是否影响正常功能。
- App 运行时拨打/接听电话。
- App 运行时发送/接收信息。
- App 运行时发送/收取邮件。
- App 运行时切换网络(2G/3G/WIFI)。
- App 运行浏览网页。
- App 运行时使用蓝牙传送/接收数据。
- App 运行时使用相机、计算器手机自带设备。
- App 运行时插拔充电器。
- 注意各交叉事件的优先级别,检验系统是否能依据各事件的优先级别依次进行处理。不能因执行优先级别高的事件而导致优先级别较低的事件吊死。
- 有中英文模式切换的手机要注意中英文模式切换后的功能实现存在的问题。
3. 性能测试
3.1 响应时间和资源占用测试
- 测试 App 中的各类操作是否满足用户响应时间要求。
- App 安装、启动、卸载的响应时间。
- App 各类功能性操作的响应时间。
- 在各种边界压力情况下,如电池、存储、网速等,验证 App 是否能正确响应。
- 内存满时安装 App。
- 运行 App 时手机断电。
- 运行 App 时断掉网络。
- 评估典型用户应用场景下,系统资源的使用情况。appium
- Benchmark 测试(基线测试):与竞争产品对比测试,产品演变对比测试等。
3.2 压力测试
- 反复/长期操作下、系统资源是否占用异常。
- App 反复进行安装卸载,查看系统资源是否正常。
- 其他功能反复进行操作,查看系统资源是否正常。
- 大数量的测试:
- 在特定环境下,客户端一次性更新大量的数据及人员列表时,客户端能否正常处理,分为三种情况:
- 客户端第一次使用,第一次就更新大量数据及人员列表。
- 客户端在平时更新中,更新大量的数据。
- 客户端已经在手机本地下载很多数据后,再次更新大量数据。
- 在特定环境下,客户端一次性更新大量的数据及人员列表时,客户端能否正常处理,分为三种情况:
3.3 特定场景测试
- 通过模拟终端低电量(例如 5% 电量)的状态来测试功能在该状态下的正确性。(每个手机系统都有自己的特性)
- 通过模拟终端处于特殊地理位置(例如上海)来测试功能在该状态下的正确性。
- 通过模拟终端处于特定网络状态下(例如4G)来测试功能在该状态下的正确性。
3.4 深度性能测试
- 获取 App 在典型使用场景及待机状态下消耗的电量流量消耗。(第一次测从98%开始测,第二次测也最好从98%)
- 获取 App 在典型使用场景及待机状态下消耗的流量。
- 获取 App 在典型使用场景及待机状态下的 CPU 占用率。
- 获取 App 在典型使用场景及待机状态下内存量。
- 获取 App 冷启动和热启动耗时内容。
- 获取 App 特定页面的内容加载耗时。
- 获取 App 退出的耗时。
- 获取 App 在典型使用场景下帧率。
4. 安全测试
4.1 软件权限(合规性测试 应用商店、Appstore)
- 扣费风险:包括发送短信、拨打电话、连接网络等。
- 隐私泄露风险:包括访问手机信息、访问联系人信息等。
- 对 App 的输入有效性校验、认证、授权、敏感数据存储、数据加密等方面进行检测。
- 限制/允许使用手机功能接入互联网。
- 限制/允许使用手机发送接收信息功能。
- 限制/允许应用程序来注册自动启动应用程序。
- 限制/允许使用本地连接。
- 限制/允许使用手机拍照或录音。
- 限制/允许使用手机读取用户数据。
- 限制/允许使用手机写入用户数据。
- 检测 App 的用户授权级别、数据泄漏、非法授权访问等。
4.2 安装与卸载安全性
- 应用程序应能正确安装到设备上。
- 能够在安装设备上找到应用程序的相应图标。
- 是否包含数字签名信息。
- JAD 文件和 JAR 包中包含的所有托管属性及其值必须是正确的。
- 下载 JAVA 程序是通常会发现是两个文件,即 JAR 和 JAD。
- JAR 文件:是许多信息经过封装后形成的捆绑体,是一个压缩文件。
- JAD 文件:是 Java 应用程序描述器文件。
- JAD 文件显示的资料内容与应用程序显示的资料内容应一致。
- 安装路径应能指定。
- 没有用户的允许,应用程序不能预先设定自动启动。
- 卸载是否安全,其安装进去的文件是否全部卸载。
- 卸载用户使用过程中产生的文件是否有提示。
- 其修改的配置信息是否复原。
- 卸载是否影响其他软件的功能。
- 卸载应该移除所有的文件。
- 高/低版本覆盖安装。
- 安装、卸载、更新错误报告。
4.3 数据安全性
- 当将密码、信用卡明细或其他的敏感数据输入到应用程序时,其不会被储存在设备中,不以明文形式将数据写到其它单独的文件或者临时文件中,以防止应用程序异常终止而又没有删除它的临时文件,文件可能遭受入侵者的袭击,然后读取这些数据信息。
- 输入的密码将不以明文形式进行显示,同时密码也不会被解码。
- 不同的应用程序的个人身份证不能相互使用。
- 个人身份证和密码长度等必须有设定的要求。
- 备份应该加密,恢复数据应考虑恢复过程的异常。
5. 兼容性测试
- Android、iOS 版本的兼容性。
- 手机不同操作系统版本的支持。
- 手机不同厂家系统的支持。
- 手机不同尺寸的支持。
- 手机分辨率兼容性。
- 网络的兼容性:2G/3G/4G/5G/Wifi,弱网下、断网时。
- 不同浏览器兼容性。
- 与其他 APP 兼容性。
6. 安装、卸载测试
- 生成 apk 文件在真机上可以安装及卸载。
- Android 手机端通过使用安装工具,如豌豆荚。
7. 网络测试
- 外网测试主要实现模拟客户使用网络环境,检验客户端程序在实际网络环境中使用情况进行业务操作。
- 外网测试主要覆盖到 WiFi/2G/3G/4G/5G/wap、电信/移动/联通、所有可能的组合进行测试。
- 模拟信号屏蔽时候。
- 在高山、丘陵、火车上等特殊环境下进行全面测试。
8. 接口测试
- Client 端和 Service 端的交互。
- Client 端的数据更新和 Service 端的数据是否一致。
- Client 端更新时断开。
- Client 端更新时,Service 端挂掉
adb工具
adb的工作原理
启动adb客户端时,客户端会先检查是否有已经运行的adb服务器在进程。如果没有,它将启动服务器。服务器启动时会绑定到本地TCP端口5037,并侦听来自adb客户端的命令,所有adb客户端通过该端口与服务器通信。
使用夜神模拟器,端口默认:62001,进入设置->关于手机->版本号,连点8下,进入开发者模式。
adb命令
cmd打开命令提示符
adb version:查看adb版本adb connect 127.0.0.1:62001(连接本地的夜神模拟器)adb devices(查看设备)adb -s 127.0.0.1:62001 shell(参数s连接某一台设备进行shell)exit(退出 shell)
#表示root权限,$表示没有root权限
应用安装与卸载
可以通过 adb shell pm list package 来查看已安装的应用包名。
adb install -r <apk文件路径>安装adb uninstall <包名>卸载adb uninstall -k <包名>卸载但保留配置和缓存文
文件操作
- 将文件从PC传输到设备
adb push <本地文件路径> <设备路径>adb push C:\Users\aaa.txt /sdcard
- 将文件从设备传输到PC
adb pull <设备文件路径> <本地路径>adb pull /sdcard/server.log C:\Users\Desktop
截图
adb shell screencap /sdcard/screen.pngadb pull /sdcard/screen.png C:\Users\Desktop
adb服务的启动与关闭
- 启动 adb服务 :
adb start-server - 关闭 adb服务 :
adb kill-server - 释放指定端口号的进程
netstat -ano | findstr "5037端口号"或者taskkill -f -pid <进程号>
adb logcat
adb logcat 是 Android 调试工具,用于实时获取 Android 设备或模拟器的系统日志。可以帮助开发者调试应用,查看系统行为和错误信息。
- 启动logcat:
adb logcat - 将日志输出保存到log.txt文件中:
adb logcat > E:\log.txt
常见Logcat日志级别
- V (Verbose):最详细的日志,记录所有信息。
- D (Debug):调试信息,用于开发调试。
- I (Info):一般信息,通常用于显示运行状态。
- W (Warn):警告信息,可能引发问题但不影响应用运行。
- E (Error):错误信息,严重错误会影响应用运行。
- F (Fatal):致命错误,通常会导致应用崩溃。
- S (Silent):关闭日志输出。
常见命令
- 显示某一日志级别以上的日志:
adb logcat *:E显示Eerror级别以上的日志 - 按关键词过滤:
adb logcat | findstr "关键词" - 清空日志:
adb logcat -c,清空本地日志文件adb logcat > D:\log.txt -c - 显示当前已打开的包名或activity名:
adb shell dumpsys window w | findstr \/ | findstr name= - 启动指定应用的Activity:
adb shell am start -n <package-name>/<activity-name> - 查看指定包名的资源情况:
adb shell top -s9 -d3 | findstr com.tencent.mm
常见问题
OOM(Out of Memory):内存不足
nullpointer:空指针异常
ANR(Application Not Responding):应用无响应
Monkey测试
查询app的包名
adb shell pm list packages
启动monkey测试
adb shell monkey -p <package-name> -v <event-count>
参数解释:
-p <package-name>:指定要测试的应用的包名。-v:设置日志的详细程度。可以多次使用 -v 提高日志详细度。<event-count>:设置生成的事件数量。adb shell monkey -p com.baidu.searchbox -v 500
控制各类事件的的占比
--pct-touch 50:指定触摸事件占总事件的50%--pct-trackball 30:指定轨迹球事件占总事件的30%--pct-nav 10:导航键如home,返回键--pct-syskeys 10:指定系统按钮(电源键、音量键、返回键、主页键)的事件占10%--pct--majornav 10:物理或虚拟键盘的按键,输入字符、数字、特殊符号--pct-rotation 10:模拟屏幕旋转--pct-flip 10:模拟剪贴板操作,如复制、剪切、粘贴--throttle 1000:在每个事件之间设置1秒的延迟(单位为毫秒)--pct-motion 10:手势滑动事件(如连续滑动屏幕)--pct-appswitch 10:应用切换事件--pct-anyevent 10:其他未分类事件-kill-process-after-error:设置在出现崩溃后停止测试--ignore-crashes和--ignore-timeouts:设置在遇到崩溃或ANR时不停止测试- seed 是 Monkey 测试的 随机种子,用于控制 Monkey 工具生成伪随机事件的顺序。指定 seed 可以确保每次运行 Monkey 测试时生成的事件顺序一致,这样就可以在多个测试之间重现相同的操作顺序,以便更好地调试和追踪问题
通过
--seed <number>来设置。如果每次seed相同,那么每次monkey运行的事件顺序也将是相同的。 - 生成随机的seed,
adb shell monkey -p com.example.myapp --seed $(date +%s) -v -v -v 10000。在这个命令中,$(date +%s) 会获取当前时间的时间戳作为随机种子,每次运行时这个种子值都不同,确保每次生成不同的事件序列。
高级用法
- 限制测试在某个activity;
adb shell monkey -p com.example.myapp --activity-filter <activity-name> -v 1000指定在某个页面进行测试。 - 输出日志到文件;
adb shell monkey -p com.example.myapp -v 1000 > monkey_log.txt - 正常情况,如果monkey测试顺利执行完成,在log最后,会打印出当前执行事件的次数和所花费的时间。
- Monkey finished
- 打开log,查看log的最下端,是否有类似以下字段
- Network stats: elapsed time=5123ms (5123ms mobile, 0ms wifi, 0ms not connected)
- 这个字段表明本次的monkey没有异常,测试通过
- crash
- 如果搜索到有结果,则表明有进程出现问题,测试不通过。
- CRASH: com.onekchi.downloadmanager (pid 12919)
- anr
- 如果有搜索结果,则表示测试过程中,测试对象出现了无响应的现象,因此测试不通过。
- Monkey finished
logcat+monkey
一边monkey测试一边将日志保存到文件。
adb logcat > monkey_log.txt & adb shell monkey -p com.baidu.searchbox --pct-touch 50 --pct-motion 50 --pct-syskeys 0 --throttle 1000 --kill-process-after-error -v -v -v 100
性能测试
测试步骤
- 写测试用例,测试场景A点击这个按钮,那个按钮,滑动页面三次
- 准备测试设备,手机充满电,安装好测试工具,手机重启
- 开始测试,测试完成收集性能数据
- 做成数据报表,曲线图
APP性能指标
- App 性能问题如app 使用时卡顿严重或者加载页面慢,cpu 占用率高,app 闪退等,在测试过程中,则需特别关注性能方面的体验,app 性能差,通常会导致用户对app 的使用率下降,卸载率上升。
- 响应
- 软件的响应时间和响应速度直接影响到用户的体验度,如果一个软件,迟迟加载不出来,会直接影响到软件的日活、留存。因此对于一个软件,对响应速度测试是必不可少的。
- 优秀:0~400ms,标准:400ms~2000ms,轻微隐患:2000ms~5000ms,严重隐患:5000ms 以上。
- 内存
- 在Android 系统中,每个APP 进程除了同其他进程共享内存(shared dirty)外,还独用私有内存(private dirty),通常我们使用PSS(私有内存+比例分配共享内存)来衡量一个APP 的内存开销。由于一个移动设备的内存是固定的,如果内存消耗过大就会造成应用卡顿或者闪退,需要对内存进行测试。正常情况下,应用不应占用过多的内存资源,且能够及时释放内存,保证整个应用内的稳定性和流畅性。
- CPU
- 主要关注的CPU 的占用率。玩手机时,会出现发热发烫,那是因为CPU 使用率过高,CPU 过于繁忙,会使整个手机无法响应用户,整体性能降低,用户体验就会很差,也容易引起ANR(application not responding,应用程序无响应,主线程(UI线程)如果在规定时内没有处理完相应工作,就会出现ANR)等等一系列问题。
- FPS
- 应用的使用流畅度,FPS 是图像领域中的定义,是指画面每秒传输帧数,通俗来讲就是指动画或视频的画面数。FPS 是测量用于保存、显示动态视频的信息数量。每秒钟帧数愈多,所显示的动作就会愈流畅。
- 一般,Android 设备的屏幕刷新率为60 帧/s,要保持画面流畅不卡顿,要求每一帧的时间不超过1000/60=16.6ms,这就是16ms 的黄金准则,如果中间的某些帧的渲染时间超过16ms,就会导致这段时间的画面发生了跳帧,因此原本流畅的画面变发生了卡顿。
- GPU 过度渲染
- GPU 渲染是指在一个像素点上绘制多次(超过一次):显示一个什么都没有做的activity 界面算作画了1 层,给activity 加一个背景是第2 层,在上面放了一个Text View(有背景的Text View)是第3 层,Text View 显示文本就是第4 层,仅仅只是为了显示一个文本,却在同一个像素点绘制了四次,这一定要优化的。过度绘制对动画性能的影响是极其严重的,如果你想要流畅的动画效果,那么一定不能忽视过度绘制。
- 耗电量
- 测试应用对电量的消耗前需要对手机本身的电量消耗有个大概了解,测试前先看规定时间内手机正常待机下(重启后待机)电量消耗为多少,然后再启动待测试APP看看消耗的电量增加了多少取差值。
- 测试点:
- 测试手机安装目标APK 前后待机功耗无明显差异;
- 常见使用场景中能够正常进入待机,待机电流在正常范围内;
- 长时间连续使用应用无异常耗电现象。
- 流量测试
- 目前的网络类型包含2G\3G\4G\wifi,其中还有不同运营商的区分,我们在APP 的使用中经常遇到大资源,重复请求,调用响应慢,调用失败等各种情况。在不同的网络类型之下,我们不仅加快请求的响应,还要控制流量使用。
- 每秒钟平均流量,建议值<5.12kb,每10 分钟平均流量,建议值<3MB,不存在app偷跑流量等行为
1 APP响应时间和响应速度测试
1.1 主要测试点
- 冷启动
- 首次启动APP的时间间隔(只是启动时间,不包括页面加载)
- 热启动
- 非首次启动APP的时间间隔(只是启动时间,不包括页面加载)
1.2 测试方法
- 冷启动:
adb shell am start -W com.tencent.mm/.ui.LauncherUI-
绝对路径,首个Activitya
-
am是shell 中集成的一个命令,ActivityManager 的简写。 -
-W是指启动完成之后,返回启动耗时。 -
可能存在 app 缓存(提示 Warning: Activity not started, intent has been delivered to currently running top-most instance),建议重新打开模拟器后,直接运行命令
含义
-
ThisTime: 重点,该Activity 的启动耗时,单位ms(单纯渲染页面的时间);
-
TotalTime: 应用自身启动耗时, ThisTime+应用application等资源启动时间(应用启动的时间加渲染页面的时间);
-
WaitTime: 系统启动应用耗时, TotalTime+系统资源启动时间(安卓系统启动应用时间加应用自身启动时间)。
-
如果只关心某个应用自身启动耗时,参考TotalTime;如果关心系统启动应用耗时,参考WaitTime;如果关心应用所有界面Activity 启动耗时,参考ThisTime。
-
- 热启动
- 按返回按钮后再启动adb命令
- 测试标准:冷启动时间不超过 1.5s,热启动不超过1s
2内存占用测试
2.1 主要测试点
- 空闲状态
- 切换至后台或者启动后不做任何操作,消耗内存最少。
- 中强度状态
- 时间偏长的操作应用。
- 高强度状态
- 高强度使用应用,可以跑monkey 来测试(通常用来测试内存泄漏)。
- 内存泄漏
- 指使用malloc 或new 申请了一块内存,但是没有通过free 或delete 将内存释放,导致这块内存一直处于占用状态
2.2 测试方法
- 使用adb命令
adb shell dumpsys meminfo com.tencent.mm- 主要指标
- Native heap alloc、Dalvik heap alloc
- 若这两个值一直增长,说明可能出现内存泄漏
- PSS
- APP实际占用的内存大小
- Native heap alloc、Dalvik heap alloc
- 主要关注
- 退出某个页面后,内存是否有回落。
- 如果没有及时回落,且程序自动GC(Garbage Collection,垃圾回收)或者手动GC,那便可确认有问题
- 进行某个操作后,内存是否增长过快。
- 增长过快,也有可能存在风险,需重复操作确认。
- 退出某个页面后,内存是否有回落。
3 CPU繁忙测试
3.1 主要测试点
- 在空闲时间(切换至后台)的消耗,基本没大应用使用CPU
- 在运行一些应用的情况下,CPU 已占50%的情况下,观察应用程序占用CPU 的情况
- 在高负荷的情况下看CPU 的表现(CPU 占用应是在80%以上)
3.2 具体场景
- 空闲状态运行监测CPU 占用率
- 应用按Home 键退到后台,不再占用系统的状态(通常是灭屏半分钟后)
- CPU 占用率=0%
- 中等规格运行监测CPU 占用率
- 模拟用户最常见的使用场景
- CPU 占用率≤30%
- 满规格长时间正常运行监测CPU 占用率
- 应用正常运行,打开应用进行基本操作
- CPU 占用率≤50%
3.3 测试方法
adb shell dumpsys cpuinfo apk 包名 findstr 包名
adb shell top -m -s | findstr packageName- -m 数字
- 显示指定数目的最大值,一般后面不再接findstr
- 使用-m会 导致隐藏列名
- -s 数字
- 按指定列号进行倒序排列
- 从1 开始,最大11
- 9 代表CPU,10 代表内存
- -n 数字
- 刷新几次后退出
- -d 秒数
- 刷新间隔
- q 回车
- 退出
如果反复进行某个操作,CPU 占用过高且一直无法释放,那便可能存在风险。
4 FPS应用流畅度测试
- 开启Profile GPU rendering
- Settings→System→Advanced→Developer options→查找profile→找到并单击Profile GPU rendering→In adb shell dumpsys gfxinfo
- 打开要测试的app
adb shell dumpsys gfxinfo 包名- Graphics info for pid 1331 [com.tencent.mm]:表明当前 dump 的为 com.tencent.mm 的帧信息,pid 为1331。
- Total frames rendered: 2218:本次dump 搜集了2218 帧的信息。
- Janky frames: 26 (1.17%):帧中有26 帧的耗时超过了16ms,卡顿概率为1.17%。
- Number Missed Vsync: 3:垂直同步失败的帧
- Number High input latency:2213:处理input 时间超时的帧
- Number Slow UI thread: 1:因为ui 线程导致slow 的帧
- Number Slow bitmap uploads: 0:因为bitmap 加载slow 的帧
- Number Slow issue draw commands: 3:因为绘制导致slow 的帧
每一帧的数据
- Draw: 表示在Java 中创建显示列表部分中的OnDraw()方法占用的时间。
- Prepare:表示渲染引擎准备时间,不关注此项。
- Process:表示渲染引擎执行显示列表所花的时间,view 越多,时间就越长。
- Execute:表示把一帧数据发送到屏幕上排版显示实际花费的时间。
- Draw + Process + Execute = 完整显示一帧 ,这个时间要小于16ms 才能保存每秒60 帧。
- 通过excel进行表格处理可以直观的查看软件的流畅度
- 只保留Process、Draw、Execute
- 将三列加和
- 绘制线图
- 16ms 以上的卡顿,需要优化
- Settings→System→Advanced→Developer options→查找profile→on screen as bars
- 结果以图形形式显示在设备中
- 开启此功能后,随着屏幕刷新,界面上会滚动显示垂直的柱状图来表示每帧画面所需要渲染的时间,柱状图越高表示花费的渲染时间越长。
- 每个直方条代表一帧,每个直方条的高度表示该帧渲染所用的时间(以毫秒为单位)
- 界面中间一根绿色水平线代表16ms,每一帧的柱状线都在这条绿线以下,才能避免出现由丢帧引起的卡顿。
- 颜色含义(Android 6.0 及更高版本中的竖条区段)
5 GPU过度渲染
-
开启GPU 过度渲染
- 设置→开发者选项→单击Debug GPU overdraw→选择show overdraw areas
- 使用genymoton 可能会导致模拟器无响应,建议使用AVD 模拟器。
- 显示开发者选项
- 打开手机的“设置”,进入到“设置”页面;
- 滑到“设置”页面的最下端,进入“系统”;
- 找到“关于手机”,进入到“关于手机”页面;
- 找到“版本号”,连续点击。
- 会弹出一段文字提醒,直到提醒次数为0 后结束点击。
- 重新进入“系统”,进入“开发者选项”。
-
打开被测的应
-
GPU 过渡渲染不同的颜色代表不同的绘制程度
- 原色:无过渡绘制
- 蓝色:绘制一次 (理想状态)
- 绿色:绘制二次
- 浅红:绘制三次 (可以优化)
- 深红:绘制四次 (必须优化)
-
测试指标
- 控制过渡绘制为2x
- 不允许存在4x 过渡绘制
- 不允许存在面积超过屏幕1/4 的3x 过渡绘制
Charles
Charles 是一款常用的网络抓包工具,它可以帮助用户监控、分析和调试网络请求。通过 Charles,你可以查看客户端与服务器之间的通信数据,包括 HTTP、HTTPS 等协议的请求和响应信息。这对于开发人员调试网络应用、分析网络问题以及优化网络性能非常有帮助。
- HTTP的不足:
- HTTP传输的是明文,所有数据都可以被第三方拦截、查看。
- 没有数据加密或数据校验,容易被中间人攻击。
- HTTPS的工作原理:
- HTTPS在HTTP的基础上增加了SSL/TLS协议,用于加密传输。
- SSL/TLS通过对称加密和非对称加密结合,确保数据在传输过程中不会被拦截和篡改。
- 举例说明:访问银行网站或支付宝等涉及到支付的页面,说明如何通过浏览器锁标记识别HTTPS安全连接。
配置Chales
Proxy设置端口号为8888
为了能够抓取 HTTPS 流量,你需要安装 Charles 的根证书。点击菜单栏中的 “Help”->“SSL Proxying”-> “Install Charles Root Certificate”,按照提示将证书安装到系统的受信任证书存储区。
点击安装证书
受信任的根证书颁发机构
配置ssl 代理设置 包含 域名+端口号 域名:( 代表任何数据 通配符) 端口号:443(https端口号), 域
名:* 端口号:*
请求编辑
请求右键点击Compose
重定向
拦截
点击请求右键,选择 Breakpoints,勾选状态。说明拦截该请求。
拦截该请求后可以进行编辑请求
弱网测试
Proxy菜单
分析bug前后端问题
Linux
常用命令
- cd :去指定的目录
- cd 相对路径\绝对路径
- 相对路径:以当前目录为准,回到上一级或者下一级目录
- cd .. :返回当前目录的上一级目录
- cd .: 进入当前目录 .当前目录
- cd ~: 回到当前用户目录
- pwd:显示当前所在目录的路径
- cd ../../a/
- 可以通过tab键 对路径上的文件进行补全,如果不确定文件目录的名称,可以用这个方法
- ls :查看当前目录下的内容
- ls -l 通过ll简写的方式实现查看当前目录下的详细的内容
- drwxrwxr-x. 2 qingyun qingyun 6 10月 18 04:30 bbb
- d rwx rwx r-x
- d 代表文件夹
- 第一个rwx 目录所有者对这个文件或者文件夹的权限
- r read 读权限,w write 写权限,x excute 执行
- 第二个rwx 代表所属组的权限
- 第三个r-x 代表其他用户的选线
- r 读权限,- 没有写权限,x 执行权限
- ls -a 可以通过这种方式看到包括.开头的隐藏文件
- ls -lh :human 显示k,M,G文件的大小
- ls -lah
- ls -l 通过ll简写的方式实现查看当前目录下的详细的内容
- mkdir :创建文件夹
- mkdir abc
- mkdir b/bb1/bbb1 -p 加上-p 当父目录不存在的时候会自动创建
- mkdir bb2 bb3 bb4 一次创建多个目录
- mkdir bb2/{bbb1,bbb2,bbb3} 一次创建多个文件目录
- touch 创建一个空文件
- touch bbb4/testcase01.txt 保证目录必须是存在的,才能够创建成功
- touch .log.txt
- gedit testcase01.txt
- rm :删除文件的命令
-
rm abc -r : -r 删除文件夹
-
rm abcd -rf : -f force 强制删除,有任何通知都忽略
-
rm .abc.txt 删除隐藏文件
-
rm -r bb2/{bbb1,bbb2,bbb3}
-
rm -rf bb2/{bbb4,bbb5} 删除目录下指定的文件
-
rm bb2 bb3 bb4
-
表示该目录的硬链接数,每个目录至少有两个硬链接,一个指向自身,另一个指向父目录对它的引用
- ln 硬链接 将多个文件路径指向同一个数据块,或者数据源,这样可以减少存储空间,提高文件的可用性,避免存储重复的数据,当有多个应用或者用户需要使用同一个数据的时候。
- ln 原文件 硬链接文件
创建一个硬链接
ln a.txt a_hard_link.txt
往其中一个文件里写入数据6
echo "Hello world!" > a.txt
当我们删除一个文件的时候,数据块是不会被删除的,这样可以保证数据的安全,查看文件的inode号,去确认文件是否是同一个数据块
ls -li
- 35715848 -rw-rw-r--. 2 qingyun qingyun 11 10月 18 04:56 aaaa.txt
- 35715848 -rw-rw-r--. 2 qingyun qingyun 11 10月 18 04:56 a_hard_link.txt
- 52115878 drwxrwxr-x. 2 qingyun qingyun 6 10月 18 04:30 bbb3
- 35715848 inode号
总结:
- 硬链接 将多个文件路径指向同一个数据块,或者数据源,这样可以减少存储空间,提高文件 的可用性,避免存储重复的数据,当有多个应用或者用户需要使用同一个数据的时候。
- 当我们删除一个文件的时候,数据块是不会被删除的,这样可以保证数据的安全
- 硬链接的意义在于数据共享与安全性。
-
ln -s: 软链接,相当于windows的快捷方式
- ln -s a.txt a_soft_link : 给某个源文件创建软链接,对软链接查看、修改,都是作用在源文件身上 软链接只记录源文件的名称
ln -s /home/admin/桌面 a_soft : 给目录创建软链接,切记使用绝对路径
ls -l /home/user/symlink.txt
-
删除软链接 rm a_soft_link
-
切记如果是删除目录软链接不要带根号,不然删的就是软链接下的内容
-
例如 rm a_soft_link/
-
输出示例
-
lrwxrwxrwx 1 user user 10 Oct 17 12:00 symlink.txt -> /home/user/file.txt
-
开头的 l 表示这是一个符号链接。
-
-> 表示软链接指向的文件路径。
-
-
硬链接
- ln a.txt a_hard_link : 硬链接相当于给源文件备份一个,可以同步更新数据,
- 硬链接有一个数量,代表共有几个文件会同步变化
- 不能给目录创建硬链接
总结
- 软链接适用于指向不同分区或文件系统中的文件或目录。
- 硬链接更适合需要高可用性的文件(如避免文件误删),因为文件数据不会因某个硬链接的删除而丢失。
- 通配符
ls *txt 显示以txt结尾的所有的文件
ls b*
-
cp : 拷贝
- cp a.txt a1.txt
- cp d1 d2 -r 拷贝文件夹需要加-r
-
history 显示你执行过的历史命令
-
clear 清除屏幕
-
mv : 移动,相当于windows中的剪切功能
- mv a.txt b.txt : 重命名文件
- mv a.txt day1 : 把文件移动到某个文件夹,名称不会变
- mv a.txt day1/b.txt : 把文件移动到某个文件夹,同时修改名称
- mv day1 day2 : 重命名文件夹,前提是day2不存在
- mv test test1 : 把目录移动到另一个目录下,前提是test1已经存在
-
>: 输出重定向- 默认情况,所有的命令返回的结果都是输出到终端的窗口中
- pwd > 1.txt : 把pwd返回的结果输出到文件中,会覆盖以前的内容
- pwd >> 1.txt : 把pwd返回的结果追加到文件中,不会覆盖以前的内容
-
cat : 查看文件内容
- cat a.txt : 把文件的内容输出到终端窗口中
- cat a.txt b.txt : 把多个文件的内容按照顺序输出到屏幕中
- cat a.txt b.txt > c.txt : 把多个文件的内容合并到新的文件中
-
more : 以分屏的方式查询内容,当文件内容多的时候使用
-
ls -l / >> test.txt : 生成一个内容比较多的文件
-
more test.txt : 从头显示一页,按回车键 翻一行,空格键 翻一页,b按键 往回翻页,q按键 退出
-
| : 管道,把前面命令输出的结果交给后面的命令
-
ls -al / | more : 把ls返回的比较多的内容交给more命令,more命令对ls返回的结果进行分页显示
-
grep : 搜索文本内容
- grep -n hello 1.txt : 在某个文件中查找内容,n代表显示行号,查询日志时用到
- grep -ni hello 1.txt : i代表忽略大小写
- grep -n '^h' 1.txt : 查找以h开头的内容
- grep -n 'h$' 1.txt : 查找以h结尾的内容
- grep -n hello /home -r : 在某个目录下查找所有的文件
- ll /etc/ | grep yum
-
find : 查找文件
- find . -name test.txt : 在当前目录下查找某个文件
- find . -name '*txt' : 在当前目录下查找txt文件,会遍历所有的子目录
- touch .filename 创建隐藏文件
-
cut:分割字符串
- -d 'sep':每行按字符口中分割
- -f 1:分割后的第1个字符
- cut -d '_' -f 1 text1.txt
-
tar : 打包命令 f选项必须在最后位置
- -c:创建压缩文件
- -x:解开压缩文件
- -v:显示压缩或解压的过程
- -C:解压到指定目录
- -z:用Gzip压缩或解压
- -j:用bzip2压缩或解压
- -f:放在参数最后一位,表示要压缩或解压的软件包名称
- tar cf test.tar 1.txt 2.txt abc : 打包命令,把多个文件打包到一个文件中
- tar tf test.tar : 显示tar包里面的内容
- tar xf test.tar -C test : 把tar包的内容解压到指定目录,需要保证目录已经存成,大写的C
-
chmod:修改文件或目录的权限
- chmod u+x script.sh 为文件所有者添加执行权限
- chmod g-w file.txt 移除所属组的写权限
- chmod o+r file.txt 为其他人添加读权限
-
chown:更改文件或目录的所有者和所属组
- chown newuser file.txt 将文件的所有者改为 newuser
- chown newuser:newgroup file.txt 将文件的所有者改为 newuser,所属组改为 newgroup
- chown :newgroup file.txt 只更改文件的所属组为 newgroup
- chown -R user:user /home/user/ 更改 /home/user/ 目录及其所有文件的所有者和所属组为 user
- chown --reference=example.txt file.txt 将 file.txt 的所有者和组设置为与 example.txt 相同
- -R:递归更改目录及其内容的所有者或组。
- --reference:将某个文件的所有者或组设置为参考文件的所有者或组
-
useradd:创建用户
- -m:自动创建用户的主目录(如 /home/username)。
- -s:指定用户的默认登录 Shell。
- -G:将用户添加到附加组中。
- -e:指定用户账户的到期时间。
useradd -m -s /bin/bash newuser- 创建一个名为 newuser 的用户,使用 /bin/bash 作为默认 Shell,并创建主目录 /home/newuser
useradd -m -G sudo,developers newuser-创建用户 newuser,并将其添加到 sudo 和 developers 组。
-
passwd:设置用户密码
passwd uwername为username设置或更改密码
-
groupadd:创建组
- groupadd groupname
-
usermod:添加用户到已有组
usermod -aG groupname username- 使用 -aG 选项将用户添加到指定组,不会覆盖用户的其他组。
-
groups username:查看用户的组信息
-
cat /etc/passwd:查看所有系统用户
-
cat /etc/group:查看所有系统组
-
userdel username:;删除用户
- userdel -r username:删除用户及其主目录
-
groupdel groupname:删除指定组
- 使用 -aG 选项将用户添加到指定组,不会覆盖用户的其他组。
定时执行任务
crontab 是 Linux 中用来定时执行任务的命令,通过定时调度系统 cron 运行。系统管理员或用户可以使用crontab 定义特定时间自动执行的任务,例如备份、日志清理、定期更新等
-
常用 crontab 命令
crontab -e编辑当前用户的定时任务crontab -l列出当前用户的所有定时任务crontab -r删除当前用户的所有定时任务crontab -u username -l查看指定用户的定时任务(需 root 权限)crontab -u username -e编辑指定用户的定时任务(需 root 权限)
-
crontab 定时任务的格式
每一行任务的基本格式为:
* * * * * command-
每个 * 代表一个时间字段,共 5 个字段,顺序如下:
-
分钟 0-59 每小时的第几分钟
-
小时 0-23 每天的第几个小时
-
日期 1-31 每月的第几天
-
月份 1-12 哪个月(1 = 一月)
-
星期 0-7(0 和 7 = 星期日)一周的哪一天
* * * * *:每分钟执行一次0 * * * *:每小时的第 0 分钟执行30 2 * * *:每天凌晨 2:30 执行0 8 * * 1:每周一早上 8:00 执行
-
-
crontab 工作中示例任务
- 每分钟执行脚本:
* * * * * /home/user/script.sh - 每天凌晨 2 点备份数据:
0 2 * * * /home/user/backup.sh - 每月 1 日凌晨 1:30 执行日志清理:
30 1 1 * * /home/user/log_cleanup.sh - 每周一上午 9:00 发送报告:
0 9 * * 1 /home/user/send_report.sh - 每隔 5 分钟执行一次脚本:
*/5 * * * * /home/user/monitor.sh
-
特殊时间标志
除了使用时间字段,还可以使用以下特殊标志:
@reboot -系统重启后立即执行@yearly 0 0 1 1 *每年 1 月 1 日 00:00 执行@monthly 0 0 1 * *每月 1 日 00:00 执行@weekly 0 0 * *0 每周日 00:00 执行@daily 0 0 * * *每天 00:00 执行@hourly 0 * * * *每小时执行一次
示例:
@reboot /home/user/startup.sh在系统重启后立即执行 startup.sh。
-
日志和调试
查看 cron 的执行日志:
cat /var/log/cron | grep cron
- 调试脚本的输出:
- 将输出和错误日志重定向到文件:
* * * * * /home/user/script.sh >> /home/user/script.log 2>&1
- 将输出和错误日志重定向到文件:
- crontab 使用注意事项
- crontab 环境变量问题:cron 执行时不会加载用户的环境变量。建议在脚本中手动设置路径:
PATH=/usr/local/bin:/usr/bin:/bin - 定时任务中的权限:普通用户只能编辑自己的 crontab,而 root 用户可以编辑任意用户的 crontab。
- 删除 crontab 任务
- 删除所有定时任务:
crontab -r - 仅删除某一行任务:使用
crontab -e进入编辑模式,手动删除对应的行即可。 - 实时查看文件最后10的内容,这个命令用来看实时的日志是最好的:
tail -n 10 -f timestamps.txt
一些特殊的执行策略
-
每月特定日期执行 假设你想在每个月的 1 号和 15 号执行某个任务,可以使用以下格式:
0 0 1,15 * * /path/to/your/script.sh,这个命令将在每个月的 1 号和 15 号的午夜(00:00)执行脚本。 -
每周特定日期执行 如果你想在每周的星期一和星期四执行某个任务,可以这样设置:
0 12 * * 1,4 /path/to/your/script.sh这个命令将在每周的星期一和星期四中午 12 点执行脚本。 -
结合使用 如果你希望每个月的 1 号和 15 号,以及每周的星期一和星期四都执行,可以使用两个不同的 cron 任务,
分别写入 crontab:
0 0 1,15 * * /path/to/your/script.sh# 每月 1 号和 15 号0 12 * * 1,4 /path/to/your/script.sh# 每周星期一和星期四
-
每月的最后一天执行
如果需要在每个月的最后一天执行,可以使用:
59 23 28-31 * * [ "$(date +\%d -d tomorrow)" == "01" ] && /path/to/your/script.sh,这个命令将在每个月的 28、29、30 和 31 日的 23:59 执行,并检查明天是否是 1 号,从而确定今天是否是最后一天。 -
每天的特定时间范围内每小时执行
如果你想在每天的 9 点到 17 点之间每小时执行一次,可以使用:
0 9-17 * * * /path/to/your/script.sh
执行定时脚本
- 新建sh文件,第一行输入
#!/bin/bash,后面是命令 - 赋予执行权限
chmod +x *.sh - 设置定时任务
crontab -e输入* * * * * /path/test.sh >> /path/log1.txt 2>&12>&1表示将错误输出也重定向到 log1.txt
Wget命令
Wget是一个命令行工具,用于从互联网下载文件。
wget http://example.com/file.tar.gz,下载指定 URL 的文件wget -O new_name.tar.gz http://example.com/file.tar.gz,以指定文件名保存下载内容wget -b http://example.com/file.tar.gz,在后台下载文件wget -c http://example.com/file.tar.gz,断点续传下载,支持中断后继续wget -r -np -k http://example.com,递归下载整个网站,转换链接为本地文件路径wget --limit-rate=100k http://example.com/file.tar.gz,限制下载速度为 100KB/swget -e use_proxy=yes -e http_proxy=proxy_server:port http://example.com/file.tar.gz,使用指定代理服务器下载文件
实战示例
rpm包查询:www.rpmfind.net/linux/rpm2h…
sudo yum install wget -y,使用 YUM 安装 wget 工具wget https://www.rpmfind.net/linux/fedora/linux/development/rawhide/Everything/aarch64/os/Packages/h/htop-3.4.1-2.fc43.aarch64.rpm,下载htop RPM 包31wget https://www.rpmfind.net/linux/fedora/linux/development/rawhide/Everything/aarch64/os/Packages/h/htop-3.3.0-4.fc41.aarch64.rpm
RPM相关命令
RPM(Red Hat Package Manager) 是 Red Hat 系的包管理工具,用于管理 RPM 格式的软件包。我们通过 RPM 命令来安装、查询、卸载和验证软件包。
rpm -ivh package.rpm, 安装 RPM 包,显示详细信息和进度条rpm -Uvh package.rpm,升级 RPM 包,如果包不存在则进行安装rpm -e package_name,卸载 RPM 包(注意这里是包名而不是文件名)rpm -qa | grep package_name,查询已安装的 RPM 包,并使用 grep 过滤结果rpm -ql package_name,列出指定 RPM 包安装的所有文件rpm -V package_name,验证 RPM 包的完整性,检查是否被篡改
YUM相关命令
YUM(Yellowdog Updater, Modified) 是一个高层包管理器,它依赖 RPM,但具备自动解决依赖的能力。
yum makecache,更新 YUM 缓存,加速后续的软件包安装yum list available,列出所有可用的软件包yum install package_name -y,安装指定的软件包,并自动确认所有提示yum reinstall php-fpm或者yum update -y,更新系统中已安装的所有软件包yum remove package_name -y,卸载指定的软件包,并自动确认所有提示yum search package_name,查找包含指定名称或描述的软件包yum info package_name,查看指定软件包的详细信息yum clean all,清除所有缓存文件,释放磁盘空间
安装htop
yum install htop或者yum localinstall htop-2.2.0-1.el7.x86_64.rpm -y
解释:
- localinstall:从本地路径安装 RPM 包。
- -y:自动确认所有提示,避免手动交互。
特点:
- 解决依赖问题:YUM 会自动检查并下载 RPM 包所需的依赖项。
- 更智能:即使是本地安装,YUM 也会查询线上仓库以确保所有依赖都能满足。
- 推荐使用:适用于需要处理复杂依赖的软件包。
区别总结
进程相关命令
ps aux,查看所有进程的详细信息ps -ef | grep process_name,查找特定进程(通过名称过滤)top,实时显示系统的进程状态(CPU、内存使用情况等)htop,更友好的进程监控工具(需要安装) yum install htopkill -9 pid,强制终止指定进程(pid 是进程 ID)pkill -f process_name,通过进程名终止进程
网络配置相关命令
dhclient从dhcp服务器获取动态ip地址ip a,查看网络接口和 IP 地址信息ifconfig,查看和配置网络接口(可能需要安装 net-tools)ping -c 4 8.8.8.8,测试网络连通性(向 8.8.8.8 发送 4 次 ping 请求)nslookup example.com,查询域名的 DNS 信息traceroute example.com,跟踪数据包到目标的路由(需要安装 traceroute)nmcli d,使用 NetworkManager 查看网络设备状态nmcli con show,列出所有网络连接nmcli con up "your-connection",启用指定的网络连接nmcli con down "your-connection",禁用指定的网络连接
服务管理相关命令
systemctl status mysqld,查看特定服务(如 MySQL)的运行状态systemctl list-units --type=service,列出所有已加载的服务systemctl start service_name,启动指定服务systemctl stop service_name,停止指定服务systemctl restart service_name,重启指定服务systemctl enable service_name,设置服务开机自启systemctl disable service_name,禁止服务开机自启systemctl status service_name,查看服务的状态journalctl -u service_name,查看特定服务的日志
防火墙相关命令
firewall-cmd --state,查看防火墙状态(是否正在运行)firewall-cmd --permanent --zone=public --add-port=3306/tcp,永久开放 3306 端口(MySQL 端口)firewall-cmd --permanent --zone=public --add-service=http,永久开放 HTTP 服务firewall-cmd --reload,重新加载防火墙配置firewall-cmd --list-all,列出所有开放的端口和服务firewall-cmd --permanent --remove-port=3306/tcp,永久移除开放的 3306 端口systemctl stop firewalld,停止防火墙systemctl disable firewalld,禁用防火墙开机自启
实战示例
- 重启网络服务 ,
systemctl restart network,如果网络有问题,重启网络服务 - 开放 22 端口并启用防火墙
firewall-cmd --permanent --zone=public --add-port=22/tcpfirewall-cmd --reload
- 查看 MySQL 服务状态并重启服务
systemctl status mysqldsystemctl restart mysqld
- 使用 ping 测试与 baidu 的连接
ping -c 4 baidu.com
配置网络
查看网络接口
ip addr show
手动配置网络接口
编辑网络配置文件(例如,/etc/sysconfig/network-scripts/ifcfg-eth0):
vi /etc/sysconfig/network-scripts/ifcfg-eth09
示例配置:
DEVICE=eth0
BOOTPROTO=none\static
ONBOOT=yes
IPADDR=192.168.1.100
NETMASK=255.255.255.0
GATEWAY=192.168.1.1
DNS1=8.8.8.8
DNS2=8.8.4.4
重启网络服务
systemctl restart network
测试网络连接
ping www.baidu.com
手动设置环境变量
临时设置环境变量
(仅在当前会话有效):
export VARIABLE_NAME=value
示例:
export MY_VAR="Hello World"
echo$MY_VAR
永久设置环境变量
(对所有用户有效):
编辑 /etc/profile 或者 /etc/environment 文件:
vi /etc/profile
添加以下行:
export VARIABLE_NAME=value
永久设置环境变量(对当前用户有效):
编辑用户的 ~/.bashrc 文件:
vi ~/.bashrc
添加以下行:
export VARIABLE_NAME=value
使更改生效
source ~/.bashrc
系统资源查看相关命令
- 查看 CPU 信息 ,
lscpu,列出 CPU 架构的详细信息,包括内核数量、时钟频率等 5 cat /proc/cpuinfo,查看每个 CPU 核心的详细信息- 查看内存使用情况
free -h,以人类可读的格式显示内存使用情况 12 cat /proc/meminfo,查看系统内存的详细信息- 查看磁盘使用情况,
df -h,以人类可读的格式显示磁盘分区使用情况 du -sh /path/to/directory,显示指定目录及其子目录的总大小lsblk列出所有块设备(磁盘)和分区fdisk -l,列出磁盘分区表- 查看 I/O 性能,
iostat,显示 CPU 使用率和设备的 I/O 统计信息(需要安装sysstat包) iotop,实时显示每个进程的 I/O 使用情况(需要安装iotop)- 查看网络使用情况,
ifconfig,显示网络接口信息(需要安装net-tools) ip a,查看 IP 地址和网络接口状态netstat -tulnp,显示当前正在监听的端口和服务(需要安装net-tools)ss -tuln,显示正在监听的端口,功能类似于netstatnload,实时显示网络流量信息(需要安装nload)- 查看系统负载,
top,实时显示系统的 CPU、内存使用情况及运行的进程 htop,更友好的进程监控工具,提供更直观的界面(需要安装htop)uptime,显示系统的运行时间、登录的用户数量、系统平均负载- 查看系统整体信息 ,
uname -a,显示内核版本、系统架构等信息 hostnamectl,显示主机名及操作系统信息dmesg | less,显示内核的引导和诊断信息- 查看系统日志,
journalctl -xe,查看系统日志,尤其是错误日志 tail -f /var/log/messages,实时查看系统日志文件的最新日志- 查看系统资源占用情况(内存、CPU、硬盘等),
vmstat 1 5,每秒刷新一次,显示系统整体的 CPU、内存、IO、进程状态 sar -u 1 5,显示 CPU 使用情况(每秒刷新一次,显示五次,需安装sysstat)- 查看 swap 交换区的使用情况,
swapon --show,显示所有已启用的交换区 free -h,查看 swap 交换区的大小和使用情况- 查看系统温度和硬件信息 ,
sensors,显示 CPU、风扇等硬件的温度(需要安装lm_sensors并运行sensors-detect) inxi -Fx,显示系统硬件的详细信息(需要安装inxi)
实战示例
- 查看 CPU、内存、磁盘的整体使用情况
lscpu查看 CPU 详细信息free -h查看内存使用情况df -h查看磁盘使用情况
- 实时查看系统资源占用情况
top实时查看进程及资源使用情况htop使用更直观的工具查看资源使用
- 查看磁盘分区及挂载情况
lsblk查看块设备和分区fdisk -l查看分区表信息
- 查看网络使用情况
ifconfig查看网络接口信息ss -tuln查看当前监听的网络端口
- 查看系统运行时间和负载
uptime,查看系统运行时间及平均负载
- 查看系统日志和内核诊断信息
dmesg | less查看内核日志journalctl -xe查看系统日志和错误日志
查看端口是否被占用并杀掉占用进程
-
查看端口是否被占用
使用 netstat 或 ss 命令来查看指定端口是否被占用。
netstat -tuln | grep :8080或者ss -tuln | grep :8080参数:
- -tuln:显示所有TCP和 UDP端口的监听状态
- grep:8080 :过滤出8080端口的占用情况
-
查找占用该端口的进程PID
使用lsof或者netstat查看占用该端口的进程ID(PID)
lsof -i :8080或者netstat -tulnp | grep :8080参数:
- lsof -i:8080 :查看占用8080端口的进程信息 ,-i参数指定端口
- netstat -tulnp:显示监听的端口并包括进程ID(PID)信息
输出示例
这里,1234 就是占用该端口的进程 ID。
-
杀掉占用该端口的进程
使用kill命令终止进程
kill -9 1234kill -9 强制终止进程ID为1234的进程
查看IP地址并修改为静态或动态IP
场景:你需要配置一台测试机的网络接口,查看当前的 IP 配置,并根据需要修改为静态或动态 IP。
-
查看当前的IP地址
使用 ip addr 或 ifconfig 命令查看当前的IP配置
ip addr show或者ifconfig解释:ip addr show 会列出所有网络接口的 IP 地址。如果你需要查看某个特定接口的 IP,可以指定接口名,例如
ip addr show eth0。 -
修改为静态IP配置
编辑网络配置文件来设置静态 IP 地址。以 CentOS 为例,配置文件位于
/etc/sysconfig/network-scripts/ifcfg-eth0。
打开文件进行编辑sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0修改内容,设置静态 IP 地址:
TYPE=Ethernet1 BOOTPROTO=static2 IPADDR=192.168.1.1003 NETMASK=255.255.255.04 GATEWAY=192.168.1.15 DNS1=8.8.8.86 ONBOOT=yes- BOOTPROTO=static:设置为静态 IP 配置。
- IPADDR:静态 IP 地址。
- NETMASK:子网掩码。
- GATEWAY:默认网关。
- DNS1:DNS 服务器地址。
-
重新启动网络服务使配置生效
修改完成后,重新启动网络服务:
sudo systemctl restart network解释:使用 systemctl 重新启动网络服务以使新的配置生效。
-
查看新的IP地址
使用 ip addr show 或 ifconfig 命令再次检查,确认 IP 是否已成功修改:
-
修改为动态IP配置
如果你想恢复为动态 IP(通过 DHCP 获取 IP 地址),只需将配置文件
/etc/sysconfig/network-scripts/ifcfg-eth0中的 BOOTPROTO 改为 dhcpsudo vi /etc/sysconfig/network-scripts/ifcfg-eth0BOOTPROTO=dhcp然后重新启动网络服务
sudo systemctl restart network
查看磁盘使用情况并清理日志文件
场景:测试过程中,服务器磁盘空间不足,需要查看磁盘使用情况,并清理不必要的日志文件。
-
查看磁盘使用情况 使用 df 命令查看磁盘空间的使用
df -h- -h:以易读的方式显示磁盘使用情况(例如 GB、MB)。 输出示例
说明:根分区 / 已使用 40G,剩余 10G。
-
查看某个目录下的文件大小 使用du命令查看指定目录的磁盘占用情况:
du -sh /var/log/*- -s:仅显示每个目录的总计
- -h:以易读的方式显示大小
-
清理不必要的日志文件
如果发现日志文件占用了大量磁盘空间,可以使用 rm 删除不再需要的日志文件,例如:
sudo rm -f /var/log/old_log_file.log -
清空日志文件
如果希望保留日志文件,但清空文件内容,可以使用:
sudo truncate -s 0 /var/log/large_log_file.log解释:truncate 用于将文件大小设置为 0,从而清空文件内容。
Postman
环境变量{{x}}
常用内置变量:
- 时间戳:
{{$timestamp}} - 生成0-1000的随机整数:
{{$randomInt}} - 生成一个GUID的字符串:
{{$guid}} - 生成一个随机UUID:
{{$randomUUID}} - 说明:内置变量和Environment、Collection变量一样,只是它是内部已经定义好的,可以直接在请求参数和脚本中引用。
- 内置变量参考: Use dynamic variables to return randomly generated data | Postman Docs
script脚本
Postman 包含一个基于Node.js的强大的运行时,允许您向请求Request、Collection和Folder添加动态行为,这允许您编写测试套件,构建可以包含动态参数的请求,在请求之间传递数据等等。
执行流程的2个脚本事件:
pre-request script:请求前脚本,在请求接口前执行。
test script:测试脚本,在请求接口并响应数据后执行。
脚本使用:设置、删除和获取变量
//设置Collection变量
pm.collectionVariables.set("variable_name", "variable_value");
//设置Global变量
pm.globals.set("variable_name", "variable_value");
//设置Environment变量
pm.environment.set("variable_name", "variable_value");
//删除Collection变量
pm.collectionVariables.unset("variable_name");
//删除Global变量
pm.globals.unset("variable_name");
//删除Environment变量
pm.environment.unset("variable_name");
//获取变量(包括Global,Environment和Collection),同名变量,按照优先级获取
pm.variables.get("variable_name");
//获取Global环境变量
pm.globals.get("variable_name");
//获取Collection环境变量
pm.collectionVariables.get("variable_name");
//获取Environment环境变量
pm.environment.get("variable_name");
获取请求参数
//脚本使用:获取请求参数
//raw请求方式
let body = pm.request.body.raw;
let data = JSON.parse(body);
//form-data请求方式
let param = pm.request.body.formdata.get("variable_name");
// x-www-form-urlencoded请求方式
let param = pm.request.body.urlencoded.get("variable_name");
获取响应数据
//解析JSON
const responseJson = pm.response.json();
//解析xml
const responseXml = xml2Json(pm.response.text());
//解析csv
const parse = require('csv-parse/lib/sync');
const responseCsv = parse(pm.response.text());
//解析HTML
const temp = cheerio.load(pm.response.text());
console.log(temp.html());
// 测试响应体是否包含某个字符串
pm.test("Body contains string", () => {
pm.expect(pm.response.text()).to.include("customer_id");
}
脚本使用:MD5、AES、SHA256加密
//MD5
let token = CryptJS.MD5("文本内容").toString();
//SHA256加密
let token = CryptJS.SHA256("文本内容").toString();
//AES加密
function AesEncrypt(data, secret_key){
//密码,文本,偏移量、模式等设置
var ECBOptions = {mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7};
//加密密钥
var AesSecert = CryptoJS.enc.Utf8.parse(secret_key);
//AES加密
return CryptoJS.AES.encrypt(data, AesSecert, ECBOptions).toString();
}
//AES解密
var ECBOptions = {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
};
function decrypt(data, secret_key) {
var AesSecert = CryptoJS.enc.Utf8.parse(secret_key);
return CryptoJS.AES.decrypt(body, AesSecert, ECBOptions).toString(CryptoJS.enc.Utf8);
}
sendRequest请求接口
当我们在请求某个接口时,需要先从另一个接口获取需要的数据,或者在请求某个接口后再请求其他
接口,这个时候就可以使用sendRequest。
pm.sendRequest(param, function(err, response){
//进行其他操作(也可以再次调用sendRequest)
});
param:请求接口信息(包括但不限于请求路径、请求头和请求方式)。
err:接口异常信息。
response:接口响应数据.
注意:没指定请求方式默认是Get请求。
Get请求
//无参数无Header请求
pm.sendRequest("http://127.0.0.1:8090/demo/goods/list", function(err, resp) {
console.log(resp.json());
});
//携带Header请求
const param = {
//请求路径
url: 'http://127.0.0.1:8090/demo/goods/list',
//请求方式
method: 'GET',
//请求头
header: {
'token': '9e11562e553b4f56af43a1e81dcbb137'
}
};
pm.sendRequest(param, function(err, resp) {
console.log(resp.json());
});
//携带参数请求:在请求路径后面用?号拼接,多个参数用&分隔
pm.sendRequest("http://127.0.0.1:8090/demo/goods/list?id=123&name=小馒头",
function(err, resp) {
console.log(resp.json());
});
//携带参数携带Header请求
const param = {
//请求路径
url: 'http://127.0.0.1:8090/demo/goods/list?id=123&name=小馒头',
//请求方式
method: 'GET',
//请求头
header: {
'token': '9e11562e553b4f56af43a1e81dcbb137'
}
};
pm.sendRequest(param, function(err, resp) {
console.log(resp.json());
});
Post请求
Post请求和Get不同,请求参数在Body里,而Body有raw、x-www-form-urlencoded、form-data、xml模式。
raw模式
Content-Type设为application/json。
header: {
'Content-Type': 'application/json'
}
body的model设置为raw。
body: {
mode: 'raw',
raw: JSON.stringify({"data":{"name":"青云爱购物"}})
}
注意:raw的属性格式是{"key1":"value1","key2":"value2"},JSON格式。
示例:
定义请求入参
const jsonParam = {
"data": {
"name": "青云"
}
};
//定义请求参数
const reqData = {
url: 'http://127.0.0.1:8090/demo/goods/info',
method: 'POST',
header: {
'Content-Type': 'application/json',
'signature': '0cc4d99e4d9941d19c324de7881b6a98'
},
body: {
mode: 'raw',
raw: JSON.stringify(jsonParam)
}
};
//发送请求
pm.sendRequest(reqData, function(err, resp) {
console.log(resp.json());
});
登录接口设置变量
在body里使用
返回数据的测试
测试结果
pm.test("get my token", function () {
var jsonData = pm.response.json();//获取返回体数据
var my_token=jsonData.token//获取json里的token数据
//把my_token变成环境变量让所有测试脚本都可以使用
pm.environment.set("my_token",my_token)
//断言返回体中的nickname数据与某个字符串是否相等
pm.expect(jsonData.nickname).to.eql("qqqqq")
if(my_token){
console.log("token 不为空")
}else{
console.log("token 为空")
}
});
postman接口自动运行
面试
什么是缺陷验证?你在验证缺陷修复时会采取哪些步骤?
回答:
缺陷验证是指在开发人员修复缺陷后,测试人员通过重新运行相关的测试用例,确保缺陷确实被修复。
验证的过程包括:
- 确认测试环境与发现缺陷时的一致性。
- 复现原有的缺陷,并验证是否修复成功。
- 执行回归测试,确保修复的代码没有引入新的问题。
- 如果验证通过,则关闭缺陷;如果未通过,则重新打开缺陷并提交进一步修复请求。
问题描述:你在测试过程中发现了一个偶现的bug,并提交了相应的bug。然而,开发人员和你自己再也无法复现这个问题。作为测试人员,你会如何处理这种情况?
回答思路:
- 回顾并检查提交的bug报告
- 描述是否清晰完整: 检查自己提交的bug报告,确认是否包含了充分的细节,包括问题发生的步骤、预期结果与实际结果、环境设置、输入数据等。如果报告不够详细,可能是问题难以复现的原因。
- 提供相关日志、截图或录屏: 如果可以,提供更多的辅助信息,如应用日志、错误截图或录屏,帮助开发人员理解问题的发生。
- 分析环境和配置
- 检查测试环境和配置: 确认问题发生时的系统配置、网络条件、浏览器或设备类型等。如果环境或配置有变化,可能导致问题无法再现。尝试在不同环境下再次执行测试,观察是否会复现问题。
- 操作系统和软件版本: 确认操作系统、浏览器、应用等相关软件的版本,是否与问题发生时一致,特别是在多平台测试时。
- 回顾测试过程中所有的操作步骤
- 逐步回顾操作: 再次执行当时的测试步骤,确保每个细节都被准确回顾。特别注意不常见的操作顺序或非正常操作(如快速点击、网络延迟等),因为偶现问题可能是由特殊的操作引发。
- 考虑其他操作干扰: 回顾当时是否有其他的后台操作、并发请求或其他可能引发bug的干扰因素。
- 利用日志或监控工具深入分析
- 查看系统日志: 检查服务器端、客户端的日志记录,是否有未捕获的异常或警告信息,这些都可能成为复现问题的关键线索。
- 启用调试模式: 如果可能,在系统或应用中启用调试模式,以便更详细地记录运行时的状态,便于分析和跟踪问题。
- 与开发人员沟通,尝试不同的复现方法
- 与开发团队协作: 主动与开发人员合作,讨论可能的根源和触发条件。通过分析代码逻辑,尝试找到某些特定条件下才会触发的问题。
- 使用自动化工具: 如果问题涉及到并发或压力情况,可以使用自动化测试工具或压力测试工具来反复模拟用户操作,增加复现问题的可能性。
- 考虑时间和系统状态的变化
- 时间依赖性: 有些问题可能与时间相关,比如定时任务、缓存刷新、过期数据等。回顾问题发生的时间段,检查是否存在时间依赖的因素。
- 系统负载: 检查系统负载,当时是否存在高并发、服务器过载等情况导致问题偶然发生。
- 保持问题的跟踪与记录
- 不关闭问题: 在无法复现问题的情况下,建议暂时不要关闭bug,而是将其标记为“待观察”或“无法复现”,保持对问题的追踪记录。如果问题再次发生,补充新的证据和细节。
- 定期复测: 将问题纳入到回归测试中,定期执行相应的用例,确认是否再次出现
一个bug是前端问题还是后端问题
显而易见是前端的问题情况
前端页面布局问题,图片排版不合理,文字太长显示不合理,不同分辨率下的布局有问题。字体大小 字体样式有问题 和设计图不一致
不好判断是前后端问题的情况
从前端发送请求,后端接收请求并返回数据,前端接收到数据并显示,网页右键检查网络模块的
Fetch/XHR请求,查看请求参数是否正确请求,如果没有正确请求是前端的问题,如果正确请求了,观看后端是否正确返回数据,没有正确返回数据,则进行排查。第一步:进行数据库查询,确定数据库里是否有数据;第二步:请求参数和数据库里的id,name等字段名称是否一致;前端没有正确传参是前端问题。如果正确返回了,那么是前端没有正确显示的问题。
一种场景: 商城页面,搜索一个商品,结果页面返回一个商品不存在的情况? (我确定这个商品是的的确确存在的)
数据库结构
接口文档标准
测试过程:手动搜索,并查看devtool-network 发现了接口如下GET /search?pid=100 200 OK
返回数据为null
首先你可以通过数据库去确定 是否存在pid=100的商品 id 100 iphone
接口文档说明 该接口需要传递参数 ProudctId(int)
以上可以判断此次bug属于前端请求时的参数使用错误 修改为
GET /search?ProudctId=100 200 OK。返回数据为 {"pname":"iphone16"}
有没有漏测
登录界面的验证码不显示,登录流程已经测试过了,自动化也通过了,发现一个问题,测试环境与真实环境有一个区别,就是测试环境中没有开启验证码验证机制。发现环境配置在上线前的验证非常关键,于是立刻把这项列入上线前的checklist中,保证每一次都会对他进行一次检查,还写了很多自动化测试用例,尤其是在不同环境进行了动态检测。以免类似的问题再次发生。
如何设计测试用例
- 第一步
- 吃透需求文档
- 再拆解用户的使用场景
- 最后转化成测试用例
- 第二步
- 等价类划分正常流
- 边界值卡极端的情况
- 错误推测搞破坏
- 状态迁移跟着流程走
- 举例(登录模块)
- 有效类:正确账号和正确密码去登录
- 边界值:密码16位,测试15或17位
- 错误推测:sql注入
- 状态迁移:锁定后找回密码的流程
介绍公司的测试流程
一:需求分析与评审阶段:
- 项目启动时,产品经理会输出产品求文档(PRD)和原型图。
- 测试团队会积极参与需求评审会议,与产品、开发一起计论需求的合理性、可测性、潜在风险和逻辑漏洞。
- 目标是确保需求清晰、无歧义、可衡量,并在早期识别测试范制和可能的问题点。
二:测试计划与设计阶段
- 需求基线确定后,测试团队会深入理解产品需求,并基于项目整体排期制定详细的测试计划(包括测试范围、策略、资源、进度、风险等)。
- 测试负责人会根据模块划分测试任务。
- 各测试工程师负责编写所负责模块的详细测试用例,覆盖功能、边界、异常等场景
- 所有测试用例完成后,会组织测试用例评审会议,检查用例的完整性、准确性和可执行性,查漏补缺并优化用例
三:执行测试阶段:
- 开发人员完成模块开发并提测后,测试团队即开始执行测试
- 模块测试
- 回归测试
- 集成测试
- 系统测试
四:发布准备与验收阶段:
经过多轮测试、回归,当系统达到预定的质量目标(如关键bug清零、遗留风险可控)后,进入发布准备阶段
- 验收测试:通常由产品经理、业务方或最终用户代表进行,从业务角度验证系统是否符合预期需求。测试团队提供支持。
- 发布评审:测试团队输出测试报告,总结测试过程、缺陷分析、质量评估和发布风险,供项目组决策是否上线
五:上线与后续:
- 项目通过验收和发布评审后,按计划上线部署
- 上线后通常会有线上监控和一段时间的线上验证,确保生产环境运行稳定
兼容测试时测试机不够怎么办
- 盘活现有资源,再用手头的测试机覆盖核心机型,借同事和自己的手机
- 抓用户反馈:锁定一些核心的高危的机型,真实用户反馈了某些机型会发生崩溃闪退等现象,那这类机型优先测试。结合市场数据,如公司用户机型top10,优先覆盖占比比较高的机型
- 把核心的兼容性测试用例,如(启动、登录、支付这些路程自动化脚本)利用晚间空间时间来跑自动化测试
- 云真机平台:如test in和v test ,各种机型做远程测试
做接口测试时,要不要对数据库断言
- 因为很多接口的操作最后都会变成对数据库的操作,光看接口的返回数据是不够的,需要看数据库的数据是否被修改,并且是符合预期的
- 在实际的测试环节里,频繁的查询数据库会拖慢性能,只有在关键用例(比如核心的业务接口,会改变数据库状态的用例)的时候才做断言
公司的自动化框架是你搭建的吗
搭建的时候选择用python的pytest框架,接着是创建pytest的项目目录,初始化空的pytest的pytest.ini配置文件,然后按钮功能或者模块,去划分了目录,设计了测试用例的一些组织结构,再就是写一些测试用例类,还有一些基类,把一些注册、登录数据库操作这些通用的逻辑封装起来,在测试数据方面的话,我们用csv文件或者是数据库来存储和读取,同时的话,配置数据库的链接,还会配置api接口等测试环境,还写了脚本把那些测试结果生成了html的报告,另外也集成了像日志记录,邮件通知这些工具,可以让我们这个测试框架跑的更顺畅,然后结果也更直观。
工作中是如何跟进bug的
首先新建bug指派给开发人员,并确定开发人员已经确定了bug的状态,如果长时间没有人确定bug的状态,就要去及时的去询问是什么原因,可以直接询问,也可以在会上询问bug的进程,接下来当开发对bug进行确认后,bug在修复后进行等验证的状态,那么我在版本更新的时候会对bug进行验证,如果验证bug修复,会关闭bug,如果验证没有修复成功我会重新打开,在开发确认修复进行新一轮的验证,直到bug修复验证关闭。期间也会出现其他的状态,比如延期、拒绝等,对于这些状态我会及时的和开发沟通,和产品经理确认,保证问题不会被遗漏或问题被错误的修改状态
简述postman测试接口的过程
用postman去做接口测试,简单来说,首先是要充分理解接口文档,然后并且去设计完成接口测试用例之后,就可以开始在postman去做操作了。
- 先做配置请求,我先填好接口地址,比如说我们做登录的测试,那么我们可能去测试login的这个接口,然后选取对应的一些方法,如果是post,我们就添加post方法,然后在headers里添加必要的值,比如说
content-type,它可能需要认定是application/json的这个类型的,然后再一个是body,在body里写一些json的参数,比如说账号密码这些,然后还可以根据设计的接口测试用例去添加对应的参数,包括去测试一些边界值,一些异常值。 - 添加断言,在test里去写检查点,去验证一些必要的检查点,比如说验证他的状态码是不是200,然后验证这些关键的数据是否是存在的或者是否是正确的,然后再一个可以验证一些性能方面的一些相关的东西,包括它的响应时间是否是高于一个阀值。
- 可以获取变量设置全局变量,以登录为例,可以提取token,然后把它存储成全局变量,这样的话后续的一些接口可以直接调用这个token,就可以直接执行
- 可以使用runner进行批量执行,选择测试集,然后可以设置一个迭代的次数,就可以模拟多人操作,可以做一个简单的性能测试
http请求的常用方法有哪些
- get:用于从服务器获取数据,get方法只是获取数据,它不会对服务器的资源数据有任何影响,它的特点是参数是在url里可见的,长度是有限制的,不能修改数据,比如说我们在网页查询商品信息,查询商品列表的时候会用到get
- post:典型的一些场景就是用于注册、上传文件,post的这个方法是用来去提交数据的,它的特点是,它的参数是藏在这个body里面的,所以它会更安全,而且它会去传大的一些数据
- put:是用来更新服务器上是一些资源,比如修改用户的所有信息
- delete:就是删除信息、服务器上的资源
给你一个app,怎么测试
首先是基础功能的验证,包括一些安装与卸载,首次安装、覆盖安装,强制卸载有没有问题,再一个是核心功能的验证,那这可以包含像正向路径、逆向路径、中断这样的测试,比如支付的时候来电或者切到后台,那返回的时候这个流程能不能继续恢复。再一个就是数据一致性,本地操作后,这个数据能同步到云端,再有就是时间敏感的操作,就是切换时区后,订单的这个时间能不能校准。第二个就是移动端的专项测试,这可以包含像兼容性测试,包括像操作系统维度的测试,还有分辨率的一些适配,再一个就是弱网与网络的一些切换,使用一些抓包工具,去模拟一些2g,3g这些丢包率延迟率比较高的场景,看一下是否会有异常,接下来可以去验证这个权限管理,比如拒绝定位后,地图能不能正常使用,比如拍照的一些权限,再一个就是资源的占用,是否有内存泄露,CPU过载,还有就是耗电这个方面。第三个就是异常的场景的覆盖,比如说输入框里输入一些超长字符或者特殊字符,然后文件上传,可以上传空文件,比如说一些超大的文件,看是不是有崩溃的情况,再一个就是环境异常,比如说时区的切换,字体的放大是否会导致页面的一些错位,再一个就是存储的写满,当我们的手机系统空间不足时,是不是会有异常,还有就是安全的测试,我们可以进行抓包,去修改里面的数据,会不会有经过一些校验,再一个就是本地的数据在本地的app里面的信息是否有明文存储的风险。第四就是自动化与效率的提升,可以用appium去覆盖主流程的一个测试,在兼容性方面可以去云平台测试一些主流机型。第五是性能方面的测试,就是页面的渲染时间,可以使用adb来测试,比如页面的打开时间、渲染时间,这样可以验证性能是否合格。
web测试与app测试的区别
- 第一点是测试环境的复杂度,web主要关注浏览器的兼容性,比如像chrome,edge,还有分辨率的适配,另外一个像app这边,就需要覆盖设备型号,比如华为、小米、苹果,在系统版本的话像ios,安卓,屏幕尺寸也是需要关注的
- 第二点就是性能测试的关注点,web这边主要关注核心指标页面加载时间,js执行效率,app这边除了页面加载时间,还需要关注内存泄露,电量消耗,安装与卸载时间
- 第三点是网络环境影响,web这边通过是wifi环境下测试,所以网络波动影响较小,像app要模块3g,4g,5g,wifi,弱网的场景,验证断网的重连,然后数据的缓存策略
- 第四点是测试工具的差异,web这边主流selenium,app这边要掌握appium,charles,
- 专项测试重点,像web侧重cookie,session的一些管理,浏览器回退的的一些按钮测试,app这边需要进行安装卸载测试,多任务切换测试
线上出现bug会怎么处理
- 首先的话快速联动开发,然后进行评估,第一时间找到开发团队,去结合线上日志、用户反馈,根据这些判断这个bug影响有多大,比如通过是不是核心功能用不了了,或者说影响了多少个用户来去判断,然后严重程度的话,我们把bug分成p0,比如致命的像交易崩溃的这种,比如p1的像严重的问题,但是还有替代方案的,定好处理的优先等级
- 第二就是分情况解决,首先是看一下影响大又难定位的功能性bug,比如说支付流程崩溃了,但是我们不知道是什么原因,类似这种问题,就是我们需要系统能够进行回滚,先回滚到上一个稳定的版本,赶紧止损,之后在测试环境模拟用户的操作,查日志调试代码,和开发一起找问题的根源。第二就是能快速定位的功能性bug,开发改好补丁代码,然后我会在测试环境做回归测试,确认修好没有新的问题之后,我们就走紧急的流程上线修复。第三种就是性能类的bug,比如页面加载变慢,那就先临时求场,比如采用扩容服务器,开缓存、限流,让用户能用核心功能,同时开发会分析这个瓶颈,是代码写的有问题,还是说资源不够,我们后面在排期进行优化。第四类就是小问题,比如说方案错了,就放到下一次版本去迭代修复,会记录bug在bug平台里面
- 最后就是收尾复盘,梳理在发现到解决问题过程中,哪里是能改进的,比如说优化监控,补测试用例
pom模式有什么好处
做ui自动化主要是python加selenium框架,因为python语法简单,selenium对浏览器兼容性都不错,而且社区丰富,这个框架设计模式用pom,也就是页面对象模型,我会把页面拆成一个独立的类,比如说登录页,它就是一个类,然后首页也可以放成一个类,每个类里面放页面的元素定位然后专属的一些操作,比如说登录页里面我会定义用户名输入框、密码输入框、登录按钮、验证码的定位方式,以及一个输入账号、点击登录这些测试的方法,测试脚本里只要调用这些类就可以了,不用关心具体的元素定位,包括元素操作的细节是怎么封装的。这么做第一可以保证低耦合,如果元素定位变了或者操作方式改变了,都不用改这个测试代码;第二个就是高复用,比如说登录的一些操作,很多用例都用到,那我可以把它写成一个方法,后面所有的测试用例可以直接调用就行了,不用重复写;第三个就是维护简单,因为它代码结构很清晰,不管谁来接手很快就可以用起来。
测试数据怎么来的
测试数据的来源主要是以下几个方面
- 首先,会从实际的业务场景中去获取数据,比如说从数据库里面,获取正常业务数据,然后日志数据啊,或者说通过接口返回的那些数据,确保这个测试的真实性
- 其次还可以使用数据生成工具,比如说像faker这种库,来去模块不同的类型,然后不同规模的一些数据,可以覆盖各种边界或者异常的一些场景。另外对于敏感信息的处理,我会进行一些脱敏后,再去使用,保证这个数据的安全,尤其像生产环境中的一些比较敏感的数据。
- 如果遇到不清楚数据来源,或者是没有授权,直接使用真实数据的情况的话,我会提前和开发还有产品进行沟通,获取必要的数据的一个样本,然后再利用数据模拟工具,自己去生成这样的数据。如果碰到一些更极端的情况,比如说没有办法事先获取到这种测试数据的话,我会手工设计这样的测试数据,然后要覆盖这些异常啊,边界啊常用情况等等,然后借助脚本去生成。
产品两天内上线,怎么测试
遇到这个情况,肯定不能抱怨,吐槽,要想办法解决。
1、这类的事情,我遇到很多次了,很多时候改bug,小优化,小需求的更新,我们都会在2~3天内测试加上线,首先是减少一些会议的召开,比如开发方案评审会议和测试用例评审会议,还有需求评审会议,可以把这三个会议合并成一个,在一个会议上一次性全部介绍完;其次是把编写完整测试用例的过程简化为只用xmind写测试点,然后测试过程中按照测试点执行,这样会节省很多时间。
2、确定需求的优先级,优先测试核心主干的需求,小需求和其他非主干流程放到下一个迭代作为优化需求,或者下一个迭代上。
3、测试过程中产生的bug,优先解决严重程度的,其他的不严重的尽量修改完验收,实在有一些界面bug,不影响用户使用的bug留到下个迭代再上。
4、可以调动人员,比如拉上运营,产品还有其他测试一起来测。后续如果他们需要人员,我也会去帮助他们。
5、把更多的时间放到接口测试过程中,因为接口测试做好了,主干核心的bug就少了很多,而且也少了很多的功能测试的bug。
6、中间让开发加班写代码自测,测试也要加班去测试和验收bug。(某些团队为了赶进度会把团队拉倒度假村别墅 吃住和工作都在一起 这种在封闭环境下集中工作的形式就是封闭开发和测试)
7、还可以完善自动化测试用例,把主干功能自动化掉,保障在测试左移过程中,节省回归测试的时间。
综上:全员加班!拉人帮我,减少会议,多写测试点,优先测试主干功能,优先改严重bug,核心做接口测试,最后完善主干自动化代码