量angular器页面对象inheritance

鉴于我build立我的angularjs量angular器e2etesting套件利用页面对象模式。

而且我把页面目标代码分开放在不同的文件中。

  1. 什么是一个好的方法来启用页面对象的inheritance? JavaScript的经典inheritance? 基于Object.create()的inheritance? 其他?

  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; }; 

usage.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' 

这里是链接到一个教程,我build立了一些关于创build好的量angular器testing套件的培训。

这是所有生活,与演示网站,您可以访问,探索等

https://github.com/Droogans/ProtractorPageObjects

这将安装,大纲,组织技巧,等等。

如果您有任何问题,请随时留下问题。

我的意见和我们如何构build我们的testing

  • 一个普通的页面模型包含了一些我们希望大多数页面使用的方法,比如go()或者我们有一些与一些常用的自定义元素进行交互的方法。

  • 许多页面特定的模型,从这个一般页面inheritance。 这些模型中的大多数方法都与获取页面上的各种元素或与该页面的UI进行交互有关。 这些模型没有断言方法。

  • 用于与某些更复杂的小部件进行交互的UI模型。 与页面模型类似,但是这些不是绑定到页面上的。 他们绑定到一个用户界面/部件。 这些模型没有断言方法。

  • 对于常见和可重用的断言,我们有断言模型,利用各​​种页面模型和UI模型的交互方法。 它们按页面或UI进行组织。 对于不常见的,不可重用的断言,我们只是把它们放入规范本身。

  • 虽然我们有特定的UI /小部件的规格,但是规范通常是按页面组织的。