19

ページオブジェクトパターンを利用してangularjs分度器e2eテストスイートを構築しているとします。

そして、私はページオブジェクトコードを別のファイルにできるだけ分けています。

  1. ページ オブジェクトの継承を有効にするには、どのような方法がよいでしょうか? JavaScriptの古典的な継承? Object.create() ベースの継承? 他の?

  2. ページオブジェクト内で期待を維持する必要がありますか? または、それらをアサーション ライブラリに移動して、 Martin Fowler オプションを支持しますか? この場合、この javascript-nodejs テクノロジ スタックではどのように見えるでしょうか?

ここにライブ jsfiddle プレイグラウンドを用意したので、改善点を試すことができます。

または、回答内にコードを貼り付けるだけです。明確にするために、以下に jsfiddle コンテンツを貼り付けます。

loginPage.js

"use strict";

// A Page Object is a Singleton, so no need to constructors or classic js inheritance,
// please tell me if I'm wrong or what's the utility of creating a (new LoginPage())
// every time a spec need to use this login page.
var loginPage = {
    // Page Object Elements
    userElm: $('.user.loginPage'),

    // Page Object Assertions
    // Martin Fowler [doesn't favor](http://martinfowler.com/bliki/PageObject.html)
    // assertions in page objects, I'm open to suggestions on how to move 
    // the assertions away from the Page Object and see how an assertion library 
    // could like like in protractor.
    assertInputsDisplayed: function() {
        return ('Assertion: this.userElm: '+this.userElm);
    },

    // Page Object Actions
    get: function () {
        return ('navigating to LoginPage with userElm: '+this.userElm);
    }
};

module.exports.loginPage = loginPage;

loginDialog.js

"use strict";

var loginPage = require('./loginPage.js').loginPage;
var helpers = require('./helpers.js');

// Inherit properties from another Page Object
var loginDialog = helpers.extend({}, Object.create(loginPage), {
    // Page Object Elements
    userElm: $('.user.loginDialog'),

    // Page Object Actions
    get: function () {
        return ('navigating to LoginDialog with userElm: '+this.userElm);
    },

    logout: function () {
        return ('logging out of Dialog. user was: '+this.userElm);
    }
});

module.exports.loginDialog = loginDialog;

helpers.js

"use strict";

// some helper to avoid adding an external dependency for now
var extend = function(target) {
    var sources = [].slice.call(arguments, 1);
    sources.forEach(function (source) {
        for (var prop in source) {
            target[prop] = source[prop];
        }
    });
    return target;
};

使用法.js

"use strict";

// Mock $() for easy unit testing this on nodejs REPL
global.$ = function(args) { return ('$BUILT '+args); };

var loginPage   = require('./loginPage.js').loginPage;
var loginDialog = require('./loginDialog.js').loginDialog;

console.log(loginPage.userElm);    //=> '$BUILT .user.loginPage'
console.log(loginDialog.userElm);  //=> '$BUILT .user.loginDialog'
console.log(loginPage.get());      //=> 'navigating to LoginPage with userElm: $BUILT .user.loginPage'
console.log(loginDialog.get());    //=> 'navigating to LoginPage with userElm: $BUILT .user.loginDialog'
console.log(loginPage.assertInputsDisplayed());   //=> 'LoginPage assertion: this.userElm: $BUILT .user.loginPage'
console.log(loginDialog.assertInputsDisplayed()); //=> 'LoginPage assertion: this.userElm: $BUILT .user.loginDialog'

//loginPage.logout();   //=> TypeError: Object #<Object> has no method 'logout'
console.log(loginDialog.logout()); //=> 'logging out of Dialog. user was: $BUILT .user.loginDialog'
4

2 に答える 2

5

私の意見とテストの構成方法...

  • ほとんどのページで同様に使用されると予想されるいくつかのメソッドを保持する 1 つの一般的なページ モデル、go()またはいくつかの一般的なカスタム要素と対話するためのメソッドがあります。

  • この一般的なページから継承する多くのページ固有のモデル。これらのモデルのほとんどのメソッドは、ページ上のさまざまな要素の取得またはそのページの UI との対話に関連しています。これらのモデルにはアサーション メソッドはありません。

  • 特定のより複雑なウィジェットと対話するための UI モデル。ページ モデルに似ていますが、これらはページに関連付けられていません。UI/ウィジェットに関連付けられています。これらのモデルにはアサーション メソッドはありません。

  • 一般的で再利用可能なアサーションについては、さまざまなページ モデルと UI モデルの相互作用メソッドを利用するアサーション モデルがあります。これらは、ページまたは UI ごとに編成されています。一般的ではなく、再利用できないアサーションについては、仕様自体に含めます。

  • 特定の UI/ウィジェットの仕様はありますが、通常、仕様はページごとにまとめられています。

于 2014-01-30T20:34:22.430 に答える