AngularJs  E2E Testing 详解


Posted in Javascript onSeptember 02, 2016

        当一个应用的复杂度、大小在增加时,使得依靠人工去测试新特性的可靠性、抓Bug和回归测试是不切实际的。

为了解决这个问题,我们建立了Angular Scenario Runner,模仿用户的操作,帮助我们去验证angular应用的健壮性。

一、   总括

我们可以在javascript中写情景测试(scenario test),描述我们的应用发生的行为,在某个状态下给与某些互动。一个情景包含一个或者多个”it”块(我们可以将这些当作对我们应用的要求),依次由命令(command)和期望(expectation)组成。command告诉Runner在应用中做某些事情(例如转到某个页面或者单击某个按钮),expectation告诉runner去判断一些关于状态的东西(例如某个域的值或者当前的URL)。如果任何expectation失败了,那么runner标记这个”it”为”false”,然后继续下一个”it”。Scenario也可以拥有” beforeEach”和” afterEach”block,这些block会在每一个”it”block之前或者之后运行,不管它是否通过。

AngularJs  E2E Testing 详解

除了上述元素外,scenario也可以包含helper function,避免在”it”block中有重复的代码。

这里是一个简单的scenario例子: 

describe('Buzz Client', function() {
 it('should filter results', function() {
  input('user').enter('jacksparrow');
  element(':button').click();
  expect(repeater('ul li').count()).toEqual(10);
  Input('filterText').enter('Bees');
  expect(repeater('ul li').count()).toEqual(1);
 });
});

这个scenario描述了网络客户端的要求,明确地,它应该有过滤user的能力。它开始的时候,输入了一个值到”user”输入框中,单击页面上唯一的按钮,然后它验证是否有10个项目列表。然后,它输入”Bees”到”filterText”的输入框中,然后验证那个列表是不是会减少到只有一个项。

下面的API章节,列出了在Runner中可用的command和expectation。

二、   API

源代码:https://github.com/angular/angular.js/blob/master/src/ngScenario/dsl.js

pause()

暂停执行测试,直到我们在console中调用resume()(也可以在Runner界面中点击resume链接)

sleep(seconds)

暂停测试执行N秒。

browser().navigateTo(url)

在tset frame中加载指定url。

  browser().navigateTo(url,fn)

在test frame中加载fn返回的url地址。这里的url参数只是用作测试输出。当目的url是动态的时候可以使用这个API(写测试的时候,地址还是未知的)。

browser().reload()

在test frame中刷新当前加载的页面。 

  browser().window().href()

返回test frame当前页面的window.location.href。 

browser().window().path()

返回test frame当前页面的window.location.pathname。 

browser().window().search()

返回test frame当前页面的window.location.search。

browser().window().hash()

返回test frame当前页面的window.location.hash(不包含#)。 

browser().location().url()

返回test frame 当前页面的$location.url()的返回结果(http://docs.angularjs.org/api/ng.$location)

  browser().location().path()

返回test frame 当前页面的$location. path ()的返回结果(http://docs.angularjs.org/api/ng.$location) 

  browser().location().search()

返回test frame 当前页面的$location. search ()的返回结果(http://docs.angularjs.org/api/ng.$location)

  browser().location().hash()

返回test frame 当前页面的$location. hash ()的返回结果(http://docs.angularjs.org/api/ng.$location)

expect(future).{matcher}

判断给定的期望(future)值是否满足matcher。所有API的声明都返回一个在它们执行完毕之后获取到的一个指定值的future对象。matcher是使用angular.scenario.matcher定义的,他们使用futures的值去执行expectation。例如:

            expect(browser().location().href()).toEqual(‘http://www.google.com');

expect(future).not().{matcher}

判断给定future的值是否与指定的matcher的预期相反。 

  using(selector,label)

Scopes the next DSL element selection.(大概是限定选择器的作用域,label估计是用于测试输出)

例子:

          using('#foo', "'Foo' text field").input('bar') 

  binding(name)

返回第一个与指定的name匹配的绑定(也许是跟ng-bind相关)。 

  input(name).enter(value)

输入指定的value到name指定的表单域。

input(name).check()

选中或者解除选中指定name的checkbox。

input(name).select(value)

选中指定name的radio中值为value的input[type=” radio”]。 

  input(name).val()

返回指定name的input的当前值。

repeater(selector,label).count()

返回与指定selector(jQuery selector)匹配的repeater的行数。label只用作测试输出。

              repeater('#products table', 'Product List').count() //number of rows

  repeater(selector,label).row(index)

返回一个数组,绑定指定selector(jQuery selector)匹配的repeater中指定index的行。label仅仅用于测试输出。

              repeater('#products table', 'Product List').row(1) //all bindings in row as an array 

repeater(selector,label).column(binding)

返回一个数组,值为指定selector(jQuery selector)匹配的repeater中符合指定binding的列。label仅仅用于测试输出。

             repeater('#products table', 'Product List').column('product.name') //all values across all rows in an array

  select(name).option(value)

选择指定name的select中指定value的option。 

  select(name).option(value1,value2)

选择指定name的select中指定value的option(多选)。 

element(selector,label).count()

返回与指定selector匹配的元素的个数。label仅仅用作测试输出。 

  element(selector,label).click()

单击与指定selector匹配的元素。label仅仅用作测试输出。 

  element(selector,label).query(fn)

执行指定的fn(selectedElements,done),selectedElement就是与指定selector匹配的元素集合;而done是一个function,会在fn执行完毕后执行。label仅仅用作测试输出。

  element(selector,label).{method}()

返回在指定selector匹配的元素上执行method的返回值。method可以是以下的jQuery方法:val、text、html、height、innerHeight、outerHeight、width、innerWidth、outerWidth、position、scrollLelft、scrollTop、offset。label仅仅用作测试输出。

element(selector,label).{method}(value)

在指定selector匹配的元素上执行指定method,并以key、value作为参数。method可以是以下的jQuery方法:val、text、html、height、innerHeight、outerHeight、width、innerWidth、outerWidth、position、scrollLelft、scrollTop、offset。label仅仅用作测试输出。

element(selector,label).{method}(key)

返回在指定selector匹配的元素上执行指定method的结果,这些方法可以是以下的jQuery方法:attr,prop,css。label仅仅用作测试输出。 

element(selector,label).{method}(key,value)

在指定的selector匹配的元素上执行method并以key、value作为参数,这些方法可以是以下的jQuery方法:attr,prop,css。label仅仅用作测试输出。

javascript是动态类型的语言,带来了强大力量的表达式,但它同时让我们从编译器中几乎得不到任何帮助。因此,我们很强烈地感受到,任何用javascript写的代码都需要进行大量、全面的测试。angular有很多特性,可以让我们更加容易地测试我们的应用。所以我们没有借口不去写测试。(-_-!!)

        以上就是对 AngularJs E2E Testing 的资料整理,后续继续增加相关资料,谢谢大家对本站的支持!

Javascript 相关文章推荐
JAVASCRIPT HashTable
Jan 22 Javascript
jQuery EasyUI API 中文文档 - TimeSpinner时间微调器
Oct 23 Javascript
javascript间隔刷新的简单实例
Nov 14 Javascript
javascript作用域链(Scope Chain)用法实例解析
Nov 30 Javascript
js获取html的span标签的值方法(超简单)
Jul 26 Javascript
微信JS接口大全
Aug 25 Javascript
分享JavaScript监听全部Ajax请求事件的方法
Aug 28 Javascript
微信小程序 跳转传参数与传对象详解及实例代码
Mar 14 Javascript
VUE axios发送跨域请求需要注意的问题
Jul 06 Javascript
基于Vue2的独立构建与运行时构建的差别(详解)
Dec 06 Javascript
vue iview实现动态路由和权限验证功能
Apr 17 Javascript
vue改变循环遍历后的数据实例
Nov 07 Javascript
解决node.js安装包失败的几种方法
Sep 02 #Javascript
js两种拼接字符串的简单方法(必看)
Sep 02 #Javascript
AngularJs Understanding the Controller Component
Sep 02 #Javascript
JS 拼凑字符串的简单实例
Sep 02 #Javascript
AngularJs Understanding the Model Component
Sep 02 #Javascript
浅谈js中StringBuffer类的实现方法及使用
Sep 02 #Javascript
AngularJs Dependency Injection(DI,依赖注入)
Sep 02 #Javascript
You might like
一些常用的php函数
2006/12/06 PHP
PHP 数据库树的遍历方法
2009/02/06 PHP
php unset全局变量运用问题的深入解析
2013/06/17 PHP
phpmyadmin出现Cannot start session without errors问题解决方法
2014/08/14 PHP
php生成html文件方法总结
2014/12/01 PHP
php-app开发接口加密详解
2018/04/18 PHP
获取offsetTop和offsetLeft值的js代码(兼容)
2013/04/16 Javascript
微信内置浏览器私有接口WeixinJSBridge介绍
2015/05/25 Javascript
浅谈JavaScript 浏览器对象
2016/06/03 Javascript
JS二叉树的简单实现方法示例
2017/04/05 Javascript
Vue学习笔记进阶篇之vue-cli安装及介绍
2017/07/18 Javascript
jQuery选择器中的特殊符号处理方法
2017/09/08 jQuery
JS Input里添加小图标的两种方法
2017/11/11 Javascript
详解ES6中的代理模式——Proxy
2018/01/08 Javascript
ExtJs整合Echarts的示例代码
2018/02/27 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
jQuery实现小火箭返回顶部特效
2020/02/03 jQuery
基于js实现的图片拖拽排序源码实例
2020/11/04 Javascript
[42:48]完美世界DOTA2联赛PWL S3 Magma vs INK ICE 第二场 12.11
2020/12/16 DOTA
详解Python3序列赋值、序列解包
2019/05/14 Python
python从入门到精通 windows安装python图文教程
2019/05/18 Python
详解Numpy中的数组拼接、合并操作(concatenate, append, stack, hstack, vstack, r_, c_等)
2019/05/27 Python
django 做 migrate 时 表已存在的处理方法
2019/08/31 Python
Django模板语言 Tags使用详解
2019/09/09 Python
python中shell执行知识点
2020/05/06 Python
Jupyter notebook命令和编辑模式常用快捷键汇总
2020/11/17 Python
CSS3制作3D立方体loading特效
2020/11/09 HTML / CSS
英国优质鞋类专家:Robinson’s Shoes
2017/12/08 全球购物
欧洲著名的二手奢侈品网站:Vestiaire Collective
2020/03/07 全球购物
Ibatis中如何提高SQL Map的性能
2013/05/11 面试题
2015年度环卫处工作总结
2015/07/24 职场文书
2016年全国爱牙日宣传活动总结
2016/04/05 职场文书
一篇文章弄懂MySQL查询语句的执行过程
2021/05/07 MySQL
Mysql Online DDL的使用详解
2021/05/20 MySQL
MySQL 十大常用字符串函数详解
2021/06/30 MySQL
JVM钩子函数的使用场景详解
2021/08/23 Java/Android