千锋教育-做有情怀、有良心、有品质的职业教育机构

当前位置:首页  >  IT问答库  >  零基础学软件测试

3步搭建Cypress测试框架,前端回归效率提升较高

发布:cli 2026-05-10 06:13

推荐答案

01 为什么是Cypress?前端测试的3个致命痛点

传统前端测试工具(Selenium、Puppeteer)有一个共同问题:它们运行在浏览器之外。这就导致3个致命痛点:

痛点1:时间黑洞

Selenium测试一个登录流程,平均需要45秒。因为每个操作都要发送HTTP请求,等待响应,再执行下一步。Cypress直接在浏览器内执行,同样的测试只需8秒。

速度不是优势,是生存法则。

痛点2:调试噩梦

Selenium报错“Element not found”,你永远不知道是元素没加载、网络延迟、还是选择器写错。Cypress提供时间旅行——每一步操作都有截图和录像,你可以回放测试过程,看到每一毫秒发生了什么。

痛点3:异步地狱

前端应用99%的问题出在异步操作。Selenium需要手动添加WebDriverWait,一个等待条件写20行代码。Cypress自动等待——元素可见、动画结束、网络请求完成,全自动处理。

看一段对比代码:

javascript
// Selenium等待方式
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("submit-btn")));
driver.findElement(By.id("submit-btn")).click();

// Cypress等待方式
cy.get('#submit-btn').click(); // 自动等待元素可见、可点击

Cypress的代码量减少80%,可读性提升100%。

02 30分钟搭建你的第一个Cypress测试

环境要求:Node.js 12+,一个前端项目(Vue/React/Angular都行)

步骤1:安装Cypress

bash
# 在你的项目目录下
npm install cypress --save-dev

安装完成后,打开Cypress:

bash
npx cypress open

第一次运行会创建默认文件夹结构:

  • ►cypress/e2e:测试文件
  • ►cypress/fixtures:测试数据
  • ►cypress/support:自定义命令

步骤2:编写第一个E2E测试

在cypress/e2e下创建login.spec.js:

javascript
describe('登录功能测试', () => {
  beforeEach(() => {
    // 每次测试前访问登录页面
    cy.visit('http://localhost:3000/login')
  })

  it('输入正确账号密码,登录成功', () => {
    // 输入用户名
    cy.get('#username').type('admin')
    // 输入密码
    cy.get('#password').type('123456')
    // 点击登录按钮
    cy.get('button[type="submit"]').click()
    // 验证跳转到首页
    cy.url().should('include', '/dashboard')
    // 验证显示欢迎信息
    cy.contains('欢迎回来,admin').should('be.visible')
  })

  it('输入错误密码,显示错误提示', () => {
    cy.get('#username').type('admin')
    cy.get('#password').type('wrongpassword')
    cy.get('button[type="submit"]').click()
    // 验证错误提示
    cy.get('.error-message').should('be.visible')
      .and('contain', '密码错误')
  })
})

步骤3:运行测试

命令行运行(无头模式):

bash
npx cypress run

浏览器运行(可视化模式):

bash
npx cypress open

点击测试文件,Cypress会自动启动浏览器,执行测试,每一步都有实时反馈。

测试不是找bug,是证明系统按预期运行。

03 Cypress核心API:5个命令掌握80%场景

Cypress的命令链式调用,每个命令返回一个Chainable对象。掌握这5个命令,就能覆盖大部分测试场景:

1. cy.get() - 元素选择器
javascript
// CSS选择器

cy.get('.class-name') // 类名

cy.get('#id-name') // ID

cy.get('button') // 标签

cy.get('[data-cy="submit"]') // 属性选择器(推荐)

// 最佳实践:使用data-*属性

// HTML: <button data-cy="submit">提交</button>

cy.get('[data-cy="submit"]').click()

2. cy.contains() - 文本内容定位
javascript
// 查找包含特定文本的元素

cy.contains('登录') // 第一个包含"登录"的元素

cy.contains('button', '提交') // 按钮中的"提交"

3. cy.intercept() - 网络请求拦截(核心功能)
javascript
// 拦截API请求,模拟响应

cy.intercept('GET', '/api/users', {

statusCode: 200,

body: { users: [{ name: '张三' }] }

}).as('getUsers')

// 等待请求完成

cy.wait('@getUsers')

4. cy.wait() - 等待(大多数时候不需要)
javascript
// 显式等待(仅用于特殊场景)

cy.wait(1000) // 等待1秒(不推荐)

// 更好的方式:等待元素出现

cy.get('.loading-spinner', { timeout: 10000 })

.should('not.exist')

5. cy.request() - 直接发送请求
javascript
// 跳过UI,直接测试API

cy.request('POST', '/api/login', {

username: 'admin',

password: '123456'

}).then((response) => {

expect(response.status).to.eq(200)

expect(response.body.token).to.exist

})

实战案例:测试一个搜索功能

javascript
describe('搜索功能测试', () => {

it('输入关键词,显示搜索结果', () => {

// 1. 拦截搜索API

cy.intercept('GET', '/api/search?q=*', {

fixture: 'search-results.json' // 使用测试数据

}).as('searchRequest')

// 2. 访问页面

cy.visit('/search')

// 3. 输入搜索词

cy.get('#search-input').type('Cypress')

// 4. 点击搜索按钮

cy.get('#search-btn').click()

// 5. 等待API请求完成

cy.wait('@searchRequest')

// 6. 验证结果显示

cy.get('.result-item').should('have.length', 3)

cy.get('.result-item').first().should('contain', 'Cypress入门')

})

})

> 测试代码不该比业务代码复杂。

04 从手动到自动:一个表单测试的蜕变

手动测试一个注册表单需要:输入10个字段、选择下拉框、上传文件、点击提交、等待3秒、验证结果。重复10次浏览器版本测试,耗时30分钟。

Cypress测试这段逻辑,耗时3秒。

完整表单测试代码:

javascript
describe('用户注册表单测试', () => {
  beforeEach(() => {
    cy.visit('/register')
  })

  it('填写完整信息,注册成功', () => {
    // 1. 填写基本信息
    cy.get('#username').type('testuser')
    cy.get('#email').type('test@example.com')
    cy.get('#password').type('Password123!')
    cy.get('#confirm-password').type('Password123!')

    // 2. 选择下拉框
    cy.get('#country').select('中国')
    cy.get('#city').select('北京')

    // 3. 勾选复选框
    cy.get('#agree-terms').check()

    // 4. 上传文件
    cy.get('#avatar').attachFile('avatar.jpg')  // 需要cypress-file-upload插件

    // 5. 提交表单
    cy.get('button[type="submit"]').click()

    // 6. 验证成功提示
    cy.contains('注册成功').should('be.visible')
    cy.url().should('include', '/welcome')
  })

  it('密码不匹配,显示错误', () => {
    cy.get('#username').type('testuser')
    cy.get('#email').type('test@example.com')
    cy.get('#password').type('Password123!')
    cy.get('#confirm-password').type('DifferentPassword')

    cy.get('button[type="submit"]').click()

    // 验证密码不匹配错误
    cy.contains('密码不一致').should('be.visible')
    cy.url().should('not.include', '/welcome')
  })

  it('必填字段为空,表单阻止提交', () => {
    cy.get('button[type="submit"]').click()

    // HTML5验证阻止提交
    cy.url().should('include', '/register')
    
    // 验证错误提示
    cy.get('#username:invalid').should('exist')
    cy.get('#email:invalid').should('exist')
  })
})

测试数据管理:

在cypress/fixtures/user.json中存储测试数据:

json
{
  "validUser": {
    "username": "testuser",
    "email": "test@example.com",
    "password": "Password123!"
  },
  "invalidUser": {
    "username": "",
    "email": "invalid-email",
    "password": "123"
  }
}

测试中使用fixture:

javascript
cy.fixture('user').then((user) => {
  cy.get('#username').type(user.validUser.username)
})

自动化测试不是减少工作量,是转移工作量——从重复劳动到智能验证。

05 持续集成:让Cypress在CI/CD中自动运行

测试写好了,但只在本地跑等于没写。真正的价值在于每次代码提交都自动运行。

GitHub Actions配置示例:

在项目根目录创建.github/workflows/test.yml:

yaml
name: E2E Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Start application
      run: npm start &   # 启动开发服务器
      
    - name: Run Cypress tests
      uses: cypress-io/github-action@v5
      with:
        record: true
        parallel: true
      env:
        CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}

关键配置说明:

  • ►npm start &:后台启动应用服务器
  • ►record: true:将测试结果上传到Cypress Dashboard
  • ►parallel: true:并行运行测试,减少时间

性能优化技巧:

1. 并行运行测试:将测试拆分为多个文件,并行执行

2. 使用cypress run --spec:只运行特定测试文件

3. 缓存依赖:在CI中缓存node_modules

bash
# 只运行登录测试
npx cypress run --spec "cypress/e2e/login.spec.js"

# 运行多个文件
npx cypress run --spec "cypress/e2e/login.spec.js,cypress/e2e/register.spec.js"

测试报告集成:

安装Mocha报告器:

bash
npm install --save-dev mochawesome

配置cypress.config.js:

javascript
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  reporter: 'mochawesome',
  reporterOptions: {
    reportDir: 'cypress/reports',
    overwrite: false,
    html: true,
    json: true
  },
  e2e: {
    baseUrl: 'http://localhost:3000'
  }
})

最佳实践清单:

1. 每个测试独立:不依赖其他测试的状态

2. 使用beforeEach:每个测试前重置状态

3. 避免cy.wait(数字):用cy.get().should()替代

4. 使用自定义命令:封装重复操作

javascript
// cypress/support/commands.js
Cypress.Commands.add('login', (username, password) => {
  cy.visit('/login')
  cy.get('#username').type(username)
  cy.get('#password').type(password)
  cy.get('button[type="submit"]').click()
})

// 测试中使用
cy.login('admin', '123456')

---

测试不是为了证明代码没问题,而是为了证明代码按预期运行。Cypress把这句话变成了3秒的现实。

下一步行动:

1. 在你的项目中运行npx cypress open

2. 写第一个cy.get().click().should()测试

3. 在CI中配置自动运行

前端测试不再是负担。Cypress让每个开发者都能成为测试工程师。

想系统学习软件测试?

千锋教育软件测试课程,零基础入门,企业级项目实战,高薪就业,一站式搞定!

了解课程详情
最新问答资讯

01 unity用什么编程语言?unity学习难度大吗

学习 unity 语言
6020 人关注

02 python容易学吗?学好python有什么好处?

学习 python 工作 培训
5389 人关注

03 html是什么语言?html学习难吗?

学习 html 语言 可以
5062 人关注

04 c语言难学吗?c语言学好要多久?

语言 技术 学习
4733 人关注

06 学好平面设计要多久?报速成班靠谱吗?

平面 设计 学习 时间
4238 人关注

相关问题

3步搭建Cypress测试框架,前端回归效率提升较高

深圳软件测试培训机构师资力量对比:千锋教育如何敢亮底牌?

零基础学软件测试的时间规划与安排

JMeter vs LoadRunner:性能测试工具选型,较高的人选错了

从传统到敏捷,你的测试团队为什么慢人一步?

3步搭建Cypress测试框架,前端回归效率提升较高

测一测
你知道多少IT梗