不久前,埃里克·埃利奥特(Eric Elliott)撰写了JavaScript测试:单元测试 , 功能测试和集成测试 ,其中他解释了测试的不同类型以及何时使用。
在今天的文章中,我想更深入地介绍JavaScript功能测试。 为此,我们将探索和使用Nightwatch.js库。
但是在开始之前,请允许我提醒您什么是功能测试,以及为何如此重要。 粗略地说,功能测试是一个过程,旨在确保应用程序能够从用户的角度正常运行。
我们不是在谈论技术测试,例如单元测试或集成测试。 在这里,目标是确保用户可以无缝执行特定方案,例如登录平台,购买产品等。
介绍Nightwatch.js
Nightwatch.js自身描述了一个由Node.js驱动的端到端测试框架。 它依赖于Selenium ,一个旨在促进Web浏览器自动化的项目。
通过人性化的语法,Nightwatch.js使“脚本”场景成为可能,然后由浏览器自动播放(不一定是无头)。
安装Nightwatch
Nightwatch本身是一个Node.js模块,这意味着您需要在计算机上安装Node。 最简单的方法是使用版本管理器,例如nvm 。 Nightwatch在npm上分发,因此您可以像安装其他任何模块一样安装它-通过-g
全局安装,或通过--save-dev
在当前项目中安装。
npm install --save-dev nightwatch
Nightwatch依赖Selenium WebDriver API,因此需要Selenium WebDriver服务器。 它在Java上运行,这意味着您还必须在您的环境中安装Java开发工具包(JDK 7+)。 您可以从Oracle网站下载JDK 。
下载并安装后,您可以使用java -version
确保Java在计算机上正确可用。 最后一步是从Selenium下载页面下载打包成jar的Selenium独立服务器。 我建议您将其放在项目内的bin
文件夹中。
your_project/
|
|– bin/
| |– selenium-server-standlone-2.53.1.jar
|
`– package.json
好的,我们都准备好了。 让我们开始吧。
配置守夜人
可以想象,Nightwatch有很多配置。 幸运的是,我们不必一无所知。 该配置可以位于项目根目录的nightwatch.json
文件或nightwatch.conf.js
文件中。 我建议使用后者,因为它稍微灵活一些,并且可以添加注释。
var SELENIUM_CONFIGURATION = {
start_process: true,
server_path: 'bin/selenium-server-standalone-2.53.0.jar',
host: '127.0.0.1',
port: 4444
};
var FIREFOX_CONFIGURATION = {
browserName: 'firefox',
javascriptEnabled: true,
acceptSslCerts: true
};
var DEFAULT_CONFIGURATION = {
launch_url: 'http://localhost',
selenium_port: 4444,
selenium_host: 'localhost',
desiredCapabilities: FIREFOX_CONFIGURATION
};
var ENVIRONMENTS = {
default: DEFAULT_CONFIGURATION
};
module.exports = {
src_folders: ['tests'],
selenium: SELENIUM_CONFIGURATION,
test_settings: ENVIRONMENTS
};
注意:我个人发现,将配置文件拆分为较小的配置对象时,该文件更易于阅读,而JSON文件则不允许这样做。
在本例中,我们告诉Nightwatch,我们的测试将使用特定的Selenium配置和特定的测试设置保存在tests
文件夹中。 让我们遍历每个块:
var SELENIUM_CONFIGURATION = {
start_process: true,
server_path: 'bin/selenium-server-standalone-2.53.0.jar',
host: '127.0.0.1',
port: 4444
};
使用此配置对象,我们告诉Selenium在127.0.0.1:4444
上运行,它恰好是Nightwatch的默认值。 我们还确保它使用下载并存储在bin
文件夹中的Selenium服务器自动启动。
注意:要进行更高级的使用,请务必检查所有Selenium选项的列表 。
继续进行实际的测试设置:
var DEFAULT_CONFIGURATION = {
launch_url: 'http://localhost',
selenium_port: 4444,
selenium_host: 'localhost',
desiredCapabilities: FIREFOX_CONFIGURATION
};
var ENVIRONMENTS = {
default: DEFAULT_CONFIGURATION
};
Nightwatch的test_settings
选项需要一个对象,其键是每个环境的名称,并映射到另一个配置对象。 在本例中,我们尚未设置自定义环境,因此我们使用default
。 稍后,我们可能会有一个staging
或production
测试环境。
在环境配置中,我们告诉Nightwatch要打开哪个URL(例如,对于登台而言,这是不同的),以及应该使用哪种浏览器来运行测试。
var FIREFOX_CONFIGURATION = {
browserName: 'firefox',
javascriptEnabled: true,
acceptSslCerts: true
};
在我们的方案中,我们将使用未启用JavaScript的Firefox,允许使用SSL证书。 我们可以进一步指定一个特定的浏览器版本(带有version
)或操作系统(带有platform
)。
好了,我们现在有了正确的配置。 是时候写第一个测试了!
编写守夜测试
对于我们的测试,我们将考虑/login
的登录页面,其中包含一个电子邮件字段,一个密码字段和一个提交按钮。 提交表单时,应将用户重定向到显示“新闻提要”的页面。
在我们的配置中,我们指定测试位于名为tests
的文件夹中。 让我们创建一个tests
文件夹,以及一个名为login.js
的文件。
your_project/
|
|– bin/
| |– selenium-server-standlone-2.53.1.jar
|
|– tests/
| |– login.js
|
|- nightwatch.conf.js
`– package.json
该文件将导出一个描述我们方案的对象。 每个键(如果有多个键)是测试的名称,映射到包含要执行的步骤的功能。
module.exports = {
'Login test': function (client) {
// Steps to execute
}
};
测试功能公开了一个对象,该对象提供了描述场景所需的API。 首先要做的是导航到登录URL。 然后,填写字段并按按钮。 最后,检查我们是否可以发现“新闻提要”文本。
module.exports = {
'Login test': function (client) {
client
.url('http://foobar.qux/login')
.setValue('input[name="email"]', 'foo@bar.com')
.setValue('input[name="password]', 'p455w0rdZ')
.click('button[type="submit"]')
.assert.containsText('main', 'News feed')
.end();
}
};
注意:始终使用.end()
终止指令列表,以正确关闭Selenium会话。
那很简单! 现在,我们可以运行测试以查看其是否有效:
./node_modules/.bin/nightwatch
这应该给我们这样的东西:
注意:随着Firefox 47的发行, 基于扩展的版本FirefoxDriver停止工作 。 Firefox 47.1和Selenium 2.53.1已修复此问题 。 要使用其他浏览器运行测试,请查阅项目的Wiki 。
为了避免每次都到达Nightwatch二进制文件,我们可以做的最后一件事是在package.json
创建一个小的npm脚本对其进行别名:
{
"scripts": {
"test": "nightwatch"
}
}
改进夜视测试
进行大量的功能测试可能会导致产生大量重复的信息,从而使维护变得困难(是的,还需要维护测试套件)。 为了防止这种情况,我们可以使用Page Objects 。
在端到端测试的世界中,“页面对象”方法是一种流行的模式,包括将测试的页面(或页面片段)包装到对象中。 目标是抽象出基本的HTML和常规配置以简化方案。
幸运的是,Nightwatch具有处理页面对象的简单方法。 我们需要做的第一件事是将page_objects_path
选项添加到配置中。 我觉得tests/pages
有意义; 您可以指定任何文件夹。
module.exports = {
src_folders: ['tests'],
page_objects_path: 'tests/pages',
selenium: SELENIUM_CONFIGURATION,
test_settings: ENVIRONMENTS
};
现在,我们可以在此文件夹中创建一个login.js
文件。 该文件名稍后将用作检索此文件中指定的所有配置的键,因此我建议给它取一个明智的名称。
在此文件中,我们将指定一个URL并为一些HTML元素添加别名,并使用友好名称,以使编写将来的方案变得更加容易。
module.exports = {
url: function () {
return this.api.launch_url + '/login';
},
elements: {
emailField: 'input[name="email"]',
passwordField: 'input[name="password"]',
submitButton: 'button[type="submit"]'
}
};
请注意,我们不会对网址进行硬编码。 相反,我们依赖于环境配置中定义的launchUrl
选项。 这样,我们的页面对象是上下文无关的,并且无论在什么环境下都可以工作。
现在很直接地修改我们的测试以使用page对象。 首先,我们需要从客户端通过page
对象检索页面。 每个页面对象都被公开为以页面对象文件名(例如login()
)命名的函数。
然后,我们可以用别名(以@
符号为前缀)替换我们的CSS选择器,以表示我们引用的是自定义名称。 而已。
module.exports = {
'Login test': (client) => {
const page = client.page.login();
page.navigate()
.setValue('@emailField', 'foo@bar.com')
.setValue('@passwordField', 'p455w0rdZ')
.click('@submitButton')
.assert.containsText('main', 'News feed');
client.end();
}
};
请注意,我们如何在客户端本身而不是页面上终止会话。
在多种环境下工作
能够在不同环境中运行功能测试对于确保本地工作没有中断任何用户路径,或者例如,登台和生产都在进行相同的工作很有用。
要在特定环境中运行测试,我们可以在CLI中使用--env
选项。 当我们省略该选项时,将使用default
环境(已经在我们的配置中)。
让我们在配置中添加一个暂存环境。
var STAGING_CONFIGURATION = Object.assign({}, DEFAULT_CONFIGURATION, {
launch_url: 'http://staging.foobar.qux'
});
var ENVIRONMENTS = {
default: DEFAULT_CONFIGURATION,
staging: STAGING_CONFIGURATION
};
现在,在运行测试时, launch_url
选项将根据环境而有所不同。
npm test --env staging
包装东西
让我们总结一下。 Nightwatch.js是一个JavaScript框架,用于编写端到端功能测试。 它依赖于Selenium WebDriver API,并且能够自动运行不同的浏览器。
编写测试主要包括定义典型的用户方案。 为此,有一个简单但非常完整的API。
从那里开始,我会留给您,并鼓励您开始为最大的项目编写功能测试,以确保您再也不会破坏用户功能!
From: https://www.sitepoint.com/javascript-functional-testing-nightwatch-js/