最近,我和一位同事对使用 Protractor 和 Chai 作为 Promised 实现 Cucumber 步骤定义的“正确”方式存在一些分歧。我们的争论来自于相互缺乏对 Cucumber 上下文中承诺解决的确切内容的理解。
我们正在针对 AngularJS 应用程序进行测试,因此解决 Promise 和异步行为是必要的。我们遇到的最大问题是强制同步测试行为并让 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() 的工作方式类似,因为它在继续之前等待 promise 解决。我希望前一个示例按顺序等待每个 expect() 调用,然后在最终的 expect() 中通过 notify() 调用 next() 以向 cucumber 发出信号以继续下一步。
更令人困惑的是,我观察到其他同事这样写他们的期望:
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();
});
});
});
所以我认为我所暗示的问题是:
- 以上任何一项都对吗?
- finally() 到底做了什么?它会强制像 then() 这样的同步行为吗?
- and.notify(next) 到底是做什么的?它与在 then() 中调用 next() 有什么不同?
- 是否有我们尚未找到的最佳实践指南可以更清楚地说明其中的任何内容?
提前谢谢了。