在前端开发中,保证代码质量和稳定性是非常重要的。而自动化测试,尤其是端对端(End-to-End,简称 E2E)测试对于保证代码质量和稳定性则是不可或缺的。Cypress 是一个现代化的 E2E 测试框架,它建立在现代化的 JavaScript 语言之上,并且通过使用它,我们可以更轻松的构建、调试和运行 E2E 测试。
本文将会介绍 Cypress 框架的基本使用,以及一些实例介绍和最佳实践,供前端开发者学习和参考。
前置知识
在阅读本文之前,需要读者掌握一些前置技能,包括:
- 前端开发技能,如 HTML、CSS 和 JavaScript
- Node.js 和 npm 的基础知识
- 基本的 E2E 测试知识和经验
Cypress 基础
安装 Cypress
首先,我们需要安装 Cypress。在安装 Cypress 之前,需要确保已经在您的电脑上安装了 Node.js 和 npm。
然后,在您的项目中安装 Cypress,可以通过以下命令:
npm install cypress --save-dev
启动 Cypress
在安装 Cypress 后,我们需要启动 Cypress。可以在命令行中输入以下命令来启动 Cypress:
./node_modules/.bin/cypress open
或者,您可以打开 package.json
并将以下代码添加到 "scripts"
部分中:
{ "scripts": { "cy:open": "cypress open" } }
之后,在命令行中,您可以使用以下命令启动 Cypress:
npm run cy:open
启动 Cypress 后,它会自动检测您的项目目录,并在 Cypress 界面中列出您的测试用例。
创建测试用例
在 Cypress 界面中,您可以看到 examples
文件夹中自带了一些测试用例。当然,您也可以删除该文件夹以及其中的内容,然后自己创建测试用例。创建测试用例的方法非常简单,只需要在 cypress/integration
目录中创建一个 JavaScript 文件,例如 example.spec.js
,这里是一个简单示例:
describe('My First Test', () => { it('Does not do much!', () => { expect(true).to.equal(true) }) })
上面的代码包含一个测试用例,它使用 describe
函数来定义在这个测试用例之前需要执行的任何代码,并使用 it
函数定义一个具体的测试用例。此测试用例断言表达式 expect(true).to.equal(true)
是否通过。
运行测试用例
在 Cypress 界面中,单击任何测试用例的名称以运行该测试用例。当测试开始运行时,Cypress 界面将会打开并在其中显示浏览器。测试用例会在该浏览器中自动运行,并在左侧的 Cypress 界面中显示测试结果。
Cypress 实例
模拟用户输入
在 E2E 测试中,模拟用户输入是常见的场景。Cypress 提供了一种模拟用户输入的方法。在下面的示例中,我们将测试一个输入域的输入是否成功,并检查输入值是否正确。
我们首先需要添加一个 HTML 文件,并添加一个文本输入框,并指定一个 ID:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- --------- ------------ ------- ------ ------ ------ ------------------------ ------ ----------- --------- ------------ ---- ------ ------------- --------------- ------- ------- -------
然后,我们在 Cypress 中编写以下代码:
describe('Input Test', () => { it('Can type in input field', () => { cy.visit('https://www.example.com') cy.get('input[name=name]').type('John Doe').should('have.value', 'John Doe') }) })
上面的代码使用 cy.visit()
方法打开一个页面,并在输入框中键入 John Doe
,然后使用 should()
方法检查输入值是否正确。
模拟用户点击元素
另一个常见的用例是检查是否可以单击按钮。在下面的示例中,我们将测试一个按钮的单击事件是否触发,并检查按钮是否已被单击。
我们需要在 HTML 中添加一个简单的按钮,并使用 ID 标识符:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- --------- ------------ ------- ------ ------- ----------------- ------------ ------- -------
然后我们在 Cypress 中编写以下代码:
-- -------------------- ---- ------- ---------------- ------ -- -- - ------- ----- -------- -- -- - ----------------------------------- ------------------------- -------------------------------------- ---------- -- --
上面的代码使用 cy.visit()
方法打开一个页面,并使用 cy.get()
方法选择 ID 为 my-btn
的元素。然后在该元素上调用 click()
方法模拟单击事件,并使用 should()
方法检查按钮是否被单击。
模拟网络请求
Cypress 还提供了一种模拟网络请求的方法以及一些常见的网络请求用例。在下面的示例中,我们将模拟已成功处理的网络请求,并检查返回结果是否正确。
我们首先需要在 HTML 中添加一个简单的表单,并使用 ID 标识符来标识表单字段:
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- --------- ------------ ------- ------ ------ ------ -------------------------------- ------ ----------- ------------- ---------------- ------ -------------------------------- ------ --------------- ------------- ---------------- ------- ----------------------------- ------- ------- -------
然后,我们在 Cypress 中编写以下代码:
-- -------------------- ---- ------- ----------------- ------ -- -- - ------- ---- ------- ------ -- -- - -------------------- ------------------------------- - ----------- ---- ----- ------- ------- ------------- ----------------------------------- ------------------------------------ -------------------------------------- ----------------------- -------------------------------------------------------- ---- -------------------------------------------------- ------- -------- -- --
上面的代码使用 cy.intercept()
方法来与网络请求进行交互,并使用 cy.wait()
方法等待网络请求结束。最后使用 its()
方法来访问参数,例如返回状态码和返回体,并使用 should()
方法检查这些参数是否正确。
Cypress 最佳实践
在局部单独运行测试用例
当只想运行单个测试用例时,可以在 Cypress 界面中点选该测试用例以运行。
避免在 E2E 测试中使用外部 API
在 E2E 测试中应该避免与其他应用程序进行通信。这是因为可能会发生错误,例如 API 响应速度较慢,API 随时面临改变等。
使用 Cypress 命令代替 sleep
Cypress 提供了一些内置的命令,例如 cy.wait()
, cy.clock()
, 和 cy.tick()
。 让我们使用这些命令来避免使用 setTimeout()
或 setInterval()
函数。例如:
cy.get('#my-btn').click() cy.wait(3000) cy.reload()
上面的代码中,我们等待 3 秒钟然后重新加载页面。在此示例中, cy.wait()
等待时间不确定。相反,我们可以使用在 Cypress 中使用 cy.clock()
和 cy.tick()
命令达到相同的效果:
cy.get('#my-btn').click() cy.clock() cy.tick(3000) cy.reload()
在这个示例中,我们调用 cy.clock()
,然后使用 cy.tick()
命令停止新的请求,这保证了 cy.reload()
命令将在 3 秒后执行。
使用命令别名
您可以使用别名将命令组成更简洁和易于使用的命令。例如,下面的代码将会在复杂的测试用例中更易于阅读和使用。
Cypress.Commands.add('submitAdminForm', () => { cy.get('#username').type('admin') cy.get('#password').type('admin') cy.get('form').submit() })
在上面的代码中,我们添加了一个名为 submitAdminForm()
命令别名。这个别名代表了三个命令组合在一起,使得我们可以更轻松地使用它们。例如:
-- -------------------- ---- ------- --------------- ------ -- -- - ------- ----- -- ------- -- -- - ----------------------------------- -------------------- -- --- -- --
配置持续集成
Cypress 可以与多个持续集成平台进行集成,例如 CircleCI、Travis CI 和 Jenkins 等。配置持续集成有助于检测问题并及时修复。
总结
通过本文,您应该能够建立起一个基础的 Cypress 测试框架,并进行一些基本的 E2E 测试。通过示例和最佳实践,您应该能够更好地了解和掌握 Cypress,并使用它来构建可靠、高效且功能齐全的 E2E 测试套件。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64cb4f4f5ad90b6d041fcc98