You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cypress中抽象重复的UI断言链式调用逻辑?

问题:Cypress UI断言重复代码的抽象优化

我在用Cypress编写UI断言测试时,发现大量重复的链式调用代码,想知道能不能把这些逻辑抽象成辅助方法,提升代码可维护性并减少冗余?

示例代码:

it('displays the table column headers', () => {
      DivisionPage.divisionNameColumnHeader()
        .should('be.visible')
        .and('have.css', 'text-transform', 'capitalize')
        .and('have.css', 'color', 'rgb(35, 40, 43)')
        .and('have.css', 'background-color', 'rgb(195, 202, 206)')
        .and('have.css', 'cursor', 'pointer')
        .and('have.css', 'font-family', '"Open Sans"')
        .and('have.css', 'position', 'sticky')
      DivisionPage.teamsColumnHeader()
        .should('be.visible')
        .and('have.css', 'text-transform', 'capitalize')
        .and('have.css', 'color', 'rgb(35, 40, 43)')
        .and('have.css', 'background-color', 'rgb(212, 217, 220)')
        .and('have.css', 'cursor', 'pointer')
        .and('have.css', 'font-family', '"Open Sans"')
        .and('have.css', 'position', 'sticky')
      DivisionPage.playersColumnHeader()
        .should('be.visible')
        .and('have.css', 'text-transform', 'capitalize')
        .and('have.css', 'color', 'rgb(35, 40, 43)')
        .and('have.css', 'background-color', 'rgb(212, 217, 220)')
        .and('have.css', 'cursor', 'pointer')
        .and('have.css', 'font-family', '"Open Sans"')
        .and('have.css', 'position', 'sticky')
})

注:已使用页面对象模型,DivisionPage.divisionNameColumnHeader()等价于cy.get('[data-cy="division-name-column-header"]')


解决方案

当然可以通过抽象辅助方法解决重复代码问题,结合你已有的页面对象模型(POM),有两种常用实现方式:

方案1:在页面对象中封装通用断言方法

直接在DivisionPage类里添加通用断言方法,抽离所有列头共享的样式断言,仅针对差异化属性(比如背景色)传入自定义参数。

修改后的DivisionPage代码:

class DivisionPage {
  // 原有元素定位方法
  divisionNameColumnHeader() {
    return cy.get('[data-cy="division-name-column-header"]');
  }
  teamsColumnHeader() {
    return cy.get('[data-cy="teams-column-header"]');
  }
  playersColumnHeader() {
    return cy.get('[data-cy="players-column-header"]');
  }

  // 封装通用列头断言逻辑
  assertColumnHeader(element, customStyles = {}) {
    // 基础样式断言(所有列头共享规则)
    element
      .should('be.visible')
      .and('have.css', 'text-transform', 'capitalize')
      .and('have.css', 'color', 'rgb(35, 40, 43)')
      .and('have.css', 'cursor', 'pointer')
      .and('have.css', 'font-family', '"Open Sans"')
      .and('have.css', 'position', 'sticky');
    
    // 应用自定义样式(比如不同列的背景色)
    Object.entries(customStyles).forEach(([prop, value]) => {
      element.and('have.css', prop, value);
    });
  }
}

export default new DivisionPage();

简化后的测试用例:

it('displays the table column headers', () => {
  DivisionPage.assertColumnHeader(DivisionPage.divisionNameColumnHeader(), {
    'background-color': 'rgb(195, 202, 206)'
  });
  
  DivisionPage.assertColumnHeader(DivisionPage.teamsColumnHeader(), {
    'background-color': 'rgb(212, 217, 220)'
  });
  
  DivisionPage.assertColumnHeader(DivisionPage.playersColumnHeader(), {
    'background-color': 'rgb(212, 217, 220)'
  });
});

方案2:自定义全局Cypress命令

如果多个页面都需要类似的列头断言,可以把逻辑封装成全局命令,在所有测试用例中直接调用。

在cypress/support/commands.js中添加自定义命令:

Cypress.Commands.add('assertColumnHeader', { prevSubject: true }, (subject, customStyles = {}) => {
  cy.wrap(subject)
    .should('be.visible')
    .and('have.css', 'text-transform', 'capitalize')
    .and('have.css', 'color', 'rgb(35, 40, 43)')
    .and('have.css', 'cursor', 'pointer')
    .and('have.css', 'font-family', '"Open Sans"')
    .and('have.css', 'position', 'sticky');
  
  Object.entries(customStyles).forEach(([prop, value]) => {
    cy.wrap(subject).and('have.css', prop, value);
  });
});

测试用例中使用方式:

it('displays the table column headers', () => {
  DivisionPage.divisionNameColumnHeader().assertColumnHeader({
    'background-color': 'rgb(195, 202, 206)'
  });
  
  DivisionPage.teamsColumnHeader().assertColumnHeader({
    'background-color': 'rgb(212, 217, 220)'
  });
  
  DivisionPage.playersColumnHeader().assertColumnHeader({
    'background-color': 'rgb(212, 217, 220)'
  });
});

两种方案对比

  • 页面对象封装:贴合POM设计原则,逻辑与具体页面绑定,适合仅当前页面使用的断言,便于页面内维护。
  • 自定义全局命令:全局可用,适合多页面共享的通用断言,减少跨页面重复代码。

内容的提问来源于stack exchange,提问作者Rinkala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 18:11:01