Angular/Protractor 测试开发:使用Page Object模式组织测试代码
protractor E2E test framework for Angular apps 项目地址: https://gitcode.com/gh_mirrors/pr/protractor
什么是Page Object模式
Page Object(页面对象)是一种在端到端测试中广泛使用的设计模式,它将页面元素定位和操作逻辑封装成可重用的对象。在Angular/Protractor测试框架中采用这种模式,可以带来以下优势:
- 代码复用:多个测试用例可以共享同一个Page Object
- 维护便捷:当页面结构变化时,只需修改Page Object而不必改动所有测试用例
- 可读性强:测试用例更专注于业务逻辑,而不是元素定位细节
- 层次清晰:实现了测试逻辑与页面操作的分离
不使用Page Object的问题
我们先看一个典型的Protractor测试示例:
describe('angularjs homepage', function() {
it('should greet the named user', function() {
browser.get('http://www.angularjs.org');
element(by.model('yourName')).sendKeys('Julie');
var greeting = element(by.binding('yourName'));
expect(greeting.getText()).toEqual('Hello Julie!');
});
});
这种写法存在几个明显问题:
- 元素定位逻辑散落在测试用例中
- 相同的元素定位可能在多个测试中重复出现
- 页面结构变更时需要修改多处测试代码
实现Page Object模式
基础实现方式
我们可以将上述测试重构为使用Page Object的形式:
// AngularHomepage.js
var AngularHomepage = function() {
// 元素定位
var nameInput = element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
// 页面操作方法
this.get = function() {
browser.get('http://www.angularjs.org');
};
this.setName = function(name) {
nameInput.sendKeys(name);
};
this.getGreetingText = function() {
return greeting.getText();
};
};
module.exports = new AngularHomepage();
支持async/await的改进版本
在现代JavaScript中,我们可以使用async/await语法使代码更清晰:
var AngularHomepage = function() {
var nameInput = element(by.model('yourName'));
var greeting = element(by.binding('yourName'));
this.get = async function() {
await browser.get('http://www.angularjs.org');
};
this.setName = async function(name) {
await nameInput.sendKeys(name);
};
this.getGreetingText = function() {
return greeting.getText();
};
// 返回元素本身的方法不需要async
this.getGreeting = function() {
return greeting;
};
};
module.exports = new AngularHomepage();
在测试中使用Page Object
重构后的测试用例变得更加简洁:
var angularHomepage = require('./AngularHomepage');
describe('angularjs homepage', function() {
it('should greet the named user', function() {
angularHomepage.get();
angularHomepage.setName('Julie');
expect(angularHomepage.getGreetingText()).toEqual('Hello Julie!');
});
});
使用async/await的版本:
var angularHomepage = require('./AngularHomepage');
describe('angularjs homepage', function() {
it('should greet the named user', async function() {
await angularHomepage.get();
await angularHomepage.setName('Julie');
expect(await angularHomepage.getGreetingText()).toEqual('Hello Julie!');
});
});
测试套件配置
在实际项目中,我们通常需要组织多个测试套件。Protractor配置文件支持suites选项:
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: {
'browserName': 'chrome'
},
suites: {
homepage: 'tests/e2e/homepage/**/*Spec.js',
search: [
'tests/e2e/contact_search/**/*Spec.js',
'tests/e2e/venue_search/**/*Spec.js'
]
},
jasmineNodeOpts: {
showColors: true,
}
};
运行特定测试套件的命令:
# 运行单个套件
protractor protractor.conf.js --suite homepage
# 运行多个套件
protractor protractor.conf.js --suite homepage,search
最佳实践建议
- 单一职责原则:每个Page Object应该只负责一个页面的逻辑
- 方法命名规范:使用清晰的动词命名操作方法,如
clickSubmitButton()
、enterUsername()
- 避免直接暴露元素:尽量通过方法封装元素操作,而不是直接返回元素
- 合理组织目录结构:将Page Object与测试文件分开存放
- 添加必要的注释:特别是对复杂元素定位逻辑进行说明
通过采用Page Object模式,你的Protractor测试代码将变得更加模块化、可维护性更强,能够更好地适应大型项目的测试需求。
protractor E2E test framework for Angular apps 项目地址: https://gitcode.com/gh_mirrors/pr/protractor
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考