You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cypress测试中保存API Token供后续测试用例调用?

解决Cypress中API Token跨测试用例复用的问题

问题场景

编写了以下Cypress API测试代码,试图在第一个测试用例获取Token后,在第二个创建购物车的用例中复用,但运行时报错 ReferenceError: access_token is not defined。

原代码如下:

const API_STAGING_URL = Cypress.env('API_STAGING_URL')

describe('Decathlon API tests', () => {
it('Get token',function(){
cy.request({
  method:'POST',
  url: 'https://test.com/as/token.oauth2?grant_type=client_credentials',
  headers:{
    authorization : 'Basic 1aFJueHkxddsvdvsdcd3cSA=='
  }}).then((response)=>{
    expect(response.status).to.eq(200)
    const access_token = response.body.access_token
    cy.log(access_token)
    cy.log(this.access_token)
  })
  cy.log(this.access_token)
}),

it('Create Cart',function(){      
cy.request({
  method:'POST',
  url: `${API_STAGING_URL}`+"/api/v1/cart",
  headers:{
    Authorization : 'Bearer ' + access_token,
    "Content-Type": 'application/json',
    "Cache-Control": 'no-cache',
    "User-Agent": 'PostmanRuntime/7.29.2',
    "Accept": '*/*',
    "Accept-Encoding": 'gzip, deflate, br',
    "Connection": 'keep-alive',
    "Postman-Token": '<calculated when request is sent>'

  },
      
            
  }}).then((response)=>{
    //Get statut 200
    expect(response.status).to.eq(200)
    //Get property headers
    
  })})
  
})

问题原因

  1. 变量作用域限制:第一个测试用例中声明的const access_token是局部变量,仅在then回调内部有效,无法跨测试用例访问。
  2. 异步执行顺序问题:cy.request是异步操作,写在then外部的cy.log(this.access_token)会先执行,此时this.access_token还未被赋值。
  3. 测试用例隔离性:Cypress的每个it测试用例独立执行,默认不共享上下文变量。

解决方案

方法1:before钩子+Cypress环境变量(推荐全局复用)

将Token获取逻辑放在所有测试用例执行前的before钩子中,把Token存入Cypress环境变量,实现全局复用:

const API_STAGING_URL = Cypress.env('API_STAGING_URL')

describe('Decathlon API tests', () => {
  // 所有测试用例执行前获取Token
  before(function() {
    cy.request({
      method: 'POST',
      url: 'https://test.com/as/token.oauth2?grant_type=client_credentials',
      headers: {
        authorization: 'Basic 1aFJueHkxddsvdvsdcd3cSA=='
      }
    }).then((response) => {
      expect(response.status).to.eq(200)
      // 将Token存入环境变量
      Cypress.env('access_token', response.body.access_token)
      cy.log('获取到的Token:', Cypress.env('access_token'))
    })
  })

  it('Create Cart', function(){      
    cy.request({
      method: 'POST',
      url: `${API_STAGING_URL}/api/v1/cart`,
      headers: {
        Authorization: `Bearer ${Cypress.env('access_token')}`,
        "Content-Type": 'application/json',
        "Cache-Control": 'no-cache',
        "User-Agent": 'PostmanRuntime/7.29.2',
        "Accept": '*/*',
        "Accept-Encoding": 'gzip, deflate, br',
        "Connection": 'keep-alive'
        // Postman-Token无需手动设置,Cypress会自动处理请求标识
      }
    }).then((response) => {
      expect(response.status).to.eq(200)
    })
  })
})

方法2:cy.wrap+别名(局部用例共享)

如果仅需在当前describe块内共享Token,可使用别名方式:

const API_STAGING_URL = Cypress.env('API_STAGING_URL')

describe('Decathlon API tests', () => {
  it('Get token', function(){
    cy.request({
      method: 'POST',
      url: 'https://test.com/as/token.oauth2?grant_type=client_credentials',
      headers: {
        authorization: 'Basic 1aFJueHkxddsvdvsdcd3cSA=='
      }
    }).then((response) => {
      expect(response.status).to.eq(200)
      // 将Token包装为Cypress对象并设置别名
      cy.wrap(response.body.access_token).as('accessToken')
    })
  })

  it('Create Cart', function(){      
    // 通过this访问别名(需使用function()而非箭头函数)
    cy.get('@accessToken').then((access_token) => {
      cy.request({
        method: 'POST',
        url: `${API_STAGING_URL}/api/v1/cart`,
        headers: {
          Authorization: `Bearer ${access_token}`,
          "Content-Type": 'application/json',
          "Cache-Control": 'no-cache',
          "User-Agent": 'PostmanRuntime/7.29.2',
          "Accept": '*/*',
          "Accept-Encoding": 'gzip, deflate, br',
          "Connection": 'keep-alive'
        }
      }).then((response) => {
        expect(response.status).to.eq(200)
      })
    })
  })
})

注意事项

  • 避免直接用this赋值共享变量:Cypress异步操作中可能丢失上下文,导致变量无法正确传递。
  • 无需手动设置Postman-Token:Cypress会自动生成请求标识,手动设置可能引发异常。
  • 关注Token有效期:若Token过期时间短,可改用beforeEach钩子在每个用例执行前重新获取Token。

内容的提问来源于stack exchange,提问作者FlutterLover

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 09:50:27