柏树深平等工作怪异

Cypress deep equal works weirdly

提问人:Constantin Suiu 提问时间:11/18/2023 最后编辑:TesterDickConstantin Suiu 更新时间:11/18/2023 访问量:35

问:

我今天开始学习柏树,并尝试编写下面的测试

it('Validate Price High - Low sorting', () => {
    let unsortedItemPrices = [];
    const sortedItemPrices = [];

    unsortedItemPrices.sort((a, b) => parseFloat(a) - parseFloat(b)).reverse();
    cy.get(inventoryPage.itemsPrice).each((item) => {
      unsortedItemPrices.push(item.text().replace('$', ''));
    });

    cy.get(inventoryPage.sortDropdown).get('option').should('have.length', 4);
    cy.get(inventoryPage.sortDropdown).select('hilo');
    cy.get(inventoryPage.itemsPrice).each(($item) => {
      sortedItemPrices.push($item.text().replace('$', ''));
    });
    

    cy.task('log', unsortedItemPrices.sort((a, b) => parseFloat(a) - parseFloat(b)).reverse());
    cy.task('log', sortedItemPrices);
    expect(sortedItemPrices).to.deep.equal(unsortedItemPrices.sort().reverse());
  });

2 个日志语句返回这些行,这很奇怪,因为当我单独尝试时,我看到数据排序正确。但是,上面的 expect().to.deep.equal() 语句不会返回错误。

[ '29.99', '9.99', '15.99', '49.99', '7.99', '15.99' ]
[ '49.99', '29.99', '15.99', '15.99', '9.99', '7.99' ]

更奇怪的是,如果我像这样编辑日志

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

然后我确实收到一个错误,但它说

AssertionError: expected [] to deeply equal [ 1 ]
      + expected - actual

      -[]
      +[ 1 ]

有人可以解释一下这是怎么回事吗?这对我来说完全令人困惑:|

柏树 桧木-每个

评论

0赞 adsy 11/18/2023
加剧您困惑的一件事是,既要就地修改数组,又要返回对同一数组的引用,而不是返回一个经过修改的新数组。这意味着当您使用这些调用进行日志记录时,数组实际上会被反转一段时间。首先将它们全部更改为 toSortedtoReversed。这至少可以帮助您更轻松地进行调试。sortreverse
0赞 adsy 11/18/2023
除此之外,最终调用在没有回调的情况下调用,因此它尝试对对象引用本身而不是对象内部的属性进行排序。expect(sortedItemPrices).to.deep.equal(unsortedItemPrices.sort().reverse());sort

答:

4赞 TesterDick 11/18/2023 #1

在测试中,您可以使用一些命令将值从页面上获取,但是在这些命令完成之前继续运行。cy.get()expect().to.deep.eq()

这是因为命令是异步的,在使用从页面中提取的值之前需要等待。cy.get()

所以你的期望是比较空数组,相当于

expect([]).to.deep.equal([])

这在您之后解释此消息push(1)

AssertionError:预期深度相等[][ 1 ]


怎么修

只需将比较包装在 a 中,即可确保在提取值后执行。cy.then()

还要注意 和 是影响原始数组的就地方法,因此您不想调用 then 两次(您已经正确地避免了这样做,但很容易忽略该问题)。.sort().reverse()

const sortFn = (a, b) => parseFloat(a) - parseFloat(b)

let unsortedItemPrices = [];
const sortedItemPrices = [];

cy.get(inventoryPage.itemsPrice).each($item => {
  unsortedItemPrices.push($item.text().replace('$', ''))
})

cy.get(inventoryPage.sortDropdown).get('option').should('have.length', 4);
cy.get(inventoryPage.sortDropdown).select('hilo');
cy.get(inventoryPage.itemsPrice).each($item => {
  sortedItemPrices.push($item.text().replace('$', ''))
})

cy.then(() => {
  // sort() and reverse() work in-place, so we can apply first
  unsortedItemPrices.sort(sortFn).reverse()
  // then compare
  expect(sortedItemPrices).to.deep.equal(unsortedItemPrices)
})

更清晰的测试

IMO 构建测试的一种更简洁的方法是将元素映射到值,而不是使用.each()


const sortFn = (a, b) => parseFloat(a) - parseFloat(b)
const mapFn = ($items) => [...$items].map(item => item.innerText.replace('$', '')

cy.get(inventoryPage.itemsPrice)
  .then(mapFn)
  .then(unsortedItemPrices => {

    // create a new array for expected values
    const expectedSortedItemPrices = [...unsortedItemPrices.sort(sortFn).reverse()]

    cy.get(inventoryPage.sortDropdown).get('option')
      .should('have.length', 4);
    cy.get(inventoryPage.sortDropdown).select('hilo');
    cy.get(inventoryPage.itemsPrice)
      .then(mapFn)
      .should(sortedItemPrices => {

        // using should() instead of then() gives some retry
        // in case the page sorting happens asynchronously
        // (not likely but you don't know the internal implementation)

        expect(sortedItemPrices).to.deep.equal(expectedSortedItemPrices)
      })
  })

评论

0赞 Constantin Suiu 11/18/2023
谢谢TesterDick..我不知道柏树异步运行东西:)