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

Protractor JS处理大型重复测试任务的最优设计模式

多步重复测试任务的最优实现方案

针对你提到的changeDealer()这类高频复用的多步业务操作,推荐用原子操作拆分+高层业务工作流封装的设计模式,结合你现有的页面对象(PO)架构适配即可,核心设计思路如下:

1. 先拆分原子操作,消除重复代码

你当前changeDealer()的两个分支里80%的步骤完全重复,先把通用步骤拆成仅负责单一动作的原子方法,按所属页面放在对应PO文件中:

  • 头部操作相关方法放在DealerHeader类中:expandHeader()、openDealerModal()
  • 经销商定位页相关方法放在Locators类中:navigateToLocatorPage()、searchDealerByZip(zipCode?: string)、pickRandomDealer()、confirmDealerChange(isDealerSet: boolean)

示例代码:

// locators.po.ts 补充原子方法
async searchDealerByZip(zipCode = '10001') {
  await waitToBeDisplayed(this.zipInput);
  await this.zipInput.sendKeys(zipCode, Key.ENTER);
  await waitToBeDisplayed(this.dealerList);
}

async pickRandomDealer() {
  const dealerList = await this.dealerListItems;
  const randomIndex = Math.floor(Math.random() * dealerList.length);
  await click(dealerList[randomIndex].$('.detail-btn'));
  await waitToBeDisplayed(this.confirmDealerBtn);
}

2. 封装高层业务工作流方法

把原子方法按业务逻辑串成changeDealer()方法,放在和业务最相关的PO类(这里是Locators类),支持可选入参适配不同测试场景,同时加前置状态校验减少冗余操作:

// locators.po.ts 封装后的changeDealer
async changeDealer(targetZip?: string, targetDealerId?: string) {
  // 前置校验:如果已经是目标经销商,直接返回,跳过全流程
  const currentDealer = await getCurrentDealerId();
  if (targetDealerId && currentDealer === targetDealerId) return;

  // 通用前置步骤
  const dh = new DealerHeader();
  await dh.expandHeader();
  await dh.openDealerModal();
  await this.navigateToLocatorPage();
  await browser.executeScript('window.scrollTo(0, document.body.scrollHeight)');

  // 支持自定义邮编/默认随机邮编
  await this.searchDealerByZip(targetZip ?? getRandomTestZip());
  // 支持指定经销商/默认随机选
  targetDealerId ? await this.pickDealerById(targetDealerId) : await this.pickRandomDealer();

  // 分支逻辑仅保留差异部分
  const isDealerPreSet = !!currentDealer;
  await this.confirmDealerChange(isDealerPreSet);
  // 可选加后置校验:确保切换成功
  await waitForDealerIdChange(currentDealer);
}

3. 测试用例层仅调用高层方法

测试用例文件中不要散落操作步骤,只调用封装好的业务方法,仅保留断言逻辑:

// header.test.ts 简化后的用例
it('Dealer Header Display', async() => {
  const dh: DealerHeader = new DealerHeader();
  const loc: Locators = new Locators();
  const dealerHeaderPrimaryDealerName = await dh.dealerHeaderPrimaryDealerName();

  if (!await dealerHeaderPrimaryDealerName.isPresent()) {
    await loc.changeDealer(); // 直接调用封装好的方法即可
  }

  await waitToBeDisplayed(dealerHeaderPrimaryDealerName);
  await expect(dealerHeaderPrimaryDealerName).toBeDisplayed();
  // 其余断言逻辑保持不变
});

方案优势

  • 维护成本低:业务流程改动时,仅需要修改对应原子方法或工作流的组装逻辑,不需要逐个修改所有用到切换经销商操作的测试用例
  • 复用性强:支持自定义入参适配不同测试场景,比如需要测试指定区域经销商的用例,直接传入对应邮编即可
  • 稳定性高:所有等待、异常处理逻辑都封装在方法内部,避免不同用例写操作步骤时漏加等待导致的偶现失败
  • 可读性好:测试用例逻辑清晰,看方法名就能知道做了什么操作,不需要读大段步骤代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 07:51:03