В последнее время у нас с коллегой возникли некоторые разногласия по поводу «правильного» способа реализации определений шагов Cucumber с использованием Protractor и Chai as Promised. Наше утверждение проистекает из взаимного непонимания того, что именно происходит с разрешением обещаний в контексте Cucumber.
Мы тестируем приложение AngularJS, поэтому выполнение обещаний и асинхронного поведения - неизбежное зло. Самая большая проблема, с которой мы столкнулись, - это заставить Cucumber ждать выполнения обещаний между определениями шагов. В некоторых случаях мы наблюдали такие ситуации, что Cucumber, кажется, просматривает определения шагов прямо до того, как Webdriver даже выполнит их. Наши решения этой проблемы различаются ...
Рассмотрим гипотетический сценарий:
Scenario: When a user logs in, they should see search form
Given a user exists in the system
When the user logs into the application
Then the search form should be displayed
Большая часть путаницы возникает на шаге Then. В этом примере определение должно утверждать, что все поля для формы поиска существуют на странице, что означает несколько проверок isPresent ().
Из документации и примеров, которые мне удалось найти, я почувствовал, что утверждение должно выглядеть примерно так:
this.Then(/the search form should be displayed/, function(next) {
expect(element(by.model('searchTerms')).isPresent()).to.eventually.be.true;
expect(element(by.model('optionsBox')).isPresent()).to.eventually.be.true;
expect(element(by.button('Run Search')).isPresent()).to.eventually.be.true.and.notify(next);
});
Однако мой коллега утверждает, что для выполнения обещания вам нужно связать свои ожидания с then () следующим образом:
this.Then(/the search form should be displayed/, function(next) {
element(by.model('searchTerms')).isPresent().then(function(result) {
expect(result).to.be.true;
}).then(function() {
element(by.model('optionsBox')).isPresent().then(function(result) {
expect(result).to.be.true;
}).then(function() {
element(by.button('Run Search')).isPresent().then(function(result) {
expect(result).to.be.true;
next;
});
});
});
});
Последнее мне кажется неправильным, но я тоже не знаю, правильно ли первое. Насколько я понимаю, функция finally () заключается в том, что она работает аналогично then () в том смысле, что она ожидает разрешения обещания, прежде чем двигаться дальше. Я ожидал, что предыдущий пример будет ждать каждого вызова expect () по порядку, а затем вызывать next () через notify () в последнем expect (), чтобы сигнализировать огурцу о переходе к следующему шагу.
Чтобы добавить еще больше путаницы, я наблюдал, как другие коллеги пишут свои ожидания следующим образом:
expect(some_element).to.eventually.be.true.then(function() {
expect(some_other_element).to.eventually.be.true.then(function() {
expect(third_element).to.eventually.be.true.then(function() {
next();
});
});
});
Я имею в виду следующие вопросы:
- Правильно ли что-либо из вышеперечисленного вроде?
- Что в конечном итоге () действительно делает? Принуждает ли он к синхронному поведению, как then ()?
- Что на самом деле делает and.notify (next)? Отличается ли он от вызова next () внутри then ()?
- Есть ли руководство по передовой практике, которое мы еще не нашли, чтобы прояснить что-либо из этого?
Спасибо заранее.