Cypress系列(4)- 自定义 Cypress & 重试机制

956 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

前言

  • Cypress 不仅支持用户自定义文件结构,还支持用户自定义 Cypress 的各项配置
  • Cypress 可以通过 cypress.json 文件来实现各项配置的自定义 【文件默认是空的】
  • 这里只介绍常用到的配置项,更多配置项请看:docs.cypress.io/zh-cn/guide…

 

全局配置项

 

超时 Timeouts相关

  • 超时是必须要了解的核心概念
  • 几乎所有命令都可能以某种方式超时
  • 所有断言,无论它们是默认断言还是自己添加的断言都具有相同的超时时间

 

文件夹 / 文件相关

相对于默认文件结构来说,Cypress 支持用户自定义的文件结构

 

可视视图

Cypress 在 Test runner 中运行时,会显示一个可视视图

 

Cypress.config()

除了直接在 cypress.json 文件里更改配置项之外,Cypress 还允许我们通过 Cypress.config() 去获取或覆盖某些配置项,语法如下:

**

// 获取所有config信息
Cypress.config()

// 获取指定配置项的信息
Cypress.config(name)

// 更改指定配置项的默认值
Cypress.config(name, value)

// 使用对象字面量(object literal)设置多个配置项
Cypress.config(object)

 

小栗子

每次测试运行前都打印所有的配置信息,将下列代码添加到 cypress/support/index.js 中

**

beforeEach(function () {
    cy.log(`当前环境变量为${JSON.stringify(Cypress.env())}`)
    cy.log(`当前配置项信息为${JSON.stringify(Cypress.config())}`)
})

运行任意测试文件,则可以看到执行 visit() 命令前打印了两次log日志

 

在测试文件的栗子

在 Integration 文件夹下创建 testConfig.js 文件

**

//<reference types="cypress" /R>

describe('测试配置项', function () {
    it('测试取值和设置值', function () {
        // 获取 pageLoadTimeout默认值
        cy.log(`pageLoadTimeout默认值是:${Cypress.config('pageLoadTimeout')}`)

        // 设置 pageLoadTimeout 值
        Cypress.config("pageLoadTimeout",100000)

        // 再次获取 pageLoadTimeout 的值

        cy.log(`pageLoadTimeout默认值是:${Cypress.config('pageLoadTimeout')}`)
    })
})

运行 testConfig.js 文件,结果如下图

重试背景

重试(Retry-ability)是 Cypress 的核心概念之一,有助于我们写出更加健壮的测试

 

命令和断言

Cypress 测试中经常被调用的两种类型,仍以前面说到的 testLogin.js 为栗子

最后的断言解析

检查标签为 h1 的元素是否包含 jane.lane

 

断言的一般步骤

  1. 用 cy.get() 查询应用程序的DOM,找到元素
  2. 针对元素或元素列表进行断言尝试 ,我们示例中为 .should("contain", "jane.lane") 

 

关于实际工作中的灵魂拷问

现在的 web 应用基本都是异步的,如果出现以下情况又应该怎么处理呢?

  1. 如果断言发生时,应用程序尚未更新DOM怎么办?
  2. 如果断言发生时,应用程序正在等待其后端响应,而导致页面暂无结果怎么办?
  3. 如果断言发生时,应用程序正在进行密集计算,而导致页面未及时更新怎么办?

上述情况在测试中经常会发生,一般处理方法是在断言前价格固定等待时间(或像 selenium 一样显式、隐式等待),但仍有可能会发生测试失败

 

Cypress 如何优美的解决上述问题

  1.  cy.get() 命令之后的断言通过,则该命令成功执行完成
  2.  cy.get() 命令之后的断言失败,则 cy.get() 命令会自动重新查询 web 应用程序的 DOM 树,然后 Cypress 将再次尝试对 cy.get() 返回的元素进行断言
  3. 如果断言仍然失败, cy.get() 仍然会重新查询 DOM 树....以此类推
  4. 直到断言成功 或 cy.get() 命令超时

总结

  • 其实很像selenium 的显式等待,只不过 Cypress 是全局的,不用针对元素去单独识别
  • Cypress 这种自动重试机制避免了在测试代码中编写硬编码等待(强制等待),使测试代码更加健壮

 

多重断言

  • 在日常测试中,有时候需要多重断言,即获取元素后跟多个断言
  • 在多重断言中,Cypress 将按顺序进行断言,即当第一个断言通过后,会进行第二个断言,通过后进行第三个断言...以此类推

 

列表的栗子

需求

  • 假设一个下拉列表,存在两个选项,第一个选项是“iTesting”,第二个选项是“testerTalk”
  • 我们需要验证两个选项的存在,并且顺序正确,代码片段如下

代码解析

  1. 总共有三个断言:一个 should() ,两个 expect() 
  2. and() 断言实际上是 should() 断言的别名,它是 should() 的自定义回调断言,其中包含两个 expect() 断言
  3. 在测试执行过程中,如果第二个断言失败了,那第三个断言永远不会执行
  4. 如果导致第二个断言失败的原因被找到且修复了,且此时整个命令还没有超时,则在进行第三个断言时,还会再次重试第一、第二个断言

 

重试(Retry-ability)的条件

前言

  • Cypress 并不会重试所有命令,当命令可能改变被测应用程序的状态时,该命令将不会重试(如: click() ,毕竟要点击)
  • Cypress 仅会重试那些查询 DOM 的命令: cy.get() 、 find() 、 contains() 等
  • 可以通过官方文档 Assertions 部分来检查是否重试了特定命令:docs.cypress.io/zh-cn/guide…

 

常用的可重试命令

 

重点啦!

重试的超时时间默认是 4秒,对应的配置项是: defaultCommondTimeout ,如果想改重试的超时时间,在 cypress.json 文件改对应的字段值即可