最近、同僚と私は、Protractor と Chai as Promised を使用して Cucumber のステップ定義を実装する「正しい」方法について意見の相違がありました。私たちの主張は、Cucumber のコンテキストでのプロミス解決で正確に何が起こっているのかを相互に理解していないことに起因しています。
AngularJS アプリケーションに対してテストしているため、promise と非同期動作の解決は必要悪です。私たちが経験した最大の問題は、同期テスト動作を強制し、Cucumber にステップ定義間の promise を待機させることです。場合によっては、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;
});
});
});
});
後者は私には本当に間違っているように感じますが、前者も正しいかどうかはよくわかりません。私が最終的に理解する方法は、先に進む前に約束が解決するのを待つという点で、then() と同様に機能するということです。前の例では、各 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();
});
});
});
したがって、私がほのめかしていると思う質問は次のとおりです。
- 上記のいずれかはちょっと正しいですか?
- 最終的に()は実際に何をしますか?then() のような同期動作を強制しますか?
- and.notify(next) は実際に何をしますか? then() 内で next() を呼び出すのとは違いますか?
- これについてより明確にする、まだ見つかっていないベスト プラクティス ガイドはありますか?
よろしくお願いします。