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')

相关推荐
大圣编程14 分钟前
Python中continue语句的用法是什么?
开发语言·前端·python
yuhaiqiang15 分钟前
随手 vibecoding 的浏览器插件已经 6000 多次下载,聊聊他的产品设计
前端·后端·面试
之歆1 小时前
Vue商品详情与放大镜组件
前端·javascript·vue.js
再吃一根胡萝卜2 小时前
如何把小米 MiMo 接入 CodeBuddy,打造私有 Agent
前端
负责的蛋挞3 小时前
异步HttpModule的实现方式
java·服务器·前端
丹宇码农5 小时前
把 HLS 字幕玩出花:zwPlayer 如何让 M3U8 视频支持全文搜索、翻译与码率自适应
前端·javascript·音视频·hls·视频播放器
2501_943782355 小时前
【共创季稿事节】猜数字游戏:二分法思维与交互式反馈
前端·游戏·microsoft·harmonyos·鸿蒙·鸿蒙系统
GV191rLvq6 小时前
基于Socket实现的最简单的Web服务器【ASP.NET原理分析】
服务器·前端·asp.net
吠品6 小时前
LangChain 里 tool_call_id 为空?一次 MCP 工具集成的排查记录
前端