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

Cypress测试用例登录后点击菜单跳转回登录页如何解决

问题原因

登录后跳转页面就被踢回登录页,本质是没搞懂Cypress的默认执行规则:
Cypress 默认开启测试隔离,每个it()测试用例执行前,都会自动清空当前浏览器的全部状态,包括Cookie、LocalStorage、SessionStorage这些存储登录凭证的内容。
第一个登录用例跑通后,进入下一个用例时Cypress会自动清掉登录状态,这时候点击需要登录才能访问的菜单,服务端检测不到有效登录凭证,自然就重定向回登录页了。
之前把登录写在before钩子里不生效也是同一个原因:before只在整个describe块的最开始执行一次,后面每个用例执行前Cypress还是会清空状态,登录态照样留不住。

解决方法

方案1:关闭测试隔离(仅适合临时调试)

给describe块加配置,关掉默认的状态清除逻辑,同个describe下的用例就能共享浏览器状态,原有代码不需要改动,只需要加一行配置:

describe('Dashboard Page', { testIsolation: false }, function () {
    // 原有所有it用例直接放在这里即可
})

提醒:这种写法不符合测试用例独立的原则,前面的用例如果执行出错,很容易导致后面所有用例连锁失败,只适合临时调试场景,正式测试不推荐使用。

方案2:自定义登录命令 + beforeEach钩子(官方推荐写法)

这是Cypress官方推荐的标准实现,既能保证每个用例执行前都是已登录状态,又能做到用例之间互不干扰:

  1. 先在cypress/support/commands.js文件里封装通用的登录命令,后续所有测试文件都可以直接调用:
Cypress.Commands.add('login', (username = 'Admin', password = 'admin123') => {
  cy.visit('https://opensource-demo.orangehrmlive.com/')
  cy.get('#txtUsername').type(username)
  cy.get('#txtPassword').type(password)
  cy.get('#btnLogin').click()
  cy.get('#welcome').contains('Welcome')
})
  1. 改写测试文件,用beforeEach钩子在每个用例执行前先调用登录逻辑,不需要再单独写登录的it用例:
describe('Dashboard Page', function () {
  // 每个用例执行前自动完成登录
  beforeEach(() => {
    cy.login()
  })

  it('校验Dashboard页面文本', () => {
    const expectText = 'Dashboard'
    cy.get('.head > h1').should('be.visible').then(($el) => {
      const actualText = $el.text()
      cy.log(`实际获取的文本为:${actualText}`)
      expect(actualText).to.eq(expectText)
    })
  })

  it('进入My Leave页面校验', () => {
    cy.get(':nth-child(5) > .quickLaunge > a > .quickLinkText').click()
    const expectText = 'My Leave List'
    cy.contains('My Leave List').should('be.visible').then(($el) => {
      const actualText = $el.text()
      cy.log(`实际获取的文本为:${actualText}`)
      expect(actualText).to.eq(expectText)
    })
  })
})

方案3:接口登录(适合用例量大的场景提效)

如果测试用例比较多,每次都走UI输入账号密码登录速度很慢,可以直接调用登录接口拿凭证,跳过UI操作步骤,执行速度能提升好几倍:

// 同样封装成自定义命令
Cypress.Commands.add('loginByApi', (username = 'Admin', password = 'admin123') => {
  cy.request({
    method: 'POST',
    url: 'https://opensource-demo.orangehrmlive.com/index.php/auth/validateCredentials',
    form: true,
    body: {
      txtUsername: username,
      txtPassword: password
    }
  }).then(() => {
    cy.visit('https://opensource-demo.orangehrmlive.com/index.php/dashboard')
  })
})

这个命令和前面的UI登录命令用法完全一致,放在beforeEach里调用即可。

优化建议
  • 不要写cy.wait(2000)这种固定时长的等待,Cypress本身自带元素重试等待机制,直接加should('be.visible')之类的断言,等元素加载完成再操作即可,用例稳定性会高很多。
  • 不要把登录步骤写成单独的测试用例,登录是其他页面测试的前置条件,不是要验证的业务测试点,放在钩子或者公共命令里复用更合理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 07:57:28