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

2020-09-23
标签: 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 按钮将触发请求
  })
})

实际运行时,是类似 这里介绍的:每次 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() 方法被忽略,因为’test1’ 本身没执行,所以也不执行属于它的 beforeEach,在执行下一个 it 前会发现 cookie 已经被清除。

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

如果您对本站内容有疑问或者寻求合作,欢迎 联系邮箱邮箱已到剪贴板

标签: CYPRESS

欢迎转载本文,惟请保留 原文出处 ,且不得用于商业用途。
本站 是个人网站,若无特别说明,所刊文章均为原创,并采用 署名协议 CC-BY-NC 授权。

相关文章