Protractor
通过程序模拟用户在浏览器中操作来做自动化测试。
Protractor
可以为angular
应用做自动化测试,它有些api
是专门为angular
提供的。
如果不是angular
应用,也可以用Protractor
做自动化测试,只要避开调用angular
专属api
就可以了,本文的示例就是非angular
应用。
这篇文章包括以下内容:
Protractor
环境搭建
Protractor
自动化测试示例
安装NodeJS
,版本要求支持async await
。写这篇文章时候NodeJS LTS最新版6.10.3
还不支持,请下载非LTS最新版
。
使用npm
全局安装Protractor
npm install -g protractor
安装Protractor
需要用到BrowserDriver
等,命令行执行
webdriver-manager update
下面来做一个例子,涉及两个文件
conf.js
内容是Protractor
的配置项
spec.js
内容是自动化测试脚本
exports.config = { framework: 'jasmine', directConnect: true, SELENIUM_PROMISE_MANAGER: false, specs: ['spec.js'] }
解释一下这4个配置项
framework: 'jasmine'
指定使用测试框架jasmine
不熟悉jasmine
?没关系,看下面这段使用了jasmine
的测试脚本:
describe("A suite is just a function", function() { var a; it("and so is a spec", function() { a = true; expect(a).toBe(true); }); });
jasmine
提供了以下功能:
函数it
定义了一个测试用例。
函数it
中expect(a).toBe(true)
表示对意思是期望a为true
。如果a不等于true,测试用例执行失败。
函数describe
里面可以包含多个it
,起到一个对测试用例分组的作用。
测试脚本执行完毕后,会打出结果,多少测试用例执行成功,多少执行失败以及失败的原因。
想了解更多jasmine
的信息,点击这里。
directConnect: true
这个图最左边运行的是测试脚本,最右边是浏览器。
测试脚本在Node中运行,测试脚本想要控制浏览器行为,要通过中间的Selenium Server
,Selenium Server
担当一个翻译转述的角色。
设置directConnect: true
代表测试脚本将不经过Selenium Server
,直接和浏览器通信,这样环境更简单,更快速。
Selenium Server
在Protractor
中存在的意义说实话,我不清楚,望了解的读者告知。
SELENIUM_PROMISE_MANAGER: false
字面意思就是不使用selenium promise manager
看下面这段测试脚本:
it('test', function () { ...... browser.driver.get('https://www.baidu.com'); $('#kw').sendKeys('protractor'); $('#su').click(); ...... });
这段测试脚本在操作浏览器,底层用的是webdriverjs
:
打开百度页面,输入protractor,点击搜索。
这三个操作都是异步的,我们需要每个异步操作执行完毕后再执行下个操作。
想达到这个效果,我们可以使用callback,但最终会导致callback hell。
为了避免callback hell,promise manager
出场了,它的作用就是让你用同步的写法去写异步操作,效果是一个异步操作执行完毕后才执行下一个。
我们这里将promise manager
禁用了又是为什么呢?
webdriverjs
很多年前就有了,promise manager
是webdriverjs
自己实现的,代码很多,维护也困难。
ES2017中async await
得到了支持,使用async await
同样可以达到想要的效果。因此webdriverjs
已准备放弃promise manager
,推荐直接使用async await
。这就是为什么在环境搭建时要求大家安装支持async await
版本的NodeJS。
specs: ['spec.js']
指定要执行的测试脚本,是个数组,代表可以放多个脚本文件。
describe('测试百度搜索', function () { it('测试protractor官网会不会出现在第一个搜索结果中', async function () { await browser.waitForAngularEnabled(false); await browser.driver.get('https://www.baidu.com'); await $('#kw').sendKeys('protractor'); await $('#su').click(); var EC = protractor.ExpectedConditions; await browser.wait(EC.presenceOf($('.result.c-container h3')), 5000); await expect($$('.result.c-container h3 a').first().getText()) .toBe('Protractor - end-to-end testing for AngularJS'); }); });
下面解释一下这段代码。
代码用了async await
。await
后面是一个异步操作,程序会阻塞在这里,直到异步操作执行完毕后,才会继续向下执行。
开头说过,Protractor
是为angular
设计的。
脚本通过browser.get('url goes here')
让浏览器加载一个angular应用,这句话会一直阻塞到angular应用初始化完毕。如果加载的不是一个angular应用,会抛异常出来。
如果想让Protractor
测试非angular应用,下面两行代码是必须的
// 不需要等待angular应用初始化完毕,因为不是angular应用await browser.waitForAngularEnabled(false);// 使用browser.driver.get加载非angular应用,browser.get用于加载angular应用await browser.driver.get('https://www.baidu.com');
像jquery一样选择dom元素,输入搜索字符串,点击搜索按钮
// 搜索框输入protractorawait $('#kw').sendKeys('protractor');// 点击搜索按钮await $('#su').click();
点击搜索后,搜索结果不是立刻出现的,要等待一阵。
var EC = protractor.ExpectedConditions;// 等待结果的dom元素出现,超时时间5000毫秒,超过超时时间认为测试用例执行失败await browser.wait(EC.presenceOf($('.result.c-container h3')), 5000);
判断第一个搜索结果的header和Protractor
官网是否一样
// $$选取所有符合css选择符的元素await expect($$('.result.c-container h3 a').first().getText()) .toBe('Protractor - end-to-end testing for AngularJS');
命令行输入
protractor conf.js
控制台打印结果
1 spec, 0 failures Finished in 2.235 seconds
只有登录之后才可以评论,请点击这里进行登录