十、Cypress最佳实践——写出高效又好维护的测试

Cypress最佳实践------写出高效又好维护的测试

用Cypress写测试不难,但写出稳定、简洁、易维护的测试却需要技巧。这一章咱们聊聊实战中的最佳实践,从项目结构到代码细节,帮你避开"写时一时爽,维护火葬场"的坑。

一、基础配置:让测试跑起来更顺畅

1. 配置baseUrl减少重复代码

cypress.json里设置baseUrl,测试中访问页面时就不用写完整URL了,既简洁又方便切换环境:

json 复制代码
// cypress.json
{
  "baseUrl": "http://localhost:7077"
}
javascript 复制代码
// 直接写相对路径,自动拼接baseUrl
cy.visit('/login') // 等同于访问http://localhost:7077/login

2. 禁用不必要的等待,依赖自动重试

传统测试工具里,我们习惯用sleep(1000)等待页面加载,但Cypress的命令会自动等待元素可操作(默认等4秒),完全不用手动加等待。

javascript 复制代码
// 错误示例:多余的等待
cy.visit('/dashboard')
cy.wait(2000) // 没必要!cy.get会自动等待
cy.get('[data-cy=stats]').should('contain', '销售额')

// 正确做法:依赖Cypress的自动重试
cy.visit('/dashboard')
cy.get('[data-cy=stats]').should('contain', '销售额') // 会自动等元素加载

二、测试用例设计:聚焦核心场景

1. 避免"大而全"的用例,拆分独立场景

一个用例只测一个功能点,比如"登录成功""登录失败(密码错误)""登录失败(账号为空)"应该拆成3个用例,而不是写在一个it里。

好处:失败时能精准定位问题,且可以单独重跑某个场景。

2. 动态生成用例,应对多组数据

如果多个场景的步骤相同,只是输入/输出不同(比如测试登录时的各种错误提示),用数据驱动动态生成用例,不用复制粘贴代码:

javascript 复制代码
// 测试数据:不同输入对应的预期结果
const testData = [
  { username: '', password: '', expectError: '请输入账号' },
  { username: 'jane', password: 'wrong', expectError: '密码错误' },
  { username: 'invalid', password: '123', expectError: '账号不存在' }
]

describe('登录错误场景', () => {
  // 循环数据生成用例
  testData.forEach((data) => {
    it(`输入${data.username}/${data.password}时,提示${data.expectError}`, () => {
      cy.visit('/login')
      cy.get('input[name=username]').type(data.username)
      cy.get('input[name=password]').type(data.password)
      cy.get('[data-cy=login-btn]').click()
      cy.get('[data-cy=error-msg]').should('contain', data.expectError)
    })
  })
})

三、代码复用:减少重复劳动

1. 用Custom Commands封装重复操作

把常用步骤(比如登录、添加商品到购物车)封装成自定义命令,在cypress/support/commands.js里定义:

javascript 复制代码
// 定义登录命令
Cypress.Commands.add('login', (username, password) => {
  cy.visit('/login')
  cy.get('input[name=username]').type(username)
  cy.get('input[name=password]').type(password)
  cy.get('[data-cy=login-btn]').click()
})

之后在所有测试用例里直接调用:

javascript 复制代码
// 测试中直接用cy.login()
it('登录后访问个人中心', () => {
  cy.login('jane.lane', 'password123') // 复用登录逻辑
  cy.visit('/profile')
  cy.get('[data-cy=username]').should('contain', 'jane.lane')
})

2. 用fixture管理测试数据

测试中用到的静态数据(比如用户信息、接口模拟数据)别硬编码在代码里,放在cypress/fixtures文件夹下,用cy.fixture()读取:

json 复制代码
// cypress/fixtures/user.json
{
  "username": "jane.lane",
  "password": "password123",
  "nickname": "简"
}
javascript 复制代码
// 测试中读取fixture数据
it('使用fixture数据登录', () => {
  cy.fixture('user.json').then((user) => {
    cy.login(user.username, user.password) // 用fixture里的数据
  })
})

四、断言与调试:让失败原因一目了然

1. 用清晰的断言描述预期结果

断言不仅要判断"对不对",还要说明"预期是什么",方便其他人看懂测试意图:

javascript 复制代码
// 不好的断言:只知道错了,不知道预期是什么
cy.get('[data-cy=user-count]').should('eq', 5)

// 好的断言:清晰说明预期
cy.get('[data-cy=user-count]')
  .should('contain', '5')
  .and('be.visible') // 同时验证可见性

2. 测试失败时自动截图/录屏

Cypress默认会在测试失败时自动截图,无头模式(cypress run)下还会录屏,这些文件保存在cypress/screenshotscypress/videos里,配合日志能快速定位问题。

如果想手动截图,用cy.screenshot()

javascript 复制代码
// 在关键步骤手动截图
cy.get('[data-cy=order-summary]').screenshot('订单摘要')

五、避坑指南:这些做法要不得

  • 别测UI样式细节:比如颜色、字体大小(容易随设计变更,增加维护成本),专注测功能逻辑。
  • 别依赖第三方服务 :测试中用到的接口尽量用cy.intercept() mock掉,避免因第三方服务不稳定导致测试失败。
  • 别在测试中操作数据库:直接改数据库会污染测试环境,应该通过接口或UI操作准备数据。
相关推荐
TT哇1 小时前
【实习】数字营销系统 银行经理端(interact_bank)前端 Vue 移动端页面的 UI 重构与优化
java·前端·vue.js·ui
蓝帆傲亦1 小时前
Web前端跨浏览器兼容性完全指南:构建无缝用户体验的最佳实践
前端
晴殇i1 小时前
【前端缓存】localStorage 是同步还是异步的?为什么?
前端·面试
不一样的少年_1 小时前
Chrome 插件实战:如何实现“杀不死”的可靠数据上报?
前端·javascript·监控
深度涌现1 小时前
DNS详解——域名是如何解析的
前端
小码哥_常1 小时前
Android内存泄漏:成因剖析与高效排查实战指南
前端
卤代烃1 小时前
✨ 形势比人强,Chrome 大佬也去搞 Gemini 了
前端·agent·vibecoding
偶像佳沛1 小时前
JS 对象
前端·javascript
Jing_Rainbow1 小时前
【React-6/Lesson89(2025-12-27)】React Context 详解:跨层级组件通信的最佳实践📚
前端·react.js·前端框架
gustt1 小时前
构建全栈AI应用:集成Ollama开源大模型
前端·后端·ollama