ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

接口测试异常场景全攻略:从401鉴权到超时与数据污染

接口测试异常场景全攻略:从401鉴权到超时与数据污染 接口测试做了几年的人几乎都有过这种体验正常流程的用例跑得飞起一到异常场景就开始抓瞎。参数多传一个少传一个、鉴权过期、下游服务超时、数据状态对不上每一个坑都能耗掉大半天。尤其是注册接口测试提示{code:401,message:未登录,请登录!}这种返回刚接触服务端接口测试的新手看到基本一脸懵老手也得先排查一圈环境变量、token有效期和请求头配置。这篇文章围绕接口测试中的异常场景展开把我实际踩过的坑、用过的排查方法、沉淀下来的工具配置经验一次性说清楚。不管你是刚入门接口测试的小白还是已经被异常用例折磨过的测试开发应该都能从中找到可以直接用的思路和步骤。1. 异常场景为什么比功能用例更耗时间三个真实案例说起先说个我自己经历过的例子。有次要测用户注册接口需求把注册成功、用户名重复、手机号格式错误这些用例都写好了。真正动手跑的时候第一个请求发出去返回结果就是{code:401,message:未登录,请登录!}。我当时的反应是注册接口不是公开接口吗为什么会要求登录排查了一下午最后发现是测试环境的网关统一做了登录鉴权注册请求头里必须带上一个Authorization字段而这个字段在接口文档里根本没写清楚。更麻烦的是这个token有有效期每隔几小时要重新获取一次。于是异常测试还没开始做光打通环境就用掉了一天。第二个案例是超时问题。有个订单查询接口正常情况响应时间在100毫秒左右。我在测试工具里设了5秒超时怎么跑都是成功的。直到一次联调上游库存服务挂了这个接口卡了整整30秒才返回。这时候我才意识到接口测试里很多正常的结论是建立在超时参数设置得太宽松的基础上的。真正到生产环境用户等不了那么久网关也等不了。第三个案例是数据状态问题。测试一个支付回调接口第一次跑是成功的。第二次跑同样的请求参数返回的是订单状态不正确。原因是第一条用例已经把订单状态从待支付改成了已支付第二条用例基于同一个订单号再来跑自然就失败了。这是个典型的测试数据污染问题也是异常场景里最容易让人抓狂的一种——因为你很难判断到底是接口有bug还是自己的测试数据没做好隔离。这三个案例分别代表了异常场景里最常见的三类问题环境与鉴权异常、超时与性能异常、数据状态与依赖异常。它们的共同特点是用功能测试的思维根本发现不了必须带着系统排查的思路去做。我后面所有的方法和工具配置基本都是围绕这三类问题展开的。2. 异常场景的分层盘点其实九成时间都耗在这四类问题上做了大量接口测试之后我发现自己陷入了一个循环每天到处救火这个接口报错了查一下那个接口返回不对改一下但始终没有形成体系。后来我把过去三个月处理过的异常问题全部翻出来归类发现九成以上的时间其实耗在四类问题上。2.1 请求参数异常最多见、最容易漏参数异常绝不只是少传一个必填字段这么简单。我见过太多测试用例只覆盖了参数缺失和参数类型错误但漏掉了更隐蔽的场景。比如参数长度超出数据库字段限制接口返回的是数据库层面的报错还是业务层的友好提示字符串前后带空格、大小写不同、包含特殊字符引号、尖括号、emoji后端有没有做trim和过滤数值参数传负数、传0、传超大数、传小数接口的校验逻辑是否覆盖同一个参数在body里传两遍后端取的是第一个还是最后一个JSON格式本身不合法缺少花括号、多了一个逗号返回的是400还是500很多开发在写接口的时候只校验了自己能想到的异常场景测试如果不去补这些边角上线后出问题的概率非常高。2.2 业务状态与依赖异常最需要业务知识支撑这类异常是功能测试用例里很难覆盖到的。典型的有一个订单在待支付状态时调用取消接口是成功的但在已支付状态下调用取消接口返回什么操作一个不存在的资源ID比如查询订单号根本不存在返回的是明确的业务错误还是空的成功响应依赖的上下游服务异常库存服务超时、短信服务不可用接口是快速失败还是长时间挂起同时两个人操作同一个数据一个支付一个取消接口的并发处理是否正确处理这类异常需要测试人员对业务链路有足够的理解否则你连什么情况算正常都判断不了。2.3 服务端能力异常和性能测试的分界线接口测试里的服务端异常通常指的不是压测层面的性能问题而是接口在异常负载下的表现。比如某一瞬间请求量猛增接口是快速返回503还是把线程池打满导致整个应用不可用某个依赖服务响应变慢时当前接口的线程是被长时间占用还是做降级处理。这类异常测试和纯性能测试有个明显区别性能测试关心的是能承受多大压力服务端异常测试关心的是出现压力时接口是否还能优雅地失败。我一般不会花大量时间做这个但至少会设置几个关键的异常用例比如把超时时间调短、模拟依赖返回500看接口是否做了超时熔断。2.4 数据预置与数据污染异常最隐蔽的坑数据类异常分两层。一层是造数比如测试退款接口你得先造一笔已支付的订单测取消订单接口你得先造一笔待支付的订单。这些数据如果依赖人工在数据库里改效率极低而且容易漏字段。另一层是清理用例跑完之后测试数据如果不清理下一次运行必然互相影响。我之前就犯过这个错。为了测重复注册的场景我先用某个手机号注册了一个账号用例执行成功。第二周再跑同一套回归用例同样的手机号直接返回该手机号已注册但用例预期是注册成功结果一跑就失败。最后排查了半天发现是上一次的数据没有清理。把这四类问题想清楚之后我开始有意识地在每个接口测试计划里分别覆盖这几块而不是想到哪个测哪个。后面章节讲到的工具配置和排查链路也都是基于这个分类来展开的。3. 鉴权与登录态异常401未登录这类问题的一次完整排查链路如果你用的接口测试工具是apifox这类支持环境管理、全局变量和脚本的鉴权类异常处理起来要轻松很多。但正因为工具太方便很多人忽略了一个事实401未登录这个提示根本原因并不总是在token过期上。注册接口测试提示{code:401,message:未登录,请登录!}就是一个非常典型的例子。下面这条排查链路我完整复现过很多次每次都能定位到不同的根因。3.1 第一步确认token有没有真的传到请求头里打开接口测试工具的请求详情看实际发出的请求里有没有Authorization或Cookie字段。这一步听起来简单但翻车率极高。尤其是用了环境变量之后变量名写错、变量没有正确引用、引用到了另一个环境的值都会导致token没有真的带上。我见过最离谱的案例全局变量里定义了token但请求头里写的是{{auth_token}}变量名对不上接口收到的请求头里根本没有这个字段。所以排查的第一步永远不要猜直接看实际发出的请求报文。3.2 第二步确认token本身有没有过期在接口测试工具里跑一个能正常获取token的登录接口把返回的token和出问题的请求里实际带的token对比一下。如果token是同一个那说明不是过期问题如果token已经变了那说明是测试环境里token刷新机制没走通。这里有个容易被忽略的点很多登录接口返回的token有效期只有2小时。而测试人员经常会创建一批用例隔几天再跑一次。如果用例里用的是写死的历史token必然返回401。正确的做法是用环境变量加脚本每次跑用例前自动登录拿到新token。在apifox里可以用测试前置操作调用登录接口把返回体里的token提取出来存到环境变量中后面的接口自动引用这个变量。3.3 第三步确认网关层有没有额外的鉴权逻辑这是注册接口测试里最容易翻车的一步。很多项目的网关会对所有接口做统一鉴权包括那些本身不要求登录的公开接口。这种情况下你调注册接口时后端业务逻辑其实不需要鉴权但请求到了网关这一层就被拦下来了。排查方法很简单看接口文档里有没有单独的鉴权说明如果没有问一下后端同学这个接口是不是要走网关的全局鉴权。我记得当时排查注册接口返回401最后发现网关配置里把/api/user/register这个路径漏配了白名单解决方式是网关加白名单而不是在测试里硬塞token。3.4 第四步确认环境隔离有没有问题很多公司会有多套测试环境dev环境、test环境、staging环境。接口测试工具里如果配了多个环境一不小心就会把测试环境的请求发到staging环境去。两个环境的用户体系不互通在dev环境登录拿到的token请求打到了staging环境网关一验就校验失败返回401。这个问题的排查有个小技巧401返回时看一下响应头里的服务器标识或者报错里面的环境标识能快速判断是不是发错了环境。如果接口返回里不区分环境那就把接口测试工具的请求URL、环境变量、当前选中的环境三项截图对比基本能发现问题。完整的排查链路走完之后你会发现401类问题很少有单一根因。大多数情况是token没带、token过期、网关白名单、环境串扰这四类问题的叠加。在工具里做好环境变量、自动登录脚本和请求头引用之后这类问题基本能降到最低。4. 参数边界与数据造假把异常用例做快的关键操作细节参数异常和测试数据是异常场景里最需要抠细节的部分。我见过很多测试新手用例设计得密密麻麻但执行起来效率极低因为每个用例都要手动造数据。这一节把我在参数边界和数据造假两个方向上的实操经验拆开讲。4.1 参数边界别只盯着必填看很多接口测试教程会告诉你必填参数不传、传空、传null这三种用例必写。这没错但要真正把异常场景覆盖住只靠这三板斧是不够的。我一般会按下面的维度来拆解每个参数长度边界数据库字段是varchar(32)就测31位、32位、33位。尤其是中文字符一个汉字在数据库里到底占几个字节后端和数据库的编码配置不同结果会差很远类型边界金额参数传0.001精度的边界、传-1负数的边界、传999999999999999.99超出精度范围格式边界手机号传12345位数不够、传1380000000a含字母、传138 0000 0000中间带空格编码边界URL里带中文、body里带emoji、参数值里带单引号和尖括号SQL注入和XSS的初步探测我实际经验是边界值用例写的时候很枯燥但收益非常大。一个订单金额接口如果后端用double还是BigDecimal对0.01和0.001的处理完全不一样。这类问题在功能测试阶段很难发现往往要到线上出现金额对不上的事故后才暴露。所以做接口测试时对金额、数量、时间戳这类参数边界用例越细越好。4.2 数据造假用例能不能跑得快全靠这一项异常场景测试里你有大概率需要这种数据一个已支付待发货的订单一个用户名已存在的账号一个进行中的活动一个已被删除的资源ID手工去数据库里改费时费力而且容易漏掉关联表。我现在遇到这种情况优先用两种方式解决。第一种是写SQL脚本。比如要造一个已支付订单先查订单表结构把状态字段改成PAID再改支付流水表的状态如果有必要还要改一下支付时间。我一般会把常用的SQL脚本按业务模块保存下来下次直接改参数执行。这比每次打开数据库客户端手动敲SQL快太多。第二种是直接用工具加接口测试脚本。很多接口测试工具支持脚本语言可以串联多个接口先调创建订单接口再调支付接口等用例跑完之后订单自然就是已支付状态。这种方法不需要直接操作数据库而且更贴近真实业务链路数据的完整性更好。我强烈建议优先用接口串联的方式造数实在走不通再上SQL。4.3 数据清理跑完不等于结束数据污染问题前面提过一次这里说具体解法。我给自己定了一条规矩凡是在测试过程中创建的数据用例执行完成之后必须清理。清理策略一般有三种通过接口清理如果有删除接口直接调用通过SQL清理按创建时间和标识字段批量删除通过独立测试账号隔离每个开发、每个测试用不同的账号前缀互不影响如果接口本身有删除功能优先用接口清理没有删除功能就写SQL。测试工具里可以把清理动作放在测试后操作里这样每次跑用例结束数据自动回滚不用手动处理。这一节最后补充一句参数边界和数据造假这部分最忌讳的是临到执行前才开始想。提前把每个接口的必填参数、边界值、依赖数据梳理成一份清单执行的时候照着清单逐条过速度会比边想边测快出一倍以上。5. 服务端异常与超时场景慢接口和抖动的度量与处置接口测试里有一类异常特别让人头疼你发一个请求它既不报错也不快速返回就那么一直转圈。等你等到没耐心了工具报了个超时。到底是接口本身慢还是网络问题还是工具的超时设置不合理这个事必须理清楚否则你连问题归属都分不清。5.1 超时设置并不是越大越安全很多测试人员习惯把所有超时时间调到很大觉得这样就不会误报。这在接口测试阶段可能没问题但和真实用户体验完全是两回事。接口测试工具里的超时一般分连接超时connect timeout和读取超时read timeout。连接超时是TCP握手阶段等待的时间读取超时是连接建立后等待服务端返回数据的时间。这两个值应该分开设置不能一刀切。我的经验是正常的内部API接口连接超时设3000毫秒读取超时设5000毫秒依赖第三方服务的接口连接超时设5000毫秒读取超时设10000毫秒涉及文件上传、导出下载的接口读取超时设30000毫秒以上如果在这么长的时间里接口还没返回那基本可以判定接口本身有问题需要开发去排查而不是靠测试工具无限等下去。5.2 慢接口的定位先看聚合报告再看单次请求工具里如果提供了请求耗时统计可以先看聚合报告里的平均耗时、最大耗时和错误率。如果平均耗时正常但最大耗时特别大说明存在明显的抖动如果平均耗时本身就高说明接口性能本来就差。我之前测过一个商品列表接口平均耗时400毫秒最大耗时3.2秒。一开始以为是网络抖动后来单独把那个3.2秒的请求拎出来看发现它触发了缓存重建。这就是个典型的慢接口场景正常流量下接口很快一旦缓存失效所有请求都打到数据库上。如果只看平均耗时这个问题根本发现不了。5.3 下游抖动与超时怎么模拟依赖服务异常服务端接口往往不是孤立的它会调用库存服务、价格服务、用户中心等下游。想要测下游服务超时的异常场景最直接的办法是在测试工具里加一个mock服务把下游的响应改成延迟返回或直接返回500。有些测试工具自带mock能力比如apifox的mock服务可以针对某个接口路径返回自定义响应。把被测接口的下游地址指到mock服务上再用脚本控制mock服务的响应耗时和状态码就能模拟出各种服务端异常场景。在测试订单查询接口时我用mock把库存服务改成了延迟3秒返回订单接口等了3秒后返回了一个库存查询超时请稍后重试的业务错误。这个用例特别有价值因为它验证了接口有没有做超时处理而且确认了接口在超时时返回的是友好的业务报错不是把500错误直接抛给用户。5.4 幂等与重试超时要测的不只是超时本身最后说一个和超时强相关但经常被忽略的点幂等。很多接口在超时之后调用方会做重试。如果接口本身没有做幂等处理同样的请求发两次结果可能就乱了。我在测试支付接口时验证过这个场景第一次请求因网络原因超时但服务端其实已经处理成功了。第二次重试同一个订单被再扣一次款用户多付了一笔钱。这个异常场景的用例设计思路是调用接口并制造超时可以用mock控制慢响应在服务端确认已处理完成再发一次相同的请求看接口是否返回重复支付之类的业务提示而不是再次扣款。这个场景写出来容易真正模拟起来有不少细节核心在于对超时时间和慢响应的控制。如果你用的工具支持脚本设置延迟响应强烈建议把这类用例沉淀下来它对支付、订单、库存这类核心链路的保障价值极高。6. 用工具把异常场景固化下来断言、环境隔离与用例沉淀异常场景最大的问题不是想不到而是每次都要重想一遍。解决这个问题的最佳方式是把异常场景的断言、环境配置和用例数据全部固化在接口测试工具里。工具选哪个不是核心核心是你有没有把流程和规范落地。6.1 断言技巧不要只盯着状态码也不要用固定值服务端接口测试里新手最常犯的错误是只断言HTTP状态码是200。但接口返回200太正常了真正的业务逻辑错误往往藏在响应体的code字段里。正确做法是把断言拆成三层HTTP状态码判断网络层和网关层是否正常响应体code字段判断业务层的成功失败响应体message或data里的关键字段判断业务返回的细节是否正确以注册接口测试返回401为例如果你只断言HTTP状态码那么401本身就是一个非预期但明确的结果你会很快发现有问题。如果你把断言做到了响应体的code和message上就能在用例运行失败时直接看到未登录、请登录这个信息排查效率会高很多。另外响应体断言不建议写死固定值尽量用脚本做动态判断。比如要断言用户名重复时返回错误码你可以先造一个已存在的用户名再调用注册接口用脚本判断code是否等于特定错误码、message是否包含已存在等关键字。把断言和测试数据关联起来用例的可靠性会大大提升。6.2 环境变量与登录态把401问题在源头堵住在接口测试工具里做好环境变量是处理登录态异常的核心手段。apifox支持环境变量管理你可以在测试前置操作里写一段脚本先请求登录接口把返回的token保存到环境变量中。后续所有接口的请求头都引用这个变量这样每次跑用例都会自动带上最新的tokentoken过期问题在根源上被解决了。具体配置思路是环境1dev环境baseUrl指向dev服务器环境2test环境baseUrl指向test服务器全局变量authToken由登录接口的脚本写入请求头Authorization字段值写{{authToken}}上述配置做好后你切换环境跑同一套用例登录态都是自动获取的不会出现dev上拿到的token打到了test环境这种问题。环境串扰导致401的坑提前就堵死了。6.3 用目录结构把异常用例沉淀下来工具里用例的组织方式直接决定了复用效率。我推荐按模块和场景两个维度建目录比如用户模块正常注册用例注册参数异常用例注册业务冲突用例用户名重复等注册鉴权异常用例未登录、token过期订单模块正常下单用例订单状态异常用例订单金额边界用例订单幂等与重试用例这样组织之后每次新版本回归、每次需求变更只要找到对应模块的目录跑一遍就能把异常场景全覆盖。不用再临时想这个接口有哪些异常的测法。6.4 用例运行之后结果怎么看失败怎么归类固化用例之后运行结果的查看也有讲究。我在看测试报告时会按下面三类把失败用例归类环境类失败请求都发出去了但返回的是网络错误、超时、401等优先排查工具配置和环境问题数据类失败接口返回正常但断言失败比如预期是用户名重复错误实际却注册成功了优先排查测试数据是否冲突代码类失败接口返回500、参数校验报错、响应字段缺失这类才是真正要提单给开发的bug这个分类方法帮了我很大的忙。以前一看到跑失败的用例就开始排查东一下西一下效率很低。现在先归类再动手十次里面有八次能在五分钟内定位到大致方向。7. 从一次接口测试异常排查里提炼的几点心得做了几年接口测试处理过的异常场景少说也有几百个了。这次借注册接口测试提示{code:401,message:未登录,请登录!}这个话题把一些零散的心得整理一下不一定都对但都是实际踩过的。第一个心得处理异常场景之前一定要先把正常链路跑到足够稳。如果正常流程的接口偶尔也会超时、偶尔也会报错那你做异常场景就是在沙滩上盖楼根本分不清问题是测试环境不稳定还是接口真的处理不了异常。我在做注册接口异常测试之前先把正常注册跑通了三遍确认环境稳定后才开始动异常用例。第二个心得工具只是辅助业务理解才是核心。很多人问我为什么同一个工具有的人测接口又快又准有的人总是被异常场景折磨。差距主要在于对业务链路的理解。字段之间的约束关系、状态流转的规则、上下游系统的依赖关系这些在接口文档里往往写不全但恰恰是异常场景最容易出问题的地方。第三个心得异常场景用例不是越多越好而是要成体系。我见过有人把手机号参数为null/为空/为空格/为字母/为特殊字符/为emoji写成六个用例每个用例都单独跑一遍。这样写不是不行但效率太低。更好的做法是用数据驱动的方式把多个异常参数放在一组用例里用变量去循环跑一份脚本覆盖多种情况。我个人的做法是每个接口先保证至少覆盖参数异常、业务状态异常、数据依赖异常、服务端异常四个方向然后再根据接口的重要程度加深细节。核心交易链路注册、登录、下单、支付多投入时间边缘查询接口保证基础覆盖即可。这样既不会漏掉核心风险也不会把时间耗在低价值用例上。如果你现在正被接口测试的异常场景折磨可以试着先把问题归类再照着前文的排查链路和工具配置去操作。等把401、超时、数据污染这些坑都理顺了你会发现异常场景并没有想象中那么耗时耗力。
返回列表