如何将依赖preserveOnce beforeEach的Cypress测试升级至13+?
核心背景
Cypress 12+ 默认开启 testIsolation: true,每个测试(it 块)都会自动重置浏览器上下文(清除 Cookie、LocalStorage、页面状态),这也是你用 cy.session 时遇到页面被清空的原因。之前的 Cypress.Cookies.preserveOnce 本质是绕过这种隔离,让指定 Cookie 在测试间持久化。
方案一:最小改动——关闭测试隔离(等效原逻辑)
如果你不想大幅重构现有测试套件,直接在需要共享 Cookie/状态的 context 或 describe 块中关闭 testIsolation,就能完全复刻 preserveOnce 的效果:
context('the cookie preferences panel', { testIsolation: false }, () => { before(() => { cy.visit('/') }) it('is displayed correctly by default', () => { cy.get('#cookie-preferences') .should('be.visible') .and('contain', 'We value your privacy') }) it('remains visible when page is refreshed', () => { cy.reload() cy.get('#cookie-preferences').should('be.visible') }) context('when the accept button is clicked', () => { before(() => cy.get('#cookie-preferences .accept').click()) it('the banner is no longer visible', () => { cy.get('#cookie-preferences').should('not.be.visible') }) it('does not open when page is refreshed', () => { cy.reload() cy.get('#cookie-preferences').should('not.be.visible') }) }) })
设置 { testIsolation: false } 后,整个 context 下的所有测试会共享同一个浏览器上下文:Cookie 不会被清除,页面操作的状态(比如点击「接受」按钮后的状态)也会在测试间保留,完全匹配你之前用 preserveOnce 的运行逻辑。
方案二:官方推荐——正确使用 cy.session
如果想遵循 Cypress 最新最佳实践,cy.session 的作用是复用初始化的会话状态(比如登录态、初始 Cookie),而非共享测试间的操作状态。针对你的场景,正确用法如下:
beforeEach(() => { // 创建并复用会话,保存初始访问生成的 Cookie cy.session('initial-cookies', () => { // 执行生成 Cookie 的操作(比如访问首页) cy.visit('/') // 可选:明确验证关键 Cookie 是否生成 cy.getCookie('csrftoken').should('exist') cy.getCookie('sessionid').should('exist') }, { // 会话验证逻辑,确保恢复的会话有效 validate: () => { cy.getCookie('csrftoken').should('exist') cy.getCookie('sessionid').should('exist') } }) // 恢复会话后,重新访问页面(因为会话恢复会清空页面) cy.visit('/') }) context('the cookie preferences panel', () => { it('is displayed correctly by default', () => { cy.get('#cookie-preferences') .should('be.visible') .and('contain', 'We value your privacy') }) it('remains visible when page is refreshed', () => { cy.reload() cy.get('#cookie-preferences').should('be.visible') }) context('when the accept button is clicked', { testIsolation: false }, () => { // 子上下文关闭隔离,共享点击后的状态 before(() => cy.get('#cookie-preferences .accept').click()) it('the banner is no longer visible', () => { cy.get('#cookie-preferences').should('not.be.visible') }) it('does not open when page is refreshed', () => { cy.reload() cy.get('#cookie-preferences').should('not.be.visible') }) }) })
你之前用 cy.session 失败的原因
你之前只在 before 中调用 cy.session('cookies', () => {cy.visit('/')}),但默认 testIsolation: true 会在每个 it 块前重置页面,而 cy.session 只会恢复 Cookie,不会自动恢复页面状态,所以后续测试会因为页面被清空而失败。
内容的提问来源于stack exchange,提问作者DrMeers

