|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +category : AngularJS |
| 4 | +tagline: "" |
| 5 | +tags : [ng,e2e,protractor,jasmine] |
| 6 | +--- |
| 7 | +{% include JB/setup %} |
| 8 | + |
| 9 | +在上一篇文章里有讲到<a href="http://www.ifeenan.com/angularjs/2014-08-18-%E8%AF%B4%E8%AF%B4NG%E9%87%8C%E7%9A%84%E5%8D%95%E5%85%83%E6%B5%8B%E8%AF%95/" target="_blank">ng的单元测试</a>,今天来说说`e2e`(端对端)测试. |
| 10 | + |
| 11 | +当我们测试某个模块的单个功能点时,单元测试最适合,不过当面临用户进行多个页面交互的时候产生bug了,单元测试就不行了,这时候就得用`e2e`来模拟用户操作还原问题现场.当然利用`e2e`测试也能够测试程序的健壮性,很多单元测试办不到的事情,`e2e`测试都能够办到. |
| 12 | + |
| 13 | +之前,`ng`是利用`Angular Scenario Runner`来运行`e2e`测试,现在已经换成<a href="https://github.com/angular/protractor" target="_blank">Protractor</a>来跑`e2e`了. |
| 14 | + |
| 15 | +### Protractor |
| 16 | + |
| 17 | +`Protractor`是`Angularjs`里用来测试`e2e`的框架,它本身是一个`npm`模块,内部是构建在<a href="https://code.google.com/p/selenium/wiki/WebDriverJs" target="_blank">WebDriverJS</a>之上的,`Protractor`能够真正让你的测试用例运行在浏览器上,完全模拟用户的真实行为. |
| 18 | + |
| 19 | +下面贴上它的一些资源地址: |
| 20 | + |
| 21 | +* <a href="https://github.com/angular/protractor/blob/master/docs/api.md" target="_blank">Protractor提供的测试api</a> |
| 22 | + |
| 23 | +* <a href="https://github.com/angular/protractor/blob/master/docs/tutorial.md" target="_blank">Protractor简单使用例子</a> |
| 24 | + |
| 25 | +* <a href="https://code.google.com/p/selenium/wiki/WebDriverJs" target="_blank">WebDriverJs指南</a>,这是`Protractor`依赖的核心,npm模块名为`selenium-webdriver` |
| 26 | + |
| 27 | +### Protractor运行原理 |
| 28 | + |
| 29 | +`Protractor`运行`e2e`测试所依赖的主要有以下几个东西: |
| 30 | + |
| 31 | +* WebDriver APIs,就是上面提到的`WebDriverJs`,是由`Selenium`提供给前端测试用的相关js api |
| 32 | + |
| 33 | +* Selenium Server,一个后端jar包,用来负责跟浏览器驱动进行通讯用的 |
| 34 | + |
| 35 | +* WebDriver browser drivers,用来显示真实网站内容并与`Selenium Server`通讯用,这里才是传递真实浏览器操作的地方 |
| 36 | + |
| 37 | +整个运行过程如下图 |
| 38 | + |
| 39 | +<img src="https://raw.githubusercontent.com/angular/protractor/master/docs/components.png" alt=""> |
| 40 | + |
| 41 | +想了解更多关于这几个组件之前交互的可以<a href="https://github.com/angular/protractor/blob/master/docs/infrastructure.md" target="_blank">点击这里</a> |
| 42 | + |
| 43 | +### 利用ng种子项目来讲解e2e |
| 44 | + |
| 45 | +我们利用`ng`官方提供的种子项目来讲解一个真实的`e2e`例子,首先利用下面命令获取种子项目 |
| 46 | + |
| 47 | +> git clone https://github.com/angular/angular-seed.git |
| 48 | +
|
| 49 | +然后运行 |
| 50 | + |
| 51 | +> npm install |
| 52 | +
|
| 53 | +安装相关的所有依赖文件 |
| 54 | + |
| 55 | +这里先说下运行`e2e`测试需要的配置文件,可以看到`test/protractor-conf.js`这个文件就是用来配置相关功能的,重点说下几个属性 |
| 56 | + |
| 57 | +* specs 代表要运行的测试文件路径,这里写的是`e2e/*.js` |
| 58 | + |
| 59 | +* baseUrl 代表测试文件中浏览器间跳转页面的根地址 |
| 60 | + |
| 61 | +* capabilities 代表使用哪个浏览器来运行测试用例,比如使用`chrome`,可以这样设置 |
| 62 | + |
| 63 | +```js |
| 64 | + capabilities: { |
| 65 | + 'browserName': 'chrome' |
| 66 | + } |
| 67 | +``` |
| 68 | + |
| 69 | +* framework 代表使用的哪种测试框架,这里使用的是`jasmine` |
| 70 | + |
| 71 | +想了解更多关于这个配置文件的可以<a href="https://github.com/angular/protractor/blob/master/docs/referenceConf.js" target="_blank">点击这里查看</a> |
| 72 | + |
| 73 | +说完了配置文件,我们再来看看测试用例的写法,先贴上一个官网上的例子 |
| 74 | + |
| 75 | +```js |
| 76 | +'use strict'; |
| 77 | + |
| 78 | +/* https://github.com/angular/protractor/blob/master/docs/getting-started.md */ |
| 79 | + |
| 80 | +describe('my app', function() { |
| 81 | + |
| 82 | + browser.get('index.html'); |
| 83 | + it('should automatically redirect to /view1 when location hash/fragment is empty', function() { |
| 84 | + expect(browser.getLocationAbsUrl()).toMatch("/view1"); |
| 85 | + }); |
| 86 | + |
| 87 | + |
| 88 | + describe('view1', function() { |
| 89 | + |
| 90 | + beforeEach(function() { |
| 91 | + browser.get('index.html#/view1'); |
| 92 | + }); |
| 93 | + |
| 94 | + |
| 95 | + it('should render view1 when user navigates to /view1', function() { |
| 96 | + expect(element.all(by.css('[ng-view] p')).first().getText()). |
| 97 | + toMatch(/partial for view 1/); |
| 98 | + }); |
| 99 | + |
| 100 | + }); |
| 101 | + |
| 102 | + |
| 103 | + describe('view2', function() { |
| 104 | + |
| 105 | + beforeEach(function() { |
| 106 | + browser.get('index.html#/view2'); |
| 107 | + }); |
| 108 | + |
| 109 | + |
| 110 | + it('should render view2 when user navigates to /view2', function() { |
| 111 | + expect(element.all(by.css('[ng-view] p')).first().getText()). |
| 112 | + toMatch(/partial for view 2/); |
| 113 | + }); |
| 114 | + |
| 115 | + }); |
| 116 | +}); |
| 117 | + |
| 118 | +``` |
| 119 | + |
| 120 | +首先上面的语法是`jasmine`框架支持的写法,不了解它的用法的可以<a href="http://jasmine.github.io/2.0/introduction.html" target="_blank">点击这里</a> |
| 121 | + |
| 122 | +这里只说下上面例子里关于`protractor`提供的一些常用方法与属性 |
| 123 | + |
| 124 | +* browser,全局对象,代表当前浏览器的一个实例,常用的`get`方法用来实现浏览器改变地址 |
| 125 | + |
| 126 | +* element,全局对象,提供像`jquery`里负责查找文档元素的功能,常于`by`对象联合使用 |
| 127 | + |
| 128 | +* by, 全局对象,提供一个选择器类型,比如可以通过`css`,`model`,`bind`等特性来查找一个元素 |
| 129 | + |
| 130 | +关于`element`与`by`的方法可以参考上面的<a href="https://github.com/angular/protractor/blob/master/docs/api.md" target="_blank">protractor api文档</a> |
| 131 | + |
| 132 | +说了这么多,该跑一跑上面的测试用例了,命令比较简单 |
| 133 | + |
| 134 | +> npm run update-webdriver |
| 135 | +
|
| 136 | +这个负责下载相关的`浏览器驱动`与`selenium-server 本地jar包`,一般情况下这个都是会失败的,因为这两个资源都在`google`服务器那,所以可以利用浏览器翻墙单独下载,地址如下: |
| 137 | + |
| 138 | +* <a href="http://chromedriver.storage.googleapis.com/index.html" target="_blank">Chrome Driver地址</a>,一般下载`chromedriver_2.9.zip`这个文件. |
| 139 | + |
| 140 | +* <a href="http://selenium-release.storage.googleapis.com/index.html" target="_blank">selenium-server 本地jar包 下载</a>,一般下载`selenium-server-standalone-2.40.0.jar`这个文件. |
| 141 | + |
| 142 | +然后把`selenium-server`拷到`protractor`包里的`selenium`文件夹里去,假如上面的命令超时之后,这里也会出现文件不过是空的,直接替换就可以;还要把`chromedriver_2.9.zip`解压之后的文件拷到这里 |
| 143 | + |
| 144 | +最后运行下面的命令可以看到测试结果了 |
| 145 | + |
| 146 | +> npm run protractor |
| 147 | +
|
| 148 | +想了解更多关于`ng`种子项目里的命令行,可以<a href="https://github.com/angular/angular-seed/blob/master/README.md" target="_blank">点击这里查看</a> |
| 149 | + |
| 150 | +### 总结 |
| 151 | + |
| 152 | +`ng`的`e2e`测试要比单元测试配置要繁琐的多,不过它能做的事情也很多,非常值的你也试一试,有什么问题可以回复到评论里去. |
| 153 | + |
| 154 | + |
| 155 | + |
| 156 | + |
| 157 | + |
| 158 | + |
| 159 | + |
| 160 | + |
| 161 | + |
| 162 | + |
| 163 | + |
| 164 | + |
0 commit comments