惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

O
OpenAI News
I
InfoQ
云风的 BLOG
云风的 BLOG
博客园 - 【当耐特】
D
DataBreaches.Net
H
Help Net Security
爱范儿
爱范儿
F
Fortinet All Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
Netflix TechBlog - Medium
WordPress大学
WordPress大学
GbyAI
GbyAI
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园_首页
C
Check Point Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
G
Google Developers Blog
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
M
MIT News - Artificial intelligence
Recent Announcements
Recent Announcements
P
Proofpoint News Feed
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
MyScale Blog
MyScale Blog
Recorded Future
Recorded Future
B
Blog
J
Java Code Geeks
T
The Blog of Author Tim Ferriss
Jina AI
Jina AI
博客园 - Franky
B
Blog RSS Feed
The GitHub Blog
The GitHub Blog
量子位
博客园 - 叶小钗
Hugging Face - Blog
Hugging Face - Blog
Cyberwarzone
Cyberwarzone
Google Online Security Blog
Google Online Security Blog
SecWiki News
SecWiki News
V
Vulnerabilities – Threatpost
AWS News Blog
AWS News Blog
Cisco Talos Blog
Cisco Talos Blog
G
GRAHAM CLULEY
T
Tor Project blog
腾讯CDC
美团技术团队
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News and Events Feed by Topic

BlogFinder

日常漫步 Vol.24 之漫步前山河 - 雅余 周报 #1-聊聊本周的收获 - Edwin's Blog 我的OpenCode必装插件与Skill Write Something 掌中之物未必在掌握之中 · CRIVU PiliNara,一个更顺手的 PiliPlus 分支 「NekoEcho」:做一个必有回响的猫娘主题博客 2026-05 书影音总结 简化博客主题 - 安迪 你要加油呐 我第一次发布 npm 包 拾花小记#45:中考前的二三事 – 小改学习志 黛西花园5月游 #18 枇杷又熟了的五月月报 一些奇奇怪怪的需求?word仿方正书版的几个小操作 - Xiobb's Blog 0419 御温泉之旅 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 又回到四十年前 如何定义成功 迷鹿屋2026已重新上线 科技冰火两重天+一周回顾 ${title} 热度退了,我反而用得更深了-咕咚同学 我到底该不该换个域名? 随身WIFI折腾记 - 安迪 博客撰写体验提升——hexo pro插件 为什么不用相机把屏幕上的接关密码拍下来? 国清寺与天台山 – Ouroboros ★★★★☆《挽救计划》——久违的经济上行感 - Davidの3号基地 删除右键“打开方式”里多余选项 第三周刊_No.53|一切都会被支付两次 安卓APP通话记录与录音上传踩坑记录 - 子舒的博客 天量下跌 inBox 笔记 2.3.8,把工具栏交给了你-咕咚同学 我把小龙虾搬到了微信-咕咚同学 安好 - 响石潭 Compound Engineering Plugin:让每个工程单元都比上一个更容易 MOSS-TTS Family:开源高质量语音与声音生成模型家族深度解析 Crawl4AI:专为 LLM 设计的开源 Web 爬虫与数据抓取工具 Build Your Own X:从零实现你最喜欢的技术——程序员进阶的终极资源清单 Anthropic Skills:用文件夹教 Claude 专业技能的开源框架 1年的去月球(下) - 梅之夏 欢迎回来。 简单讲讲 ASN.1 与 OID DTV - 直播聚合客户端 5.22-5.27 – 不兴江 还没去过鸭川 – 不兴江 张晶晶同学三刷林志颖 关于我 – 不兴江 爱与嫉妒 – 不兴江 港股被持续做空 备案码花了四百块-咕咚同学 一句话生成封面:我给公众号做了4种风格的AI封面生成技能 「官」方認證 再谈费曼学习法 2026-05-28T00:34:11+08:00 2026-05-28T00:28:45+08:00 离谱的英语学习指南:基于AI的英语进阶系统方法论 iii:零集成架构的后端统一运行时 Claude Code Harness:让 Claude Code 工作有迹可循的工程化框架 Heretic:全自动移除大语言模型审查机制的开源工具 MarkItDown:微软开源的万能文档转 Markdown 利器 Harness:让 Claude Code 秒变多智能体协作工厂 这段时间尽折腾AI Agent了,确实极大地提高了效率 近期动态:两个新站点正式上线啦 误判解除!zhouayuan.com 腾讯安全申诉成功 - 周阿源|玩具设计・插画日常・生活随笔 Ralph:让 AI 编码工具自主循环跑完所有 PRD 任务的量产神器 全都违法 – 个人工作记录 关于zhouayuan.com被误判 “含违规信息” 的说明与申诉记录 - 周阿源|玩具设计・插画日常・生活随笔 小米 MiMo v2.5 Pro 白嫖 最大的人间清醒,兜里有钱,但是不花。 夜晚靓歌(12):于文文现场solo - 王志勇的Blog 今日插画:风扬起的倔强 - 周阿源|玩具设计・插画日常・生活随笔 回门习俗 独立网卡 - 忘记了回忆 500亿入股人工智能企业 从命令行到桌面智能体-咕咚同学 第一性原理读书笔记 行者微评论223-加班の守株待兔-博客|政治与时事-风雨行者 ZOZO开源物理接触求解器:GPU加速的可扩展仿真引擎 OpenStock:开源股票市场交易平台技术深度解析 MoneyPrinterTurbo:基于AI的全自动短视频生成工具深度解析 Claude-Mem:为 Claude Code 构建的持久化记忆压缩系统 Twenty:可代码化定制的企业级开源 CRM 平台技术深度解析 2026-05-26T22:59:17+08:00 企业级开源大模型部署平台 GPUStack 实战教程 1年的去月球(上) - 梅之夏 Sevalla - 静态网站托管服务 不用翻墙、不用注册、不用月费,普通人也能用上 Claude Code 装修灯具要注意⚠️ 黄梅天先锋 - 游子微博 公安备案顺利办结,站点备案全部完成 - 周阿源|玩具设计・插画日常・生活随笔 第三次兑换天猫超市卡了宗宗酱-三维狐少儿编程 Don't think, feel. - Rolen's Blog 人这一辈子,到底图个什么 博客迁移 - Edwin's Blog 情感赛道写作模板 再现本轮行情的典型特征 裁员与平常心-咕咚同学 别让“偷懒”,成为隐私泄露的破绽
Cypress:现代 Web 应用测试的革命性工具
Cheman · 2026-06-15 · via BlogFinder

今天在 GitHub Trending 上看到一个有意思的项目:Cypress,这是一款专为现代 Web 应用打造的前端测试工具。不同于传统的 Selenium 等测试框架,Cypress 从底层重新思考了测试的运行方式,让 Web 测试变得快速、简单且可靠。

一、项目概述

Cypress 是一个下一代前端测试工具,专为现代 Web 构建。它的核心理念是:“Web 已经进化,测试工具也终于跟上了。"(The web has evolved. Finally, testing has too.)

核心特性:

  • 真正的浏览器内运行:Cypress 测试直接在浏览器中运行,与应用程序共享相同的运行循环
  • 自动等待:无需手动添加等待和休眠,Cypress 会自动等待元素可见、动画完成、网络请求完成等
  • 实时重载:代码修改后立即重新运行测试
  • 时间旅行:可以回溯到测试运行的每一步,查看当时发生的所有事情
  • 网络流量控制:可以 stub 和 mock 任意网络请求
  • 截图和视频:测试失败时自动截图和录制视频

解决的问题:

传统测试工具(如 Selenium)存在诸多痛点:

  • 测试运行缓慢且不稳定(flaky tests)
  • 调试困难,错误信息不明确
  • 需要配置复杂的 WebDriver
  • 无法有效控制浏览器行为

Cypress 通过架构创新解决了这些问题,它不使用 WebDriver,而是直接与浏览器交互。

二、技术原理

架构设计

Cypress 的架构与传统测试工具完全不同。从源码的 package.json 可以看出,它采用了 Lerna Monorepo 架构管理多个包:

"workspaces": {
  "packages": [
    "cli",
    "packages/*",
    "npm/*",
    "tooling/*",
    "system-tests",
    "scripts"
  ]
}

核心架构分层:

  1. Driver(驱动层):运行在浏览器中,与应用程序代码共存
  2. Node Server(服务端):运行在 Node.js 中,控制浏览器生命周期
  3. Cypress CLI(命令行):用户交互入口,管理测试执行流程
  4. Electron:内置浏览器,用于 Headless 测试

核心技术栈

package.json 的 devDependencies 可以看出技术选型:

运行时环境:

  • Electron 37.6.0:内置 Chromium 内核,支持 Headless 模式
  • Node.js ≥22.19.0:利用现代 JavaScript 特性

开发语言:

  • TypeScript 5.3.3:类型安全,更好的 IDE 支持
  • Vue + React:用于 Cypress 自身的 UI(Test Runner)

测试框架:

  • Mocha 3.5.3:经典的 BDD/TDD 测试框架
  • Vitest ^3.2.4:现代化的单元测试工具

构建工具:

  • Gulp 4.0.2:任务自动化
  • Lerna 8.1.9:Monorepo 管理
  • ESBuild:快速打包

GraphQL 集成:

// apollo.config.js
module.exports = {
  client: {
    service: {
      name: 'cypress-io',
      localSchemaFile: path.join(__dirname, 'packages/data-context/schemas/schema.graphql'),
    },
    tagName: 'gql',
    includes: [
      'packages/{launchpad,app,frontend-shared}/src/**/*.{vue,ts,js,tsx,jsx}'
    ],
  },
}

Cypress 内部使用 GraphQL 进行数据管理,通过 Apollo Client 与后端 API 交互。

关键算法与设计模式

1. 异步命令队列

Cypress 所有命令都是异步的,但通过链式调用和内部命令队列实现"同步式"编写:

cy.get('.submit').click()  // 自动等待元素出现
cy.get('.input').type('hello')  // 自动等待输入框可交互
cy.contains('Submit').should('be.visible')  // 自动重试断言

源码中通过 cy 对象的命令封装,实现了自动等待和重试机制。

2. 网络代理

Cypress 通过内置的代理服务器拦截所有网络请求:

// 从 package.json scripts 可以看出
"cypress:run": "cypress run --dev"

在测试运行时,Cypress 会启动一个代理服务器(@packages/proxy),所有 fetch 和 XHR 请求都会被拦截,从而实现:

  • 记录所有网络请求
  • 模拟服务器响应(cy.intercept)
  • 等待请求完成(cy.wait)

3. V8 Snapshot 优化

从构建脚本可以看出:

"build-v8-snapshot-prod": "node --max-old-space-size=8192 tooling/v8-snapshot/scripts/setup-v8-snapshot-in-cypress.js"

Cypress 使用 V8 Snapshot 技术预编译 JavaScript 代码,大幅提升启动速度。

数据流分析

测试执行的数据流:

用户命令 (cypress open/run)
    ↓
CLI 解析参数,启动 Node Server
    ↓
Node Server 启动 Electron 浏览器
    ↓
浏览器加载 Cypress Driver(注入到测试页面)
    ↓
Driver 执行测试代码,通过 WebSocket 与 Node Server 通信
    ↓
Node Server 控制浏览器行为(访问 URL、截图、录制等)
    ↓
测试结果实时反馈到 Test Runner UI

三、安装与快速开始

环境要求

  • Node.js:≥22.19.0(从 package.json 的 engines 字段可知)
  • 操作系统:macOS、Linux、Windows
  • 包管理器:npm、yarn 或 pnpm

安装步骤

方式一:npm

npm install cypress --save-dev

方式二:yarn

方式三:pnpm

pnpm add cypress --save-dev

安装完成后,Cypress 二进制文件会自动下载。如果下载失败,可以设置镜像:

# 使用淘宝镜像
export CYPRESS_DOWNLOAD_MIRROR=https://registry.npmmirror.com/-/binary/cypress

最简运行示例

1. 打开 Cypress Test Runner

首次运行会初始化项目结构:

cypress/
├── e2e/          # 端到端测试文件
├── fixtures/     # 测试数据
├── support/      # 全局配置和辅助函数
└── tsconfig.json # TypeScript 配置

2. 编写第一个测试

创建 cypress/e2e/sample.cy.js

describe('My First Test', () => {
  it('Visits the Kitchen Sink', () => {
    cy.visit('https://example.cypress.io')
    cy.contains('type').click()
    cy.url().should('include', '/commands/actions')
    cy.get('.action-email')
      .type('[email protected]')
      .should('have.value', '[email protected]')
  })
})

3. 运行测试

# 打开 Test Runner(交互式)
npx cypress open

# 或 Headless 模式运行
npx cypress run

四、使用方法与实战

基础用法

1. 元素选择与交互

// 通过 CSS 选择器获取元素
cy.get('.submit-button').click()

// 通过文本内容获取元素
cy.contains('Submit').click()

// 通过 data-cy 属性(推荐)
cy.get('[data-cy=submit]').click()

2. 断言

Cypress 集成了 Chai、Sinon 和 Mocha,支持 BDD 和 TDD 断言风格:

// 隐式断言
cy.get('.todo-list li').should('have.length', 2)

// 显式断言
expect(2 + 2).to.equal(4)

// 链式断言
cy.get('.error').should('be.red')
  .and('contain', 'Error message')

3. 网络请求 Mock

// 拦截并模拟 API 响应
cy.intercept('GET', '/api/users', {
  statusCode: 200,
  body: [{ id: 1, name: 'John' }],
}).as('getUsers')

// 等待请求完成
cy.wait('@getUsers').then((interception) => {
  expect(interception.response.statusCode).to.equal(200)
})

进阶用法

1. 自定义命令

cypress/support/commands.js 中定义全局命令:

Cypress.Commands.add('login', (username, password) => {
  cy.visit('/login')
  cy.get('[data-cy=username]').type(username)
  cy.get('[data-cy=password]').type(password)
  cy.get('[data-cy=submit]').click()
})

然后在测试中使用:

cy.login('testuser', 'password123')

2. 组件测试

Cypress 10+ 支持组件测试(Component Testing):

import React from 'react'
import { mount } from 'cypress/react'

describe('MyComponent', () => {
  it('renders correctly', () => {
    mount(<MyComponent title="Hello" />)
    cy.contains('Hello').should('be.visible')
  })
})

3. 插件系统

Cypress 提供丰富的插件生态,例如:

// cypress.config.js
export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:3000',
    setupNodeEvents(on, config) {
      // 安装插件
      require('@cypress/code-coverage/task')(on, config)
      return config
    },
  },
})

实际项目示例

场景:测试登录功能

describe('Login Flow', () => {
  beforeEach(() => {
    // 每个测试前访问登录页
    cy.visit('/login')
  })

  it('should display error with invalid credentials', () => {
    cy.get('[data-cy=username]').type('wronguser')
    cy.get('[data-cy=password]').type('wrongpass')
    cy.get('[data-cy=submit]').click()
    
    // 验证错误消息
    cy.get('.error-message')
      .should('be.visible')
      .and('contain', 'Invalid credentials')
  })

  it('should redirect to dashboard after successful login', () => {
    cy.get('[data-cy=username]').type('validuser')
    cy.get('[data-cy=password]').type('validpass')
    cy.get('[data-cy=submit]').click()
    
    // 验证跳转
    cy.url().should('include', '/dashboard')
    cy.get('[data-cy=welcome]').should('contain', 'Welcome back!')
  })
})

五、常见问题与解决方案

安装失败

问题:Cypress 二进制文件下载失败

错误信息:

Error: read ECONNRESET

解决方案:

  1. 使用国内镜像:
export CYPRESS_DOWNLOAD_MIRROR=https://registry.npmmirror.com/-/binary/cypress
npm install cypress --save-dev
  1. 手动下载并指定路径:
# 下载对应版本的 zip 文件
export CYPRESS_INSTALL_BINARY=/path/to/cypress.zip
npm install cypress --save-dev

运行时错误

问题:元素未找到(Element not found)

解决方案:

  1. 增加超时时间:
cy.get('.slow-loading-element', { timeout: 10000 }).should('be.visible')
  1. 使用 cy.wait() 等待特定条件:
cy.intercept('GET', '/api/data').as('getData')
cy.wait('@getData')  // 等待网络请求完成
cy.get('.data-table').should('be.visible')

问题:跨域错误(CORS)

解决方案:

cypress.config.js 中配置:

export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:3000',
    chromeWebSecurity: false,  // 禁用 Web Security(仅开发环境)
  },
})

性能问题

问题:测试运行缓慢

解决方案:

  1. 并行运行测试:
cypress run --parallel --record --key <record-key>
  1. 使用 Cypress Cloud 的智能调度

  2. 优化测试代码:

    • 避免不必要的 cy.wait()
    • 使用 cy.session() 缓存登录状态
    • 减少截图和视频录制(CI 环境)
// 缓存登录状态
Cypress.Commands.add('loginBySession', () => {
  cy.session('user-session', () => {
    cy.request({
      method: 'POST',
      url: '/api/login',
      body: { username: 'test', password: 'test' },
    }).then((response) => {
      window.localStorage.setItem('token', response.body.token)
    })
  })
})

兼容性问题

问题:与旧版浏览器不兼容

Cypress 只支持现代浏览器(Chrome、Firefox、Edge、Electron)。

解决方案:

对于需要测试 IE 的场景,可以:

  1. 使用 Sauce Labs 或 BrowserStack 进行云端测试
  2. 仅对核心功能编写 Cypress 测试,其余使用 Unit Test

六、总结

Cypress 通过架构创新和技术优化,为现代 Web 应用测试带来了革命性的体验。其核心优势包括:

  1. 开发者体验极佳:实时重载、时间旅行、清晰的错误处理
  2. 测试稳定可靠:自动等待、智能重试、内置 Mock
  3. 生态丰富:插件系统、TypeScript 支持、CI/CD 集成
  4. 性能优异:V8 Snapshot、并行执行、智能调度

从 Cypress 的源码可以看出,它不仅是一个测试工具,更是一个精心设计的技术产品:

  • Monorepo 架构 便于模块化开发
  • TypeScript + GraphQL 保证类型安全和数据一致性
  • Electron + Chromium 提供一致的测试环境
  • Semantic Release 实现自动化版本管理

如果你正在寻找一款现代、高效、易用的 Web 测试工具,Cypress 绝对值得尝试。它不仅能够提升测试效率,还能改善整个开发团队的协作流程。

相关资源:

  • 官方文档:https://docs.cypress.io
  • GitHub 仓库:https://github.com/cypress-io/cypress
  • Discord 社区:https://discord.com/invite/cypress
  • Cypress Cloud:https://www.cypress.io/cloud

本文基于 Cypress 最新源码分析,感谢开源社区的贡献!