Cypress 每次测试后注销的解决方法

发表时间

Cypress 在默认情况下,每次测试结束后将清除程序的状态。这样做的副作用是,如果测试中一个用户通过登录行为进入了登录态,那么这个登录态会被取消,用户回到未登录状态。如果要进行另一个测试,就需要重新登录。

目录

Cypress 的最佳实践 是将各个测试独立开来,去除之间的耦合,这样做能保证测试之间不相互依赖,单独执行任何一个测试都能正常执行。

但是有种特殊情况,就是页面的登录状态,当所有测试用例都基于登录态开展时,就会碰到难题。

难题描述

假设用例的格式是这样,是一个非常普通的 spec 格式:

describe('Test Suite', function(){
    before('login',function(){
        cy.login()
    })

    it('test1', function(){
      cy.get('#btn1')
        .click()   // 点击 btn1 按钮将触发请求
    })

    it('test2', function(){
      cy.get('#btn2')
        .click()  // 点击 btn2 按钮将触发请求
    })
})

实际运行时,是类似 这里介绍的 Testcafe 的代码结构 每次 it 开始执行前,Cypress 会清除前次 it 产生的所有 cookie,以保证一个干净的环境,避免状态累积造成混乱。

但是这么做的另一面就是,如果希望所有的 it 都处在同一个登录态下,就被迫需要反复登录。

解决方案

Cypress 提供了一个接口 Cypress.Cookies.preserveOnce() ,可以使单次测试结束后不清除 cookie,加入代码后如下:

describe('Test Suite', function(){
    before('login',function(){
        cy.login()
    })

    beforeEach(function(){
        // 在结束后不清除cookie,保留到下次测试开始
        Cypress.Cookies.preserveOnce('cookie1', 'cookie2')  
    })

    it('test1', function(){
      cy.get('#btn1')
        .click()
    })

    it('test2', function(){
      cy.get('#btn2')
        .click()
    })
})

上面代码中, Cypress.Cookies.preserveOnce('cookie1', 'cookie2') 参数列表是希望保存下来的 cookie 名称。

新问题

上一节这种写法 后,又会遇到新问题:调试代码时,需要反复执行整个脚本,由于保存cookie接口的存在,会在后面一次执行是带上上一次的cookie值,这时候需要在 before 中清除前次的 cookie,类似下面的代码:

describe('Test Suite', function(){
    before('login',function(){
        // 在测试开始前清除所有 cookie
        cy.clearCookies()   
        cy.login()
    })

    beforeEach(function(){
        Cypress.Cookies.preserveOnce('cookie1', 'cookie2')
    })

    it('test1', function(){
      cy.get('#btn1')
        .click()
    })

    it('test2', function(){
      cy.get('#btn2')
        .click()
    })
})

这样就解决了测试后自动注销导致反复登录的难题。

新新问题

如果你一些 it.skip() 方法,例如:

describe('Test Suite', function(){
    before('login',function(){
        cy.clearCookies()   
        cy.login()
    })

    beforeEach(function(){
        Cypress.Cookies.preserveOnce('cookie1', 'cookie2')
    })

    // 这里忽略执行
    it.skip('test1', function(){
      cy.get('#btn1')
        .click()
    })

    it('test2', function(){
      cy.get('#btn2')
        .click()
    })
})

上面的例子中,名为 ‘test1’ 的 it.skip() 方法被忽略,因为没执行,所以也不执行属于它的 beforeEach,在执行下一个 it 前会发现 cookie 已经被清除。

所以如果你用 beforeEach 的方法保存 cookie,对于想忽略的 it 只能全部注释的方法忽略。


相关文章
除非特别说明,本站文章均系原创,并采用 署名协议 CC-BY 授权。
欢迎转载,惟请保留原文链接:https://lfhacks.com/tech/cypress-logout-between-tests