菜单

核心测试基础设施

相关源文件

本文档概述了驱动 Cypress 测试功能的底层系统。它解释了实现 Cypress 命令排队和执行、管理被测应用程序 (AUT) 状态以及处理浏览器交互的内部架构。

核心测试基础设施负责命令执行模型、浏览器自动化和测试稳定性机制,这些构成了所有 Cypress 测试能力的基础。有关网络拦截等特定测试功能的信息,请参阅 网络拦截

架构概述

Cypress 的核心测试基础设施由几个关键组件组成,它们协同工作,提供了一个强大、确定性的测试环境。

核心组件图

来源:[packages/driver/src/cypress.ts], [packages/driver/src/cypress/cy.ts], [packages/driver/src/cypress/command_queue.ts], [packages/driver/src/cypress/commands.ts], [packages/driver/src/cypress/chainer.ts]

命令执行系统

Cypress 的核心是其命令执行系统,它实现了一个异步的、类似 Promise 的操作链。

命令队列流程

来源:[packages/driver/src/cypress/cy.ts:178-246], [packages/driver/src/cypress/command_queue.ts:231-402]

命令执行系统遵循以下关键原则:

  1. 命令排队:命令不会立即执行,而是被排队进行串行执行。
  2. 自动等待:命令会自动重试,直到断言通过或超时。
  3. 主体管理:每个命令都会将一个主体传递给链中的下一个命令。
  4. 自动 Promise 解析:Cypress 会自动等待 Promise 解析。

命令类型

Cypress 有两种主要类型的命令:

命令类型描述示例
父命令启动新链并传递新主体cy.get(), cy.visit()
子命令继续链并操作之前的主体.click(), .type()
双重命令可以充当父命令或子命令cy.contains()
查询返回函数的特殊命令cy.find()

来源:[packages/driver/src/cypress/commands.ts:87-120], [packages/driver/src/cypress/command_queue.ts:293-297]

命令生命周期

来源:[packages/driver/src/cypress/command.ts:7-39]

当命令执行时:

  1. 它以 queued 状态创建。
  2. 命令队列设置当前命令并更新为 pending 状态。
  3. 使用适当的参数调用命令函数。
  4. 如果成功,命令将过渡到 passed 状态,并将主体传递给下一个命令。
  5. 如果失败,命令将过渡到 failed 状态,并且测试将失败。

核心基础设施组件

$Cypress 类

$Cypress 类([packages/driver/src/cypress.ts])是 Cypress 测试基础设施的主要入口点。它:

  1. 初始化测试环境
  2. 管理配置设置
  3. 创建和配置 cy 对象
  4. 协调系统组件之间的通信
  5. 与 Mocha 测试运行器集成

主要方法包括

  • configure():设置初始配置
  • run():通过 Mocha 运行器执行测试
  • onSpecWindow():初始化 spec 窗口环境
  • action():处理组件之间的事件和操作

来源:[packages/driver/src/cypress.ts:167-368], [packages/driver/src/cypress.ts:400-765]

$Cy 类

$Cy 类([packages/driver/src/cypress/cy.ts])是测试作者的主要接口,它作为全局 cy 对象暴露。它:

  1. 管理命令执行
  2. 跟踪和更新测试状态
  3. 处理主体链接
  4. 提供核心实用方法
  5. 管理稳定性检测和自动等待

主要方法包括

  • addCommand():注册新命令
  • addQuery():注册新查询
  • enqueue():将命令添加到队列
  • runQueue():触发命令队列执行
  • setSubjectForChainer():更新链式调用的主体
  • fail():处理测试失败

来源:[packages/driver/src/cypress/cy.ts:210-290], [packages/driver/src/cypress/cy.ts:356-782]

命令队列

$CommandQueue 类([packages/driver/src/cypress/command_queue.ts])管理命令的排队和执行。

  1. 维护有序的命令列表
  2. 串行执行命令
  3. 处理断言的重试逻辑
  4. 管理命令状态转换
  5. 控制测试超时

主要方法包括

  • enqueue():将命令添加到队列
  • run():执行队列中的下一个命令
  • runCommand():执行特定命令函数
  • cleanup():在完成或失败后重置状态

来源:[packages/driver/src/cypress/command_queue.ts:114-605]

Command 和 Chainer 类

  • $Command([packages/driver/src/cypress/command.ts]):表示具有其属性和状态的单个命令。
  • $Chainer([packages/driver/src/cypress/chainer.ts]):提供测试作者交互的可链接 API。

来源:[packages/driver/src/cypress/command.ts:6-183], [packages/driver/src/cypress/chainer.ts:5-38]

稳定性检测系统

Cypress 包含一个复杂的应用程序稳定性检测系统,这对于确定何时继续执行测试至关重要。

稳定性确定图

来源:[packages/driver/src/cypress/cy.ts:491-578], [packages/driver/src/cy/commands/navigation.ts:170-410]

稳定性系统:

  1. 检测页面加载、导航事件、表单提交。
  2. 当应用程序变得不稳定时暂停命令执行。
  3. 检测到稳定性时自动恢复。
  4. 实施超时以防止无限等待。
  5. 为应用程序特定的稳定性确定提供自定义事件钩子。

关键的稳定性事件包括:

  • 页面加载/卸载事件
  • XHR/fetch 请求完成
  • 动画完成
  • 计时器执行
  • 导航更改

浏览器集成

Cypress 在测试运行器中创建两个 iframe:

  1. Spec iframe:包含测试代码(不可见)。
  2. AUT iframe:包含被测应用程序(可见)。

来源:[packages/runner/src/iframe/iframe.scss:22-38]

浏览器事件处理

来源:[packages/driver/src/cy/listeners.ts:70-162], [packages/driver/src/cy/commands/navigation.ts:152-168]

浏览器集成包括:

  1. 浏览器操作的事件监听器。
  2. 导航跟踪和处理。
  3. 页面加载检测。
  4. 表单提交管理。
  5. 从应用程序捕获错误。

命令注册系统

Cypress 通过 Commands API 提供系统来注册内置命令和自定义命令。

来源:[packages/driver/src/cypress/commands.ts:42-204], [packages/driver/src/cypress/cy.ts:664-781]

命令注册系统:

  1. 在初始化时注册内置命令。
  2. 提供用于插件/用户命令创建的 API。
  3. 验证命令属性。
  4. 管理命令类型(父/子/双重)。
  5. 处理命令覆盖。

错误处理系统

Cypress 包含一个强大的错误处理系统,该系统:

  1. 捕获来自命令、断言和应用程序代码的错误。
  2. 格式化带有有用上下文的错误消息。
  3. 提供带有用户代码突出显示的堆栈跟踪。
  4. 在适当的时候包含指向文档的链接。
  5. 允许通过事件进行自定义错误处理。

来源:[packages/driver/src/cypress/error_messages.ts:1-119], [packages/driver/src/cypress/cy.ts:364-469]

总结

核心测试基础设施为 Cypress 独特的测试方法提供了基础。其命令执行模型、稳定性检测和浏览器集成系统协同工作,创造了一个可靠、确定的测试环境。

理解这些核心系统对于 Cypress 的高级用法、创建自定义命令和排除测试问题至关重要。