章
目
录
本文将讲解如何使用Cypress对Vue 3 + Quasar 2项目开展端到端(E2E)测试,涵盖测试环境搭建、用例编写、常用API及实用技巧等方面。
一、技术框架与测试工具
本项目采用TypeScript作为主要开发语言,结合Vue 3的强大功能以及Composition API的便捷性进行开发,同时使用Quasar 2.15.1构建用户界面。在测试工具的选择上,选用了Cypress,它为E2E测试提供了丰富的功能和简洁的操作方式。此外,还需安装以下依赖:
@quasar/quasar-app-extension-testing-e2e-cypresst:用于Quasar测试集成,帮助在项目中更好地整合Cypress进行测试。@cypress/code-coverage:用于统计测试的覆盖率,方便了解测试对代码的覆盖程度。cypress:核心测试库,提供了一系列测试功能和API。eslint-plugin-cypress:用于在TypeScript项目中对Cypress相关代码进行检查和规范。
二、根目录配置(cypress.config.ts)
在项目的根目录下,cypress.config.ts文件用于配置Cypress的各项参数。具体代码如下:
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',
// Cypress Cloud项目标识符,方便在Cypress Cloud平台上管理项目测试
projectId: 'ecb187bc-5198-45a2-8da8-1c418e87363d',
// 启用测试过程录屏,方便查看测试执行过程
video: true,
e2e: {
// 注册代码覆盖率检测插件,用于分析测试对代码的覆盖情况
setupNodeEvents(on, config) {
registerCodeCoverageTasks(on, config)
return config
},
// 被测应用基础地址,这里是本地开发服务器地址
baseUrl: 'http://localhost:8080/',
// 测试支撑文件路径,包含一些自定义的测试命令或辅助函数
supportFile: 'test/cypress/support/e2e.ts',
// 测试文件匹配模式,指定哪些文件是测试文件,这里匹配test/cypress/e2e目录下的.cy.ts文件
specPattern: 'test/cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
},
component: {
// 注入Quasar框架的Vite开发服务器配置,确保组件测试环境正确
setupNodeEvents(on, config) {
registerCodeCoverageTasks(on, config)
return config
},
// 组件测试的支撑文件路径
supportFile: 'test/cypress/support/component.ts',
// 组件测试文件直接扫描src目录下的.cy.ts文件
specPattern: 'src/**/*.cy.{js,jsx,ts,tsx}',
// 自定义组件测试的HTML模板,用于渲染组件进行测试
indexHtmlFile: 'test/cypress/support/component-index.html',
// 注入Quasar的开发服务器配置,为组件测试提供服务
devServer: injectQuasarDevServerConfig(),
},
})
三、测试用例编写与目录结构
项目中的测试用例主要存放在test/cypress/e2e目录下,例如home.cy.ts和order.cy.ts。整个测试相关的目录结构如下:
├─ 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
四、Cypress常用API详解
(一)元素操作
在测试过程中,经常需要对页面元素进行各种操作。
cy.get(selector):通过选择器获取页面元素。例如cy.get('#submit-btn'),表示获取id为submit-btn的元素。cy.contains(text):用于获取包含特定文本的元素。比如cy.contains('登录'),能找到页面上包含“登录”文本的元素。.click():对获取到的元素进行点击操作。像cy.get('button').click(),就是点击页面上的按钮元素。.type(text):在输入框中输入文本。例如cy.get('input').type('Hello'),会在找到的输入框中输入“Hello”。.clear():清空输入框内容。如cy.get('input').clear(),可清空指定输入框。.check()/.uncheck():用于勾选或取消勾选复选框。cy.get('[type="checkbox"]').check()表示勾选类型为checkbox的元素。.select(value):选择下拉框中的选项。cy.get('select').select('option1')会选择下拉框中值为option1的选项。.trigger(event):触发DOM事件。cy.get('div').trigger('mouseover')能对指定的div元素触发鼠标悬停事件。
(二)导航与路由
Cypress提供了一系列方法来模拟页面导航和路由操作。
cy.visit(url):用于访问指定的页面。例如cy.visit('/login'),会访问项目中的登录页面。cy.go(direction):实现浏览器的前进或后退操作。cy.go('back')表示返回上一页。cy.reload():重新加载当前页面。cy.reload(true)可以强制重新加载页面。cy.intercept(method, url):拦截网络请求。cy.intercept('GET', '/api/data').as('getData')表示拦截对/api/data的GET请求,并将其命名为getData,之后可以通过cy.wait('@getData').its('response.statusCode').should('eq', 200)来验证该请求的响应状态码是否为200。
(三)断言与验证
断言是测试中用于验证预期结果的重要手段。
should(chainers):用于断言元素的状态。比如cy.get('h1').should('have.text', 'Welcome'),验证h1元素的文本内容是否为“Welcome”;cy.get('.list').should('have.length', 5),检查类名为list的元素数量是否为5。cy.url():用于验证当前页面的URL。cy.url().should('include', '/dashboard'),判断当前URL是否包含/dashboard。cy.title():验证页面标题。cy.title().should('eq', 'Home'),检查页面标题是否为“Home”。cy.wrap(value):包装对象以便进行断言。cy.wrap({ name: 'John' }).its('name').should('eq', 'John'),验证包装对象的name属性是否为“John”。
(四)调试与日志
在测试过程中,调试和记录日志有助于排查问题。
cy.log(message):输出日志信息。cy.log('正在执行登录操作'),会在测试日志中记录“正在执行登录操作”。cy.pause():暂停测试执行,方便检查中间状态。cy.debug():进入调试模式,例如cy.get('input').debug(),可以在调试模式下查看输入框元素相关信息。cy.screenshot():截取屏幕截图。cy.screenshot('login-page'),会截取当前屏幕并保存为login-page截图。
(五)文件与数据
在测试中,处理文件和数据是常见需求。
cy.fixture(filePath):加载测试数据文件。cy.fixture('user.json').then((user) => { cy.get('input').type(user.name) }),从user.json文件中读取数据,并在输入框中输入用户名。cy.readFile(path):读取本地文件。如cy.readFile('cypress/fixtures/data.txt'),读取指定路径的文件内容。cy.writeFile(path, content):写入文件。cy.writeFile('logs.txt', '测试完成'),会在logs.txt文件中写入“测试完成”。
(六)浏览器控制
Cypress还提供了控制浏览器行为的方法。
cy.viewport(width, height):设置浏览器视口尺寸。cy.viewport('iphone-6')可使用预设的iPhone 6设备尺寸;cy.viewport(1024, 768)则可以自定义视口尺寸。cy.scrollTo(position):用于滚动页面。cy.scrollTo('bottom')会将页面滚动到底部。cy.clearCookies():清除浏览器中的Cookies。
(七)钩子函数
钩子函数可以在测试的不同阶段执行特定操作。
before(() => {}):在所有测试用例执行前执行一次。例如before(() => cy.resetDatabase()),在所有测试开始前重置数据库。beforeEach(() => {}):在每个测试用例执行前都会执行。beforeEach(() => cy.login()),每次测试前都会执行登录操作。afterEach(() => {}):在每个测试用例执行后执行。afterEach(() => cy.screenshot()),每次测试后截取屏幕截图。after(() => {}):在所有测试用例执行后执行一次。after(() => cy.clearCookies()),所有测试结束后清除Cookies。
五、常用技巧分享
(一)链式调用
Cypress支持链式调用,使测试代码更加简洁和易读。例如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')表示等待类名为loading的元素在10秒内消失,如果10秒内元素未消失则测试失败。
通过上述内容,相信你对Vue 3 + Quasar 2项目的E2E测试有了更深入的理解。掌握这些知识,能够帮助大家更好地进行项目测试,有兴趣的测试友友们赶紧去试试吧。





