Gatling性能测试的重定向处理是为了控制测试流程、保证测试意图准确性和测量精度。Gatling默认自动跟随重定向,但为了满足复杂的测试情形(如多步骤认证、精确追踪跳转或测试特定重定向思路),必须能够手动控制这一行为。控制参数即为disableFollowRedirect。
一、自动跟随和手动控制
默认行为(自动跟随)
默认情况下,Gatling的HTTP协议会像浏览器一样,自动处理 3xx 状态码(如301、302、307)的重定向。测试脚本中只需定义一个请求,后续跳转请求由Gatling自动执行,只将最后一个非重定向响应的结果(状态码、响应时间等)记录到报告中。
优点:脚本编写简单,适合模拟绝大多数常规浏览行为。
缺点:丢失了中间跳转步骤的详细性能数据(如每个重定向请求的延迟),无法对中间状态进行断言,难以构造复杂的多步骤交互。
手动控制(禁用自动跟随)
通过在协议或单个请求方面调用 .disableFollowRedirect,Gatling将停止自动跳转。当收到 3xx 响应时,会立即停止,并将该重定向响应本身作为最后结果返回给脚本。
作用:获得了完整的控制权。可以检查重定向响应的头部(如Location)、状态码,并据此决定下一步操作(如下一个请求的目标、是不是需要携带特定参数)。
二、disableFollowRedirect 的应用情形
在以下情形中,禁用自动重定向是必须或最好选择:
精确性能监控:需要单独测量重定向步骤本身的延迟(如,CDN或负载均衡器的重定向时间)。禁用后重定向请求将作为独立事务被记录和报告。
多步骤认证流程:如OAuth 2.0授权码流程,需要从A站跳转到B站登录,再携带code跳回A站。必须手动处理中间的重定向响应来提取参数。
测试特定重定向思路:需要证实服务器返回的是302(临时)还是301(永久),或者检查Location头的值是不是正确。
处理重定向链中的特定步骤:在长链条中,可能需要在某个中间步骤注入或修改参数(如会话ID),再发起下一个跳转。
避免重定向的循环:当怀疑存在配置错误导致的重定向无限循环时,禁用后可以快速定位问题,避免压测资源被无限消耗。
配置方法:
全局禁用在协议方面-适用于整个测试套件都需要精细控制的情况。
val httpProtocol = http .disableFollowRedirect // 为所有请求关闭自动重定向局部禁用在请求方面-灵活性最高只对需要手动处理的请求生效。
exec(http("请求:获取登录页") .get("/login") .check(status.is(200)) // 先检查登录页是不是正常 ) .exec(http("提交登录表单(禁用自动跳转)") .post("/login") .formParam("username", "user") .formParam("password", "pass") .disableFollowRedirect // 仅对此请求禁用 .check(status.is(302)) // 证实服务器确实发出了重定向指令 .check(header("Location").saveAs("redirectTarget")) // 提取重定向地址 ) .exec(http("跟随重定向") .get("${redirectTarget}") // 手动发起请求到提取的地址 .check(status.is(200)) )文章来源:卓码软件测评
精彩推荐:点击蓝字即可
▲软件负载测试▲API自动化测试▲软件测试▲第三方软件测试▲软件性能测试▲软件测试机构
三、示例模拟OAuth 2.0授权码
以下是一个禁用自动重定向来精确模拟OAuth登录的示例:
import io.gatling.core.Predef._ import io.gatling.http.Predef._ import scala.concurrent.duration._ class OAuthRedirectSimulation extends Simulation { val httpProtocol = http .baseUrl("https://app.zmtests.com") .acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") val scn = scenario("OAuth 2.0 Authorization Code Flow") // 1. 应用将用户重定向到OAuth服务器 .exec( http("Redirect to OAuth Provider") .get("/auth/oauth-authorize") .queryParam("response_type", "code") .queryParam("client_id", "myClientId") .queryParam("redirect_uri", "https://app.zmtests.com/callback") .queryParam("state", "RANDOM_STATE") .disableFollowRedirect // 禁用,以获取OAuth服务器的登录页地址 .check( status.is(302), header("Location").saveAs("oauthLoginUrl") ) ) // 2. 手动请求OAuth服务器的登录页(模拟用户在此输入证据) .exec( http("Load OAuth Login Page") .get("${oauthLoginUrl}") .check( // 一般需要从登录页HTML中提取CSRF Token css("input[name='csrf']", "value").saveAs("csrfToken") ) ) // 3. 提交登录表单到OAuth服务器(再次禁用自动跳转,以获取授权码) .exec( http("Submit Login to OAuth Provider") .post("${oauthLoginUrl}") .formParam("username", "test_user") .formParam("password", "test_pass") .formParam("csrf", "${csrfToken}") .disableFollowRedirect // 重点:禁用以拦截携带code的重定向 .check( status.is(302), header("Location").saveAs("redirectUriWithCode") ) ) // 4. 从Location头中分析授权码 .exec(session => { val location = session("redirectUriWithCode").as[String] // 简单示例:从查询参数中提取code val code = location.split("code=")(1).split("&")(0) session.set("authorizationCode", code) }) // 5. 应用用授权码向OAuth服务器请求访问令牌(后端通信,无重定向) .exec( http("Exchange Code for Access Token") .post("https://oauth.zmtests.com/token") .formParam("grant_type", "authorization_code") .formParam("code", "${authorizationCode}") .formParam("redirect_uri", "https://app.zmtests.com/callback") .formParam("client_id", "myClientId") .formParam("client_secret", "myClientSecret") .check(jsonPath("$.access_token").saveAs("accessToken")) ) // 6. 使用令牌访问受保护资源 .exec( http("Access Protected Resource") .get("/api/data") .header("Authorization", "Bearer ${accessToken}") ) setUp( scn.inject(atOnceUsers(1)) ).protocols(httpProtocol) }四、调试建议
方法选择:除非有确定的精细控制需求,否则保持默认的自动重定向,这样简单能模拟大多数用户行为。
结合检查点:禁用自动重定向后,必须添加检查点来证实重定向响应(如status.is(302),header("Location").exists),否则脚本可能因意外响应而失败。
性能报告解读:启用disableFollowRedirect后,每个独立的请求(包括重定向) 都会在Gatling报告中生成一条记录。这能清晰分析每个跳转步骤的耗时。
处理相对途径:手动从Location头提取URL时,注意可能是相对途径。Gatling的.get()方法支持相对途径,但最好方式是使用完整的URL或保证基础URL已正确设置。
调试:在开发脚本阶段,可以临时添加.check(header("Location").transform(location => {println(s"Redirecting to: $location"); location}))来打印重定向地址,辅助调试。