为了账号安全,请及时绑定邮箱和手机立即绑定

从多个 cypress 承诺中收集结果

从多个 cypress 承诺中收集结果

阿波罗的战车 2021-11-12 17:34:58
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    });});以上方法正确吗?每个页面都应该有单独的测试吗?如果我有 50 多页要检查怎么办?在这种情况下,Cypress.io 中的最佳方法是什么?
查看完整描述

2 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

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


您可以使用我在类似答案中建议的助手:


// 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);

});


查看完整回答
反对 回复 2021-11-12
?
莫回无

TA贡献1865条经验 获得超7个赞

可以从 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 来检查外部站点的状态吗?

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


查看完整回答
反对 回复 2021-11-12
  • 2 回答
  • 0 关注
  • 109 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信