在Nightwatch.js的UI自动化测试开发中,重复编写相同的元素选择器是很多新手容易犯的问题。相同页面的元素定位逻辑分散在多个测试用例中,一旦页面元素结构发生变化,就需要逐个修改所有相关的选择器代码,工作量较大且容易遗漏。

使用变量统一管理重复选择器
最直接的避免重复元素选择器的方式,是把常用的选择器定义为变量,在需要使用的测试用例中直接引用变量即可。这种方式适合小型项目或者单个测试文件中重复使用的选择器场景。
变量定义与使用示例
首先可以在测试文件的顶部定义选择器变量,比如针对登录页面的常用元素:
// 定义登录页面元素选择器变量
const loginSelectors = {
usernameInput: '#username',
passwordInput: '#password',
loginBtn: '#login-button',
errorTip: '.error-message'
};
// 测试用例中使用变量
module.exports = {
'测试登录成功场景': function(browser) {
browser
.url('https://ipipp.com/login')
.waitForElementVisible(loginSelectors.usernameInput, 5000)
.setValue(loginSelectors.usernameInput, 'testuser')
.setValue(loginSelectors.passwordInput, 'testpass123')
.click(loginSelectors.loginBtn)
.assert.urlContains('/dashboard')
.end();
},
'测试登录失败场景': function(browser) {
browser
.url('https://ipipp.com/login')
.setValue(loginSelectors.usernameInput, 'wronguser')
.setValue(loginSelectors.passwordInput, 'wrongpass')
.click(loginSelectors.loginBtn)
.assert.visible(loginSelectors.errorTip)
.end();
}
};
变量方式的优缺点
- 优点:实现简单,不需要额外配置,适合单个文件内的选择器复用
- 缺点:如果多个测试文件都需要使用相同的选择器,还是需要在每个文件中重复定义变量,跨文件复用性不足
使用页面对象模式实现复用
页面对象模式是Nightwatch.js官方推荐的测试代码组织方式,核心思路是把每个页面的元素选择器和页面相关的操作方法封装到独立的页面对象文件中,测试用例只需要调用页面对象的方法即可,完全不需要直接编写元素选择器。
页面对象文件定义
首先在项目的page_objects目录下创建登录页面的对象文件loginPage.js:
// loginPage.js 页面对象文件
module.exports = {
// 页面元素的url
url: function() {
return 'https://ipipp.com/login';
},
// 页面元素选择器集合
elements: {
usernameInput: '#username',
passwordInput: '#password',
loginBtn: '#login-button',
errorTip: '.error-message'
},
// 页面相关的操作方法
commands: [{
// 输入登录信息的方法
inputLoginInfo: function(username, password) {
return this
.waitForElementVisible('@usernameInput', 5000)
.setValue('@usernameInput', username)
.setValue('@passwordInput', password);
},
// 点击登录按钮的方法
submitLogin: function() {
return this
.click('@loginBtn');
},
// 验证登录错误提示的方法
verifyErrorTip: function() {
return this
.assert.visible('@errorTip');
}
}]
};
注意这里使用@符号来引用当前页面对象中定义的elements里的选择器,不需要重复编写完整的选择器字符串。
测试用例中使用页面对象
在测试用例中只需要引入对应的页面对象,调用封装好的方法即可,完全不需要接触元素选择器:
// 引入登录页面对象
const loginPage = require('../page_objects/loginPage');
module.exports = {
'页面对象模式测试登录成功': function(browser) {
const login = browser.page.loginPage();
login
.navigate() // 跳转到登录页面,使用页面对象中定义的url
.inputLoginInfo('testuser', 'testpass123')
.submitLogin()
.assert.urlContains('/dashboard');
browser.end();
},
'页面对象模式测试登录失败': function(browser) {
const login = browser.page.loginPage();
login
.navigate()
.inputLoginInfo('wronguser', 'wrongpass')
.submitLogin()
.verifyErrorTip();
browser.end();
}
};
页面对象模式的优势
- 所有页面的选择器集中在独立的文件中管理,修改时只需要改一个地方
- 测试用例代码更简洁,只关注测试逻辑,不关注元素定位细节
- 支持跨测试文件复用,多个测试用例使用同一个页面对象即可
- 符合面向对象的设计思想,代码结构更清晰,可维护性更强
两种方案的适用场景对比
可以通过下面的表格判断两种方案的选择:
| 方案类型 | 适用场景 | 维护成本 |
|---|---|---|
| 变量统一管理 | 单个测试文件内重复选择器、小型临时测试项目 | 中等,跨文件修改需要同步多个位置 |
| 页面对象模式 | 中大型测试项目、多个测试文件复用相同页面元素 | 低,所有选择器集中在页面对象文件修改 |
实践注意事项
- 页面对象中的元素命名要清晰,建议和页面元素的实际功能对应,比如
usernameInput而不是input1 - 如果页面有多个相似的元素,可以使用数组或者对象结构组织选择器,避免单个变量过于冗长
- 页面对象中的commands方法要尽量单一职责,每个方法只做一件和页面相关的事情,方便测试用例组合调用
- Nightwatch.js需要在配置文件中开启页面对象功能,在
nightwatch.conf.js中添加如下配置:
module.exports = {
// 其他配置项
page_objects_path: 'page_objects' // 指定页面对象文件所在的目录
};
通过变量和页面对象两种方式的实践,可以有效避免Nightwatch.js中重复元素选择器的问题,让测试代码更简洁、更易维护。小型项目可以先从变量方式入手,项目规模扩大后再迁移到页面对象模式,两种方案也可以结合使用,满足不同的开发需求。
Nightwatch.js元素选择器变量页面对象UI自动化测试修改时间:2026-06-28 09:36:38