如果您在 Drupal 开发中不包含测试,很可能是因为您认为它增加了复杂性和成本,而没有带来好处。Cypress 是一个具有诸多优势的开源工具
- 可靠地测试在 Web 浏览器中运行的任何内容
- 可在任何 Web 平台上运行(它非常适合测试使用前端技术的项目,如 React)
- 高度可扩展
- 越来越受欢迎
- 易于学习和实施
- 在您的项目变得更加复杂时,防止回归
- 可以使您的开发过程更有效率
本文涵盖三个主题,帮助您开始使用 Cypress 测试您的 Drupal 项目
安装 Cypress
为了本教程的目的,我假设您已经使用 `drupal/recommended-project` 项目为您的 Drupal 项目构建了一个本地开发环境。虽然创建此类项目的详细信息不在本文的范围之内,但我建议您参考 Lando 和 Drupal 9 入门。
您的项目至少具有以下基本结构
vendor/
web/
.editorconfig
.gitattributes
composer.json
composer.lock
cypress.io 网站提供了针对各种环境的完整安装说明。 对于本文,我使用 npm 安装了 Cypress。
使用命令 npm init
初始化您的项目。 回答 Node.js 向您提出的问题,然后您将拥有一个类似于以下的 package.json
文件
{
"name": "cypress",
"version": "1.0.0",
"description": "Installs Cypress in a test project.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
在您的项目中安装 Cypress
$ npm install cypress --save-dev
首次运行 Cypress
$ npx cypress open
因为您尚未向 Cypress 添加配置或任何脚手架文件,Cypress 应用程序会显示欢迎屏幕以帮助您配置项目。 要为 E2E(端到端)测试配置您的项目,请单击 E2E 测试的未配置按钮。 Cypress 会向您的项目添加一些文件
cypress/
node_modules/
vendor/
web/
.editorconfig
.gitattributes
composer.json
composer.lock
cypress.config.js
package-lock.json
package.json
单击继续并选择您首选的浏览器进行测试。 单击在 [您选择的浏览器] 中启动 E2E 测试。 在本文中,我使用的是基于 Chromium 的浏览器。
在一个单独的窗口中,浏览器将打开到创建您的第一个规范页面

(Jordan Graham,CC BY-SA 4.0)
单击脚手架示例规范按钮以创建几个包含示例规范的新文件夹,以帮助您了解如何使用 Cypress。 在您的代码编辑器中通读这些内容,您可能会发现该语言(基于 JavaScript)直观且易于理解。
在测试浏览器中单击任何。 这将显示两个面板。 左侧的文本面板显示活动规范中的每个步骤。 右侧的模拟浏览器窗口显示 Cypress 执行规范步骤时的实际用户体验。
在您的项目根目录中打开 cypress.config.js
文件,并按如下方式进行更改
const { defineConfig } = require("cypress");
module.exports = defineConfig({
component: {
fixturesFolder: "cypress/fixtures",
integrationFolder: "cypress/integration",
pluginsFile: "cypress/plugins/index.js",
screenshotsFolder: "cypress/screenshots",
supportFile: "cypress/support/e2e.js",
videosFolder: "cypress/videos",
viewportWidth: 1440,
viewportHeight: 900,
},
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: "https://[your-local-dev-url]",
specPattern: "cypress/**/*.{js,jsx,ts,tsx}",
supportFile: "cypress/support/e2e.js",
fixturesFolder: "cypress/fixtures"
},
});
将 baseUrl
更改为您的本地开发环境中项目的 URL。
这些更改告诉 Cypress 在哪里找到其资源以及如何找到项目中的所有规范。
使用 Cypress 编写和运行基本测试
在您的 /cypress
目录中创建一个名为 integration
的新目录。 在 integration
目录中,创建一个名为 test.cy.js
的文件
cypress/
├─ e2e/
├─ fixtures/
├─ integration/
│ ├─ test.cy.js
├─ support/
node_modules/
vendor/
web/
.editorconfig
.gitattributes
composer.json
composer.lock
cypress.config.js
package-lock.json
package.json
将以下内容添加到您的 test.cy.js
文件中
describe('Loads the front page', () => {
it('Loads the front page', () => {
cy.visit('/')
cy.get('h1.page-title')
.should('exist')
});
});
describe('Tests logging in using an incorrect password', () => {
it('Fails authentication using incorrect login credentials', () => {
cy.visit('/user/login')
cy.get('#edit-name')
.type('Sir Lancelot of Camelot')
cy.get('#edit-pass')
.type('tacos')
cy.get('input#edit-submit')
.contains('Log in')
.click()
cy.contains('Unrecognized username or password.')
});
});
当您在 Cypress 应用程序中单击 test.cy.js
时,观看左侧的每个测试描述,因为 Cypress 执行每个 describe()
部分中的步骤。
此规范演示了如何告诉 Cypress 导航您的网站、通过 ID 访问 HTML 元素、在输入元素中输入内容以及提交表单。 此过程是我发现我需要添加断言,即 <input id="edit-submit">
元素包含文本登录,然后输入才能被点击的原因。 显然,提交输入的 flex 样式阻碍了 Cypress “看到”输入的能力,因此它无法单击它。 测试真的有效!
为 Drupal 定制 Cypress
您也可以编写自己的自定义 Cypress 命令。 还记得 cypress.config.js
文件中的 supportFile
条目吗? 它指向 Cypress 添加的文件,而该文件又导入 ./commands
文件。 顺便说一句,Cypress 非常聪明,当导入逻辑或数据 fixtures 时,您无需指定文件扩展名,因此您导入 ./commands
,而不是 ./commands.js
。 Cypress 会查找十几个左右的流行文件扩展名中的任何一个,并了解如何识别和解析它们中的每一个。
在 commands.js
中输入命令来定义它们
/**
* Logs out the user.
*/
Cypress.Commands.add('drupalLogout', () => {
cy.visit('/user/logout');
})
/**
* Basic user login command. Requires valid username and password.
*
* @param {string} username
* The username with which to log in.
* @param {string} password
* The password for the user's account.
*/
Cypress.Commands.add('loginAs', (username, password) => {
cy.drupalLogout();
cy.visit('/user/login');
cy.get('#edit-name')
.type(username);
cy.get('#edit-pass').type(password, {
log: false,
});
cy.get('#edit-submit').contains('Log in').click();
});
此示例定义了一个名为 drupalLogout()
的自定义 Cypress 命令,您可以在任何后续逻辑中使用它,甚至可以用于其他自定义命令。 要注销用户,请调用 cy.drupalLogout()
。 这是自定义命令 loginAs
中的第一个事件,以确保在尝试以特定用户身份登录之前 Cypress 已注销。
使用环境变量,您甚至可以创建一个名为 drush()
的 Cypress 命令,您可以使用它在测试或自定义命令中执行 Drush 命令。 看一下这使得定义一个自定义 Cypress 命令变得多么简单,该命令使用用户的 UID 登录用户
/**
* Logs a user in by their uid via drush uli.
*/
Cypress.Commands.add('loginUserByUid', (uid) => {
cy.drush('user-login', [], { uid, uri: Cypress.env('baseUrl') })
.its('stdout')
.then(function (url) {
cy.visit(url);
});
});
此示例使用 drush user-login
命令(简写为 drush uli
),并将经过身份验证的用户带到站点的基本 URL。
考虑一下在测试中永远不读取或存储用户密码的安全优势。 就我个人而言,我发现像 Cypress 这样的前端技术可以执行 Drush 命令真是太神奇了,我一直认为 Drush 命令非常后端。
测试,测试
Cypress 还有很多内容,例如 fixtures(保存测试数据的文件)和各种技巧,用于导航有时会产生网站用户界面的复杂数据结构。 要了解可能实现的功能,请观看Cypress 测试 Drupal 网站网络研讨会,特别是关于从 18:33 开始的 fixtures 部分。 该网络研讨会更详细地介绍了 一些有趣的用例,包括启用 Ajax 的表单。 一旦您开始使用它,请随意使用或 fork Aten 的 Cypress 测试 Drupal 公共存储库。
祝您测试愉快!
本文最初发表在 Aten 博客上,并经许可转载。
评论已关闭。