测试岗面试
应用
接口测试如何定位bug
通过发送相同的请求数据来重现 Bug。如果问题随机出现,记录详细的请求和响应数据,寻找是否有特定的触发条件。
验证请求格式:确保请求的 Headers、Body、URL 参数的格式和内容符合接口要求。尤其是 JSON 格式、参数类型、长度等是否正确。
分析响应状态码:状态码比如 400(请求参数错误)、401(认证问题)、500(服务器错误)等。
检查响应数据:如果状态码为 200,但数据异常,可能是后端逻辑错误。查看响应内容和日志,确认数据是否符合预期。
查看服务器日志
浏览器开多个窗口是多线程还是多进程
现代浏览器开多个窗口通常是多进程而不是多线程的设计。主流浏览器(如 Chrome、Firefox、Edge)使用多进程架构来提高安全性和稳定性,具体的设计通常包括以下几个进程:
浏览器主进程:负责管理窗口、标签页、网络请求、用户输入等,并负责协调不同进程的通信。
渲染进程:每个标签页或窗口通常会分配一个独立的渲染进程。渲染进程负责 HTML、CSS 和 JavaScript 的解析、页面布局、绘制等工作。
插件进程:如果页面中需要使用插件(如 Flash),浏览器会为每个插件创建独立的进程。
网络进程:独立处理网络请求和数据加载,减少了资源冲突。
多进程的好处
稳定性:单个窗口或标签页的崩溃不会影响整个浏览器。
安全性:多进程隔离可以限制恶意代码的影响范围,降低跨站脚本攻击等风险。
内存管理:独立的进程允许浏览器更好地管理和释放资源,每个标签页关闭时相应的进程也会结束,回收内存。
登录页面怎么测
- 功能测试
正确输入:使用有效的用户名和密码,确认登录成功,并且正确跳转到登录后的页面。
错误输入:
输入错误的用户名或密码,检查是否会提示“用户名或密码错误”。
账户被锁定或禁用的情况下,验证登录是否会被拒绝,并显示相应的提示。
边界测试:
用户名和密码的长度、特殊字符、空格等输入边界。
处理空字段:不填写用户名和/或密码,查看系统响应。
多次失败测试:
- 测试多次输入错误的用户名或密码后,是否有锁定账户的功能,并检查是否有合适的解锁机制。
重置密码:检查是否提供“忘记密码”功能,以及是否能通过邮箱或手机正确地重置密码。
记住我:测试“记住我”功能,确认再次访问时无需重新登录。
安全性测试
SQL 注入:在用户名或密码字段输入 SQL 语句,验证是否能防止 SQL 注入攻击。
跨站脚本攻击 (XSS):在输入框中输入恶意脚本,检查是否会被过滤。
跨站请求伪造 (CSRF):确认是否有防止 CSRF 攻击的措施,如 CSRF token。
敏感信息加密:
验证密码在传输过程中是否加密,比如 HTTPS 传输。
检查 Cookie 和 Token 的存储是否安全,并确保不直接存储用户名和密码。
多设备登录限制:测试多设备或多浏览器登录的处理方式,看是否有防止并发登录或异地登录的机制。
验证码:如果启用了验证码,验证是否可以防止暴力破解攻击。
- 性能测试
响应时间:测试登录的响应速度,确保在正常负载下能快速响应。
并发测试:在高并发情况下测试登录系统的稳定性和响应时间,以确保不会导致系统崩溃。
压力测试:在极端负载下测试系统的承受能力,确认在超负载的情况下是否能正常拒绝请求,并返回友好的提示信息。
- 兼容性测试
浏览器兼容性:在不同浏览器(如 Chrome、Firefox、Safari、Edge 等)中测试登录功能,确保一致性。
设备兼容性:在不同设备(如 PC、手机、平板)上进行测试,验证页面在小屏幕上的显示和操作是否正常。
- 用户体验测试
界面设计:检查页面布局、元素间距、按钮和提示信息的易读性和友好性。
可用性测试:
登录按钮是否在输入完信息后自动激活。
登录表单是否提供清晰的提示信息。
错误信息:错误提示是否清晰友好,例如“用户名或密码错误,请重试”。
自动化测试:可以通过自动化脚本模拟多种登录场景,提升测试效率和覆盖率。
- 边缘场景测试
网络不稳定:在网络不稳定或断网的情况下尝试登录,验证系统的响应及提示。
多语言支持:如果页面支持多语言,测试在不同语言环境下的显示效果和功能是否正常。
频繁登录退出:反复登录和退出,检查系统是否有资源泄漏或响应变慢的情况。
测试售货机的支付功能怎么设计测试用例
一、测试用例设计
1. 功能性测试
用例 1:测试选择饮料并进行支付
输入:选择饮料(如可乐)、输入支付金额(如 5 元)
预期输出:支付成功,饮料成功出货
用例 2:测试支付不足
输入:选择饮料(如可乐)、输入支付金额(如 4 元)
预期输出:提示支付金额不足,无法购买
用例 3:测试支付成功但选择无效饮料
输入:选择饮料(如饮料已售罄)、输入支付金额(如 5 元)
预期输出:提示饮料售罄,退款成功
用例 4:测试取消支付
输入:选择饮料(如可乐)、选择取消支付
预期输出:取消成功,不扣款,返回主界面
2. 性能测试
用例 5:测试高并发支付
输入:多个用户同时选择同一种饮料并进行支付
预期输出:系统稳定响应,无崩溃,正确处理订单
3. 安全性测试
用例 6:测试无效支付方式
输入:选择饮料(如可乐)、输入无效的信用卡信息
预期输出:提示支付失败,返回主界面
4. 兼容性测试
用例 7:测试不同支付方式
输入:使用不同的支付方式(如现金、信用卡、移动支付)
预期输出:所有支付方式均可正常使用,且正确完成交易
二、问题排查
如果付款成功后,售货机没有饮料出来,可以按照以下步骤进行问题排查:
检查支付系统:
确认支付是否真正成功。查看支付系统的返回结果和日志,确认是否有交易记录。
检查支付状态是否更新,确认系统是否收到支付成功的通知。
检查售货机状态:
查看售货机是否有足够的库存。检查售货机内的饮料存量,确认所选饮料是否确实可用。
检查售货机的硬件状态(如出货口、投币口、显示屏等),确认是否有任何故障。
查看系统日志:
查看售货机和支付系统的日志,寻找任何异常或错误信息。
检查是否有系统异常,导致支付成功但未能触发出货。
执行重现测试:
- 重现问题,选择相同的饮料进行支付,确认是否能够稳定复现此问题,以便进行进一步分析。
联系支持团队:
- 如果以上步骤无法解决问题,联系技术支持团队,提供详细信息(如支付时间、饮料种类等),请求帮助。
多线程并发爬虫时,对url做去重
1.哈希表(HashSet) + 布隆过滤器(Bloom Filter)
哈希表:使用
ConcurrentHashSet
存储已经爬取的 URL。HashSet
提供常数级别的时间复杂度 O(1) 查询和插入操作,适合 URL 去重,但在大规模 URL 爬取中内存占用较高。布隆过滤器:布隆过滤器是一种基于哈希的空间效率极高的概率型数据结构,可以用于初步去重。它的特点是可以快速判断元素是否存在,查询时间复杂度接近 O(1)。布隆过滤器可以有效减少对
HashSet
的访问,降低内存消耗。
具体做法是将每个 URL 先经过布隆过滤器,如果布隆过滤器判断 URL 存在,再使用 HashSet
确认是否真的存在。
2.初始化布隆过滤器和哈希表
设置布隆过滤器的大小和哈希函数的个数。布隆过滤器的容量可以根据需要爬取的 URL 总数估计,尽量保证假阳性率较低。
初始化一个线程安全的
ConcurrentHashSet
来保存去重后的 URL 集合。
URL 检查与去重方法
方法接收每个新 URL,首先在布隆过滤器中检查,如果布隆过滤器判断该 URL 存在,则进行二次确认。
在
ConcurrentHashSet
中进一步确认,确保无误后再将新 URL 添加到ConcurrentHashSet
和布隆过滤器中。
3. 时间复杂度
布隆过滤器检查:查询复杂度接近 O(1),而且无锁,极大地提高并发效率。
哈希表检查:
ConcurrentHashMap
查询和插入操作平均为 O(1)。整体时间复杂度近似为 O(1)。
4. 空间复杂度
布隆过滤器:空间复杂度取决于布隆过滤器的位数组大小和哈希函数的数量,通常远低于直接存储所有 URL。
哈希表:
ConcurrentHashMap
存储去重的 URL 集合,空间复杂度为 O(N),其中 N 是 URL 数量。在内存受限或并发量极高的场景,可以考虑适当清理过期的 URL。
5.实现
import java.util.concurrent.ConcurrentHashMap;
import java.util.BitSet;
import java.util.concurrent.locks.ReentrantLock;
public class URLDeduplicator {
private final BitSet bloomFilter;
private final int bloomSize;
private final int[] hashSeeds;
private final ConcurrentHashMap<String, Boolean> urlSet;
private final ReentrantLock lock = new ReentrantLock();
public URLDeduplicator(int bloomSize, int[] hashSeeds) {
this.bloomSize = bloomSize;
this.hashSeeds = hashSeeds;
this.bloomFilter = new BitSet(bloomSize);
this.urlSet = new ConcurrentHashMap<>();
}
// URL hash function based on seed value
private int hash(String url, int seed) {
int hash = 0;
for (int i = 0; i < url.length(); i++) {
hash = hash * seed + url.charAt(i);
}
return Math.abs(hash % bloomSize);
}
public boolean isUnique(String url) {
// Check Bloom filter first
for (int seed : hashSeeds) {
if (!bloomFilter.get(hash(url, seed))) {
return true; // Not in bloom filter, likely unique
}
}
// If bloom says exists, check HashSet
lock.lock();
try {
if (urlSet.containsKey(url)) {
return false; // Confirmed duplicate
} else {
urlSet.put(url, true); // Add new URL
for (int seed : hashSeeds) {
bloomFilter.set(hash(url, seed));
}
return true; // Unique URL added
}
} finally {
lock.unlock();
}
}
}
设计个指标去评判电梯的调度机制
1. 平均等待时间
定义:所有乘客在发出请求到电梯到达之间的平均等待时间。
计算方式:记录每个请求的等待时间,最终对所有等待时间求平均。
意义:等待时间直接影响乘客的使用体验,平均等待时间越短,说明调度机制的响应速度越快。
2. 平均乘梯时间
定义:乘客从进入电梯到到达目标楼层之间的平均时间。
计算方式:记录乘客从进入电梯到到达目标楼层的时间,对所有乘梯时间求平均。
意义:在优化调度时,减少乘梯时间也是核心目标之一。平均乘梯时间越短,说明电梯在目标分配和运行路径上效率越高。
3. 请求响应率
定义:在特定时间内所有电梯响应的请求数量占总请求数量的比例。
计算方式:
请求响应率 = 成功响应的请求数量 / 总请求数量
意义:请求响应率反映了调度机制处理乘客请求的覆盖能力,数值越接近 100%,说明调度机制响应能力越强。
4. 电梯空载率
定义:电梯在运行过程中空载行驶的时间占总行驶时间的比例。
计算方式:记录每部电梯空载行驶的时间,求所有空载时间占电梯总行驶时间的比例。
意义:过高的空载率会增加电梯的能源消耗和资源浪费,而合理的空载率可以反映调度机制的资源分配合理性。
5. 拥挤度(负载均衡性)
定义:在特定时间窗口内,电梯的乘客数量方差,或最大负载电梯与最小负载电梯的负载差。
计算方式:记录每部电梯在某一时间段的平均负载人数,计算负载人数的标准差或最大最小差值。
意义:负载均衡程度高的调度机制可以合理分配乘客,避免某一电梯超载而其他电梯空闲,提升整体效率和用户体验。
6. 高峰期响应效率
定义:在早晚高峰期间(或指定高峰时段),调度机制的响应效果。
计算方式:分早高峰和晚高峰统计平均等待时间、请求响应率等指标。
意义:高峰期是电梯调度的重点难点,反映调度机制在高峰期的适应性和稳定性。
概念
测试开发本质
测试开发的本质是助力业务成功。
软件测试的意义
通过一系列测试活动,「提前」发现和定位软件产品质量的薄弱环节,并倒逼开发人员修正,从而保证交付的软件质量满足客户需求。
有研究表明,越早发现软件中存在的问题,开发费用就越低,软件质量越高,软件发布后的维护费用越低。因此,提前发现和定位问题极为重要,而在软件开发的整个历程中,越是新兴的软件开发模型,越重视「提前测试」。提前测试可以使得在需求分析时期就可发现的错误,不必等到开发完成才被发现。
测试开发流程
测试方法
- 冒烟测试(Smoke Testing):
冒烟测试是在软件开发的早期阶段进行的一种表面级功能验证测试。它主要用于确认软件的基本功能是否正常工作,以便在后续的测试阶段中能够进行更详细的测试。冒烟测试通常只验证最核心、最重要的功能,并不深入测试每个细节。
冒烟测试的目标是迅速检查系统是否满足最低程度的可接受性要求,例如是否能够启动、登录、基本功能是否可用。如果冒烟测试未通过,测试团队将不再投入更多时间和资源进行进一步的测试,而是返回给开发人员解决问题。
假设我们正在开发一个电商网站,核心功能包括用户注册、浏览商品、添加到购物车和下订单。在冒烟测试中,我们只需要验证这些基本功能是否正常工作。例如,我们可以进行以下验证:
用户注册:尝试注册一个新用户,并确认是否成功创建了用户账号。
商品浏览:随机选择几个商品,打开它们的详情页面,确保商品信息能够正确地显示出来。
添加到购物车:选择一个商品并将其添加到购物车,然后查看购物车页面是否正确显示所选商品。
下订单:从购物车中选择一个或多个商品进行结算,填写必要的信息并提交订单,确保订单是否成功生成。
以上场景只是最基本的冒烟测试,旨在验证系统的主要功能是否能够正常工作。如果这些基本功能都通过了测试,那么我们可以进一步进行更详细的功能和边界测试。
- 回归测试(Regression Testing):
回归测试是在软件经过修改、修复或新功能添加后进行的一种测试。它旨在确保修改后的代码与原始代码之间没有引入新的错误,并且之前的功能仍然正常工作。回归测试是为了验证软件在进行修改后是否依然稳定和可靠。
回归测试一般包括重新执行已有的测试用例,通过比较预期结果和实际结果来确定系统是否出现了问题。它可以使用自动化测试工具来提高效率,并确保每次进行回归测试时都能够覆盖到所有关键功能和模块。
回归测试的目标是捕获并修复由于修改引入的新错误,以及确保系统的稳定性和可靠性。通过回归测试,可以防止在软件开发过程中引入新的问题,并验证之前已经修复的问题是否仍然解决了。
单元测试:通常情况下是白盒测试
最小设计单元(模块)的验证,确保模块被正确编码,对重要控制路径进行测试以发现模块内错误,通常情况下是白盒测试,对代码风格和规则、程序设计和结构、业务逻辑等进行静态测试,及早发现解决不易显现的错误。
集成测试:黑盒白盒结合
测试接口是否一致、模块间数据流控制流是否按照设计实现其功能、以及结果的正确性验证
- 系统测试:黑盒测试
系统测试是对整个系统的测试,将硬件、软件、操作人员看作一个整体,检验它是否有不符合系统说明书的地方,主要包括功能测试、界面测试、可靠性测试、易用性测试、性能测试。 功能测试主要针对包括功能可用性、功能实现程度
- 验收测试
也称交付测试,是针对用户需求、业务流程进行的正式的测试,以确定系统是否满足验收标准,由用户、客户或其他授权机构决定是否接受系统。
验收测试包括alpha测试和beta测试,alpha测试是由开发者进行的软件测试,beta测试是由用户在脱离开发环境下进行的软件测试。
常用的自动化测试工具
1、Selenium
WEB自动化测试
Selenium是网页应用中最流行的开源自动化测试框架。起源于2000年,10多年来不断地完善,Selenium成为许多Web自动化测试人员的选择,尤其是那些有高级编程和脚本技能的人。Selenium也成为了其他开源自动化测试工具比如Katalon Studio,Watir,Protractor和Robot Framework的核心框架。
2、Jmeter
接口测试,性能测试
Apache JMeter是一个开源的Java桌面应用程序,主要用于web应用程序的负载测试。它还支持单元测试和有限的功能测试。
它有很多好的特性,比如动态报告、可移植性、强大的测试IDE等,并且支持不同类型的应用程序、协议、shell脚本、Java对象和数据库。
3、Postman
接口测试
Postman 提供功能强大的Web API和HTTP请求的调试,它能够发送任何类型的HTTP请求 (GET, POST, PUT, DELETE…),并且能附带任何数量的参数和Headers。不仅如此,它还提供测试数据和环境配置数据的导入导出,付费的Post Cloud用户还能够创建自己的 Team Library用来团队协作式的测试,并能够将自己的测试收藏夹和用例数据分享给团队。
设计一个不错的测试案例
开放问题
1.对测试开发的理解
测试开发首先离不开测试,而软件测试是指,在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。
而且,现在不仅仅是通过手工测试来发现定位Bug,也会通过编写脚本、测试工具来完成自动化测试,因此,对于测试开发人员来说,他除了保证产品质量之外,还要编写脚本以及开发测试工具。这就是我对测试开发的一点理解。
2.为什么做测试而不是去做开发
首先,后端开发的工作侧重于编码和实现功能,而测试工作不仅能关注系统的功能实现,还能更全面地了解系统的性能、安全性、兼容性等多维度的问题。还能培养更加严谨、细致的思维方式,训练快速定位和分析问题的能力,所以我觉得做测试开发会对我的技术提升很有帮助。
其次,在近几年,国内对软件测试越来越重视,测试的前景是非常好的。
并且,测试在一个项目开发的过程中是非常重要的一环。开发人员很难在开发的时候又要全面兼顾产品的质量,测试人员就是项目内部的最后把关者,最大程度的保证项目上线不会出现问题。
责任非常大,责任越大成就感就越大。我很喜欢这样的工作。
在网上看到一句话,说:写程序的人就像在造没有护栏的桥,自己去走那肯定安全,那怕摸黑也不至于掉河里去;测试则像给桥修护栏的,让桥的普通使用者也能像开发那样来去自如。从这一点上说,可以体现出测试的重要性。
3.如何处理矛盾
我觉得做测试和程序员发生冲突是难免的,人与人之间在一起生活,难免会发生冲突。发生冲突不能用争吵解决,要坦诚相待,心平气和地与对方沟通,善于倾听对方的观点,并理解对方,然后向对方阐述自己的观点。如果还是产生差异,我会请示上级。
4.职业发展
对于这一行来说,经验越多,能力就越高。前几年先积累经验,不断地更新自己、改正自己,然后一步一步朝着高级测试开发工程师走去。
5.你认为测试人员需要具备哪些素质。(你有哪些优点围绕这些来说)
首先要有一定的沟通协调能力,因为测试人员经常会与开发人员接触处理一些问题,需要心平气和地沟通。还需要有一定的耐心,不能放过每一个错误;
要有责任感,要尽自己最大的能力,保证产品的质量。要有好奇心,保持一种怀疑的态度,测试人员的任务是找出缺陷,不是证明没有缺陷,所以需要保持怀疑。
要细心;乐观;
6.你为什么能够胜任这个岗位
虽然之前的实习是开发,接触的测试比较少,但是我的分析业务的能力得到了很大锻炼,而且在实习和做项目的过程中,我对自己的需求和自己做的系统也都进行了各种测试,我是有一定的测试经验的。我相信自己的学习能力,可以快速上手。而且我还有良好的沟通能力,很有耐心,有责任感,我觉得这在测试中也是很重要的一些素质。