量角器页面对象继承

Leo*_*cci 19 javascript node.js angularjs angularjs-e2e protractor

鉴于我正在构建我的angularjs量角器e2e测试套件,利用页面对象模式.

我尽可能合理地将页面对象代码分隔在不同的文件中.

  1. 什么是启用页面对象继承的好方法?javascript经典继承?基于Object.create()的继承?其他?

  2. 我应该在页面对象中保持期望吗?或者通过将他们转移到断言库来支持Martin Fowler optinion?在这种情况下,这个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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

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;
};
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

Dro*_*ans 8

这里是我为培训一些同事创建优秀的Protractor测试套件而设置的教程的链接.

一切都在现场,有一个可以访问,探索等的演示网站.

https://github.com/Droogans/ProtractorPageObjects

这将为您提供安装,概述,组织技术等.

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

  • 哇,这是你写的教程!谢谢!!但是我不喜欢将astrolabe添加到堆栈中的想法,我觉得这可以在没有它的情况下完成 (2认同)

wli*_*gke 5

我的意见以及我们如何构建测试......

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

  • 从此常规页面继承的许多特定于页面的模型.这些模型上的大多数方法都与在页面上获取各种元素或与该页面的ui进行交互有关.这些模型没有断言方法.

  • 用于与某些更复杂的小部件交互的UI模型.与页面模型类似,但这些不与页面相关联.它们与UI /小部件相关联.这些模型没有断言方法.

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

  • 规范通常按页面组织,但我们确实有某些UI /小部件的规范.

  • 嘿@wlingke感谢您分享您的标准,您能提供一些代码吗?那将是真棒 ;) (2认同)
  • 这些例子是一个非常基本的角度站点,但无论如何,谢谢 (2认同)