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

Cypress deep equal断言行为异常及数组操作问题求助

问题原因分析与解决方案

核心问题:Cypress异步执行模型与同步代码的冲突

你的代码矛盾点根源在于Cypress命令是异步排队执行的,但变量声明、expect断言这类同步代码会先于所有Cypress命令运行,导致断言时数组还未被填充数据,而你看到的cy.task('log')输出是数组填充后才执行的,所以出现了“log有数据但断言没报错”的错位现象。

1. 为什么断言没报错?

代码实际执行顺序如下:

  • 同步代码优先执行:声明空数组unsortedItemPrices和sortedItemPrices,对空数组执行sort().reverse()(空数组操作后仍为空)。
  • 所有cy.get()、cy.task()命令被加入Cypress异步命令队列,此时数组还未被each()填充数据。
  • 最后一行sortedItemPrices.to.deep.equal(unsortedItemPrices.sort().reverse())是同步断言,此时两个数组都是空数组[],自然断言通过。
  • 之后Cypress才开始执行命令队列中的each(),填充数组,再执行cy.task('log')输出填充后的数组——你看到的log数据是断言执行后才生成的。

2. 修改log语句后为什么出现奇怪错误?

你修改的log语句:

cy.task('log', unsortedItemPrices.sort((a, b) => parseFloat(a) - parseFloat(b)).reverse().push(1));

这里有两个关键问题:

  • push()方法返回的是数组新长度,而非修改后的数组本身,所以你传给cy.task('log')的是数字(比如空数组push(1)后返回1),不是数组。
  • sort()和reverse()都是原地修改数组的方法,执行这行代码时(同步计算log参数),会把1推进unsortedItemPrices数组。此时断言已经执行过,但同步修改数组后,后续可能触发的断言(或Cypress的异步校验)会检测到sortedItemPrices是空数组,而unsortedItemPrices.sort().reverse()变成了[1],因此抛出expected [] to deeply equal [1]的错误。

正确写法(修复异步问题)

要确保断言在数组填充完成后执行,必须把断言放在Cypress的异步命令链里,用.then()等待前置命令完成:

it('Validate Price High - Low sorting', () => {
  // 先获取未排序的价格数据
  cy.get(inventoryPage.itemsPrice).then(($items) => {
    // 将元素转换为价格数组
    const unsortedItemPrices = $items.map((index, item) => {
      return Cypress.$(item).text().replace('$', '');
    }).get(); // 把jQuery对象转为原生数组

    // 生成预期的降序排序结果(用数组副本避免修改原数组)
    const expectedSortedPrices = [...unsortedItemPrices].sort((a, b) => {
      return parseFloat(b) - parseFloat(a); // 直接降序,无需reverse
    });

    // 执行排序操作
    cy.get(inventoryPage.sortDropdown)
      .should('have.length', 4)
      .select('hilo');

    // 获取排序后的价格并断言
    cy.get(inventoryPage.itemsPrice).then(($sortedItems) => {
      const sortedItemPrices = $sortedItems.map((index, item) => {
        return Cypress.$(item).text().replace('$', '');
      }).get();

      cy.task('log', unsortedItemPrices);
      cy.task('log', sortedItemPrices);
      expect(sortedItemPrices).to.deep.equal(expectedSortedPrices);
    });
  });
});

关键修复点:

  • 用.then()包裹数据获取与断言,确保在cy.get()完成后再处理数组。
  • 用[...unsortedItemPrices]创建数组副本,避免sort()原地修改原数组影响后续逻辑。
  • 直接使用降序排序逻辑parseFloat(b) - parseFloat(a),比升序后reverse()更直观。
  • 用jQuery的.map().get()转换元素数组,比.each()+push()更简洁可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:06:28