Vue 3 + quasar 2 E2E测试

框架与库

  • 使用 TypeScript 作为主要开发语言
  • 使用 Vue 3 + Composition API
  • 使用 quasar 2.15.1
  • 测试工具库:cypress

需要安装的依赖

  • @quasar/quasar-app-extension-testing-e2e-cypresst // quasar测试集成
  • @cypress/code-coverage // 覆盖率
  • cypress // 测试库
  • eslint-plugin-cypress // TS

根目录配置(cypress.config.ts)

javascript 复制代码
import registerCodeCoverageTasks from '@cypress/code-coverage/task'
import { injectQuasarDevServerConfig } from '@quasar/quasar-app-extension-testing-e2e-cypress/cct-dev-server'
import { defineConfig } from 'cypress'

export default defineConfig({
  fixturesFolder: 'test/cypress/fixtures', // 测试数据存储路径
  screenshotsFolder: 'test/cypress/screenshots',  // 截图存储路径
  videosFolder: 'test/cypress/videos', // 视频存储路径
  projectId: 'ecb187bc-5198-45a2-8da8-1c418e87363d', // Cypress Cloud项目标识符
  video: true, // 启用测试过程录屏
  e2e: {
    setupNodeEvents(on, config) { // 注册代码覆盖率检测插件
      registerCodeCoverageTasks(on, config)
      return config
    },
    baseUrl: 'http://localhost:8080/', // 被测应用基础地址(本地开发服务器)
    supportFile: 'test/cypress/support/e2e.ts', // 测试支撑文件路径
    specPattern: 'test/cypress/e2e/**/*.cy.{js,jsx,ts,tsx}', // 测试文件匹配模式(匹配test/cypress/e2e目录下的.cy.ts文件)
  },
  component: { // 组件测试(component)配置
    setupNodeEvents(on, config) { // 注入Quasar框架的Vite开发服务器配置
      registerCodeCoverageTasks(on, config)
      return config
    },
    supportFile: 'test/cypress/support/component.ts',
    specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}', // 组件测试文件直接扫描src目录下的.cy.ts文件
    indexHtmlFile: 'test/cypress/support/component-index.html', // 自定义组件测试的HTML模板
    devServer: injectQuasarDevServerConfig(),
  },
})

测试用例编写

arduino 复制代码
目录结构
├─ test
│  ├─ cypress
│  │  ├─ e2e // 测试文件
│  │  │  ├─ home.cy.ts
│  │  │  └─ order.cy.ts
│  │  ├─ fixtures // 环境
│  │  │  └─ example.json
│  │  ├─ screenshots // 截图
│  │  ├─ support // 支撑文件存放位置
│  │  │  ├─ commands.ts
│  │  │  ├─ component-index.html
│  │  │  ├─ component.ts
│  │  │  └─ e2e.ts
│  │  ├─ tsconfig.json
│  │  ├─ videos // 视频
│  │  └─ wrappers
│  │     ├─ DialogWrapper.vue
│  │     └─ LayoutContainer.vue

常用API

一、元素操作

csharp 复制代码
cy.get(selector)

通过选择器获取元素

vbnet 复制代码
cy.get('#submit-btn')

cy.contains(text)

获取包含文本的元素

scss 复制代码
cy.contains('登录')

.click()

点击元素

scss 复制代码
cy.get('button').click()

.type(text)

输入文本

bash 复制代码
cy.get('input').type('Hello')

.clear()

清空输入框

csharp 复制代码
cy.get('input').clear()

.check() / .uncheck()

勾选/取消复选框

csharp 复制代码
cy.get('[type="checkbox"]').check()

.select(value)

选择下拉框选项

csharp 复制代码
cy.get('select').select('option1')

.trigger(event)

触发DOM事件

csharp 复制代码
cy.get('div').trigger('mouseover')

二、导航与路由

arduino 复制代码
cy.visit(url)

访问页面

arduino 复制代码
cy.visit('/login')

cy.go(direction)

浏览器前进/后退

go 复制代码
cy.go('back')

cy.reload()

重新加载页面

scss 复制代码
cy.reload(true)

cy.intercept(method, url)

拦截网络请求

csharp 复制代码
cy.intercept('GET', '/api/data').as('getData')
cy.wait('@getData').its('response.statusCode').should('eq', 200)

三、断言与验证

scss 复制代码
.should(chainers)

断言元素状态

csharp 复制代码
cy.get('h1').should('have.text', 'Welcome')
cy.get('.list').should('have.length', 5)

cy.url()

验证当前URL

scss 复制代码
cy.url().should('include', '/dashboard')

cy.title()

验证页面标题

lua 复制代码
cy.title().should('eq', 'Home')

cy.wrap(value)

包装对象进行断言

lua 复制代码
cy.wrap({ name: 'John' }).its('name').should('eq', 'John')

四、调试与日志

arduino 复制代码
cy.log(message)

输出日志

arduino 复制代码
cy.log('正在执行登录操作')

cy.pause()

暂停测试

scss 复制代码
cy.pause()

cy.debug()

进入调试模式

scss 复制代码
cy.get('input').debug()

cy.screenshot()

截取屏幕

arduino 复制代码
cy.screenshot('login-page')

五、文件与数据

scss 复制代码
cy.fixture(filePath)

加载测试数据

scss 复制代码
cy.fixture('user.json').then((user) => {
  cy.get('input').type(user.name)
})

cy.readFile(path)

读取本地文件

lua 复制代码
cy.readFile('cypress/fixtures/data.txt')

cy.writeFile(path, content)

写入文件

arduino 复制代码
cy.writeFile('logs.txt', '测试完成')

六、浏览器控制

arduino 复制代码
cy.viewport(width, height)

设置视口尺寸

scss 复制代码
cy.viewport('iphone-6') // 预设设备
cy.viewport(1024, 768) // 自定义尺寸

cy.scrollTo(position)

滚动页面

scss 复制代码
cy.scrollTo('bottom')

cy.clearCookies()

清除Cookies

scss 复制代码
cy.clearCookies()

七、钩子函数

scss 复制代码
before(() => {})

所有测试前执行

scss 复制代码
before(() => cy.resetDatabase())

beforeEach(() => {})

每个测试前执行

scss 复制代码
beforeEach(() => cy.login())

afterEach(() => {})

每个测试后执行

scss 复制代码
afterEach(() => cy.screenshot())

after(() => {})

所有测试后执行

scss 复制代码
after(() => cy.clearCookies())

常用技巧

  • 链式调用

    cy.get('form') .find('input') .first() .type('test@example.com')

  • 自定义命令

    Cypress.Commands.add('login', (email, password) => { cy.visit('/login') cy.get('#email').type(email) cy.get('#password').type(password) cy.get('form').submit() }) // 测试中使用 cy.login('user@test.com', 'pass123')

  • 动态等待

    cy.get('.loading', { timeout: 10000 }).should('not.exist')

相关推荐
大怪v2 小时前
AI抢饭?前端佬:我要验牌!
前端·人工智能·程序员
新酱爱学习2 小时前
字节外包一年,我的技术成长之路
前端·程序员·年终总结
小兵张健2 小时前
开源 playwright-pool 会话池来了
前端·javascript·github
IT_陈寒5 小时前
Python开发者必知的5大性能陷阱:90%的人都踩过的坑!
前端·人工智能·后端
codingWhat5 小时前
介绍一个手势识别库——AlloyFinger
前端·javascript·vue.js
代码老中医5 小时前
2026年CSS彻底疯了:这6个新特性让我删掉了三分之一JS代码
前端
不会敲代码15 小时前
Zustand:轻量级状态管理,从入门到实践
前端·typescript
踩着两条虫5 小时前
VTJ.PRO 双向代码转换原理揭秘
前端·vue.js·人工智能
扉川川5 小时前
OpenClaw 架构解析:一个生产级 AI Agent 是如何设计的
前端·人工智能
远山枫谷5 小时前
一文理清页面/组件通信与 Store 全局状态管理
前端·微信小程序