Соберите результаты нескольких обещаний кипариса - PullRequest
2 голосов
/ 08 октября 2019

Возможно ли в 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 ]

2 голосов
/ 10 октября 2019
  • Может ли собрать несколько результатов из 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 - это среда тестирования для написания тестов ваших собственных сервисов / систем.

0 голосов
/ 09 октября 2019

РЕДАКТИРОВАТЬ: часто кто-то предлагает использовать Promise.all, что не является правильным решением. Цепные объекты Cypress не являются Promises / A + -совместимыми, они просто кажутся обещаниями, потому что они реализуют интерфейс .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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...