上一篇:搭建本身的前端自动化测试脚手架(二)
By LancerComet at 23:47, 2016.07.22. 欢迎转载,转载时还请保留做者署名。前端
这是最后一章了!(・∀・)
以前咱们配置好了咱们的脚手架工具,如今能够编写测试用例了!git
在项目根目录新建一个名为 "tests" 的目录,而后这里就用来存放咱们即将编写的测试用例文件。
那么这个文件夹能不能指向到其余地方去呢?固然能够,不过要修改一个小地方。github
还记得 " nightwatch.json " 文件么?打开看看,第一项是否是叫 src_folders
,而后值为 ["tests"]
?
我相信您已经懂了,这里就是定义测试用例存放目录的地方,而后改为本身想要的目录吧!npm
您能够在目录中存放多个测试用例文件,且命名随意,Nightwatch 将读取目录中全部的 JS 文件,若是符合测试用例格式,将会自动执行。json
在 "tests" 目录中创建一个测试用例文件 "demo.js",而后咱们来写一个没什么用的小 demo!segmentfault
这个 Demo 将打开 Bing,搜索 "what is microsoft",而后保存成截图后退出。api
OK,打开 "demo.js",添加如下内容:浏览器
module.exports = { 'Find the answer.': function (client) { // TODO... } }
module.exports 导出一个对象,对象的 Key 即为测试用例名称,您能够编写多个测试用例,Nightwatch 将依次执行。cookie
您能够在测试用例中导入其余模块并直接使用在测试逻辑中,这也是比 Phantom.JS 优秀的地方。架构
先写到这里,您可能会对 cilent
感到陌生,因此仍是要简单介绍一下。
client
是代码运行时 Nightwatch 提供的对象,全部对浏览器进行的操做都将使用此对象调取,好比 client.click("CSS Selector")
、client.getCookie(function () {...})
,咱们第一章说过的 "能够简单理解为 Selenium 的控制软件" 就是经过它体现的喔!
client 的全部 API 详情见 这里。
大体了解这东西的意思以后,就能够接着完善测试逻辑了:
module.exports = { 'Find the answer.': function (client) { // 定义 Bing 页面中的节点. const searchInput = '#sb_form_q' const searchBtn = '#sb_form_go' const question = 'what is microsoft' // 启动浏览器并打开 bing.com. client.url('http://bing.com').maximizeWindow() // 确保 "body" 和输入框可使用. client.expect.element('body').to.be.present client.expect.element(searchInput).to.be.visible client.pause(2000) // 稍等两秒. // 输入 "what is microsoft" 而后搜索. client.setValue(searchInput, question) client.click(searchBtn) client.pause(2000) // 截一张图而后保存到 "reports/answer.png". client.expect.element('body').to.be.present client.saveScreenshot('reports/answers.png') client.end() } }
来关注一下 expect
,是否是看起来很像天然语言?这些语句就是测试结果的验证语句,就是咱们但愿获得的结果。好比 client.expect.element('body').to.be.present.before(3000)
,意思就是 "但愿 body 元素能在 3000 毫秒内初始化完毕"。
Nightwatch 支持 BDD-Style 与 Assert 断言两种风格,文档可见 这里。
关于 Assert、BDD、TDD 的更多内容请参照其余文章。
是否是确实没什么用?毕竟是个简单的 Demo 而已,哈哈。
那么添加一个稍微复杂点的测试用例。
这个 demo 将打开 Bilibili 直播 ,而后执行:
打开首页并等待加载完毕;
检查登录按钮是否存在;
点击登录按钮;
填写用户名与密码;
点击登录;
等待页面加载;
经过 Cookie 检查是否已登录;
确保登录后的用户导航面板存在;
鼠标移至头像处打开导航面板;
点击退出登录;
等待页面刷新后检查 Cookie 是否已退出登录;
结束测试。
其实就是第一章的那个 Demo 图干的事情了 (・∀・)
这个 demo 再也不啰嗦,直接放出代码:
// Account setting. const accountConfig = { username: 'USERNAME', password: 'PASSWORD', uid: '10000' } module.exports = { 'Bilibili Live Login Test': function (client) { client.url('http://live.bilibili.com').maximizeWindow() // Page Init. client.expect.element('body').to.be.present.before(3000) client.expect.element('.top-nav-login-btn.last').to.be.visible // Login. client.click('.top-nav-login-btn.last') client.waitForElementVisible('#bilibili-quick-login', 2000) client.frame(0) client.pause(2000) client.setValue('#login-username', accountConfig.username) client.setValue('#login-passwd', accountConfig.password) client.click('#login-submit') // Wait and check page has been reloaded. client.frameParent() client.pause(4000) client.expect.element('body').to.be.present.before(3000) // Check cookies to ensure we are signed in. client.getCookies(function (result) { result.value.forEach((value, index, array) => { if (value.name === 'DedeUserID') client.assert.equal(parseInt(value.value, 10), accountConfig.uid) }) }) // Move to User Avatar. client.expect.element('.user-avatar-link').to.be.visible client.moveToElement('.user-avatar-link', 5, 5) client.pause(800) client.expect.element('#top-nav-user-panel').to.be.visible // Logout. client.click('#top-nav-logout-link') client.pause(5000) client.expect.element('body').to.be.present.before(3000) // Check cookies again to ensure we are off. client.getCookies(function (result) { var logout = true result.value.forEach((value, index, array) => { if (value.name === 'LIVE_LOGIN_DATA') logout = false }) client.assert.equal(logout, true) }) client.pause(1000) client.end() } }
您能够新建一个文件,或者在以前的文件中继续编写。
回到项目根目录,执行 npm start
,而后就能够看到浏览器本身测试了!
运行效果以下:
测试运行完毕以后,测试结果将打印在终端里,同时会生成到 reports 文件夹中。
您能够在 nightwatch.json 中修改 "output_folder" 来更换报告生成目录。
您可能在使用中会遇到例如 “明明看到节点缺获取不到”、“鼠标功能好像时好时坏” 等问题,在此给您一些建议:
因为如今不少网站使用诸如 Angular、Vue 等框架构建,其节点可能为组件动态渲染,因此 Selenium 在执行测试时可能获取的 Dom 树为旧数据从而致使找不到节点,所以您能够执行等待语句确保节点出现后再进行测试。不过可能不是 100% 成功,这也是这套测试系统的短板之一。
若是您在进行模拟鼠标的测试,您的鼠标指针可能会干扰您的测试,所以建议运行测试后将您的指针移动至屏幕外部,以免干扰到浏览器测试。
测试极可能由于页面加载时间问题致使测试失败,不过这也是 E2E 测试的特征所在,您能够修改您的测试逻辑,或致力缩短加载时间。
如今您已经拥有您本身的测试工具而且成功编写了两个测试用例!此处您应该为本身鼓掌!
您如今已经能够将 E2E 测试归入您的开发流程之中,在下相信这将对您的开发有不小的帮助。若是您有兴趣,您也能够考虑 单元测试 的可能性。
若是您没能成功构建您的项目,您能够从这里获取代码。
同时像以前提到的,若是您在使用 Vue 构建您的项目,您可使用 Vue-cli 来生成已经包含 Selenium 与 Nightwatch 的 Vue 种子项目,您能够在 test/e2e
中编写您的测试用例。
但愿三篇简单的短文能给您带来帮助!⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄