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
只有登录之后才可以评论,请点击这里进行登录