收集来自多个柏树的结果

时间:2019-10-08 11:41:52

标签: javascript cypress

在Cypress.io中是否可以在.then结构内部收集多个断言的结果,以便可以在.then外部使用结果?

基于以下示例-如果我有一些要进行抽烟测试的页面(例如,检查代码是否不同于404),如何收集有关它们的信息?如何在一次烟雾测试中一起验证结果?

请看一下显示问题的简单代码:

describe('Smoke tests for some pages', () => {
    it('should be able to view page that was loaded correctly', () => {
      // Arrange:
      const pageAddressList = [
        'https://en.wikipediaaa.org',
        'https://en.wikipedia.org'];
      const errors = Array();

      // Act:
      pageAddressList.forEach((pageAddress) => {
        cy.request(pageAddress).then((response) => {
            // check response and add some error to errors if needed
        })

      });
      // Assert:
      // check if errors is empty
    });
});
  1. 以上方法正确吗?
  2. 每个页面都应该有单独的测试吗?
  3. 如果我要检查50多个页面怎么办?
  4. 在这种情况下,Cypress.io的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

  • 可以从cy.requests收集多个结果吗?

您可以收集全部内容,并在只有所有响应准备就绪时使用 Cypress.Promise.all

采取行动。
  it.only('Gathering results', () => {
    const urls = ['https://google.com',
      'https://en.wikipedia.org']
    const requests = urls.map(url => {
      console.log(`a request sent to  ${url}`)
      return new Cypress.Promise(resolve => {
        cy.request(url).then(resopnse => {
          console.log(`'Response from ${url}`)
          resolve(resopnse)
        })
      })

    })
    Cypress.Promise.all(requests).then(responses => {
      // process responses
      console.log("All responses ready")
      console.log(responses.map(response => response.redirects.toString()))
    })
  })
  • 我们应该使用赛普拉斯来检查外部站点的状态吗?

我没有您正在做的完整情况。显然,您似乎正在使用Cypress作为监视工具,该工具会定期检查某些外部站点的可用性并发出通知。如果是这样,我会说不,赛普拉斯是一个测试框架,用于编写您自己的服务/系统的测试。

答案 1 :(得分:0)

编辑:通常有人建议使用Promise.all,这不是正确的解决方案。赛普拉斯链接器对象与Promises/A+不兼容,它们看起来像是应许,因为它们实现了.then接口。这就是Promise.all能够使用一系列链接器对象的原因,仅此而已。传递给Promise.all().then回调的分辨率值不会达到您的期望(请参见https://github.com/cypress-io/cypress/issues/915)。

您可以使用我建议的in a similar answer助手:

// put this in cypress/support/index.js

const chainStart = Symbol();
cy.all = function ( ...commands ) {
    const _           = Cypress._;
    const chain       = cy.wrap(null, { log: false });
    const stopCommand = _.find( cy.queue.commands, {
        attributes: { chainerId: chain.chainerId }
    });
    const startCommand = _.find( cy.queue.commands, {
        attributes: { chainerId: commands[0].chainerId }
    });
    const p = chain.then(() => {
        return _( commands )
            .map( cmd => {
                return cmd[chainStart]
                    ? cmd[chainStart].attributes
                    : _.find( cy.queue.commands, {
                        attributes: { chainerId: cmd.chainerId }
                    }).attributes;
            })
            .concat(stopCommand.attributes)
            .slice(1)
            .flatMap( cmd => {
                return cmd.prev.get('subject');
            })
            .value();
    });
    p[chainStart] = startCommand;
    return p;
}

用法:

it('test', () => {
    const urls = [
        'https://en.wikipediaaa.org',
        'https://en.wikipedia.org'
    ];

    cy.all(
        ...urls.map(url => cy.request(url))
    ).then(responses => {
        responses.forEach( resp => {
            expect(resp.status).to.eq(200);
        });
    });
});

话虽如此,您也可以这样做:

const urls = [
    'https://en.wikipediaaa.org',
    'https://en.wikipedia.org'
];

let passes = 0;

urls.forEach( url => {
    cy.request(url).then( resp => {
        if ( resp.status === 200 ) passes++;
    });
});

cy.then(() => {
    expect(passes).to.eq(urls.length);
});

如果您要访问结果而不必保留全局变量并从cy.all回调中访问它们,则顶部的cy.then()助手非常有用---但就像我在上一节中所示例如,仅使用香草柏树就可以解决所有问题。

或者,如果您根本不需要响应,则只需执行以下操作即可:

const urls = [
    'https://en.wikipediaaa.org',
    'https://en.wikipedia.org'
];
urls.forEach( url => {
    cy.request(url).its('status').should('eq', 200);
});