对于测试开发来说,最头疼的莫过于 flaky tests——同一条测试,有时候过,有时候失败,还没规律。今天我们就聊聊如何用 自定义 Cypress 插件,让测试稳定、易维护,同时提升工作效率。
如果你在做端到端测试,经常会遇到这些情况:
cy.click() 报错传统解决方案:
cy.wait(500) // 等半秒再操作问题:
✅ 核心问题是:盲目等待不如智能等待。插件可以让测试像“人眼”一样,等页面真正稳定再操作。
// cypress/support/commands.js
Cypress.Commands.add('waitForSpinnerToDisappear', () => {
cy.get('.loading-spinner', { timeout: 10000 }).should('not.exist');
});小项目可以用,但逻辑无法跨项目复用,且仅能操作浏览器端。

cy.waitUntilStable(() => {
cy.get('#special-element').should('be.visible');
});Cypress.log() 帮你看到插件在做什么,调试更轻松。cy.get('#open-modal-btn').click();
cy.waitUntilStable().then(() => {
cy.get('.modal-content').should('be.visible');
cy.get('.modal-title').should('contain', '重要信息');
});cy.waitForNetworkIdle({ settleTime: 250 });your-plugin/
├── package.json
├── README.md
├── types.d.ts # TypeScript 可选
└── src/
├── index.js # Node.js 后端逻辑
└── support.js # 浏览器端自定义命令module.exports = (on, config) => {
on('task', {
logMessage(message) {
console.log(`[Plugin Log]: ${message}`);
return null;
},
// 可以增加更多任务,例如清理文件夹、读取 JSON
});
return config;
};Cypress.Commands.add('login', (username, password) => {
cy.log(`登录用户 ${username}`);
cy.visit('/login');
cy.get('#username').type(username);
cy.get('#password').type(password);
cy.get('#submit').click();
});cy.task('readJson', 'test-data/userData.json').then((data) => {
cy.get('input#name').type(data.name);
cy.get('input#email').type(data.email);
});describe('报表测试', () => {
before(() => {
cy.task('cleanFolder', 'cypress/reports');
});
});sequenceDiagram
participant T as 测试用例
participant P as 插件任务
participant F as 文件系统
T->>P: 调用 cleanFolder
P->>F: 清空 reports 文件夹
F-->>P: 完成
P-->>T: 返回自定义 Cypress 插件可以帮助测试开发者:
从日常工作痛点出发,小步迭代、封装插件、记录流程,让测试更稳定、更高效。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。