Freewind @ Thoughtworks scala java javascript dart 工具 编程实践 月结 math python english [comments admin] [feed]

(2013-01-01) 18. E2E测试

广告: 云梯:翻墙vpn (省10元) 土行孙:科研用户翻墙http proxy (有优惠)

当程序越来越大,越来越复杂的时候,靠人工手动测试新特性、抓bug变得越来越不可靠了。

为了解决这个问题,我们创建了Angular Scenario Runner来模拟用户与程序的交互,来帮助我们检查Angular程序的健康状况。

概览

你使用JavaScript来写情景测试,描述在一个确定的状态下给定一个确定的交互,你的程序如何反应。一个情景包含了一个或多个it(..)块(你可以把它们想像你的程序要满足的需求),由命令预期组成。命令用来指挥Runner让程序做一些操作(比如转到某个页面,或者点击一个按钮),而预期用来指挥Runner验证程序状态(如某个字段的值,或者当前的URL)。如果验证出错,runner把当前的it块标记为"failed"并继续运行下一个。情景脚本还可以有beforeEachafterEach块,它们会在每一个it块之前或之后运行,不管测试过程中有没有失败。

image

作为对上面元素的补充,情景脚本还可以包含一些工具函数,用来减少it块中的重复代码。

这里是一个简单的情景脚本的示例:

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);
  });
});

这一段情景脚本描述了"Buzz Client"的需求,它应该可以对用户数据流进行过滤。开始时,它向"user"这个input中输入一个值'jacksparrow',然后点了页面中仅有的一个按钮,最后验证列表中有10个元素。然后再输入'Bees',验证列表中只有1个元素。

下面的API列表描述了Runner中的可用命令和验证。

API

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

pause()

暂停测试的运行直到你在控制台中调用了resume()(或点击了Runner UI上的resume链接)

sleep(seconds)

暂停测试指定的秒数

browser().navigateTo(url)

把指定的url导入到测试框架中

browser().navigateTo(url, fn)

fn返回的URL导入到测试框架中。给定的url仅仅用来在测试输出中作为提示信息显示出来。当要测试的url是动态生成的时候,可使用这个方法。

browser().reload()

重新导入当前的页面

browser().window().href()

返回当前测试框架中页面的window.location.href

browser().window().path()

返回当前测试框架中页面的window.location.pathname

browser().window().search()

返回当前测试框架中页面的window.location.search的值

browser().window().hash()

返回当前测试框架中页面的window.location.hash( 不包含#)的值

browser().location().url()

返回当前测试框架中页面的$location.url()的值

browser().location().path()

返回当前测试框架中页面的$location.path()的值

browser().location().search()

返回当前测试框架中页面的$location.search()的值

browser().location().hash()

返回当前测试框架中页面的$location.hash()的值

expect(future).{matcher}

验证给定的future的值是否满足matcher。所有返回一个future对象的API,在它们运行结束后都会得到一个value。Matcher使用angular.scenario.matcher定义,并且将使用future的值来验证。

例如:expect(browser().location().href()).toEqual('http://www.google.com')

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

验证给定fufure的值满足matcher的相反值。

using(selector, label)

选择下一个DSL元素的域

binding(name)

返回与给定name匹配的第一个绑定值

input(name).enter(value)

将给定value输入到name对应的文本输入框中

input(name).check()

name对应的checobox选中或取消选择

input(name).select(value)

选中name单选框组中value对应的那个单选框

input(name).val()

得到name输入框中的值

repeater(selector, label).count()

返回jQuery selector 匹配的repeater中的行数。Label用于在测试中输出为提示信息。

repeater(selector, label).row(index)

得到jquery selector匹配的repeater中index所对应的中的绑定数据的数组。label用于在测试中输出信息。

repeater(selector, label).column(binding)

得到jquery selector匹配的repeater中index所对应的中的绑定数据的数组。label用于在测试中输出信息。

select(name).option(value)

name对应的select控件中,选择value对应的那一项

select(name).option(value1, value2…)

name对应的select控件中,选择value1, value2对应的那几项

element(selector, label).count()

返回jquery selector匹配的元素的个数。label用于输出信息。

element(selector, label).click()

对jquery selector对应的元素进行单击操作。label用于输出信息。

element(selector, label).query(fn)

对jquery selector匹配的元素(标记为selectedElements)执行fn(selectedElements, done)操作。其中done是在fn函数执行结束时要运行的一个函数。label用于输出信息。

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

对jquery selector匹配的元素执行method操作,其中method可以是下列jQuery方法中的任一个: val, text,html, height, innerHeight, outerHeight, width, innerWidth, outerWidth, position,scrollLeft, scrollTop, offsetlabel用于在测试中输出提示信息。

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

对jquery selector匹配的元素执行method操作,value作为传入的参数,其中method可以是下列jQuery方法中的任一个:val, text, html, height, innerHeight, outerHeight, width, innerWidth, outerWidth,position, scrollLeft, scrollTop, offsetlabel用于在测试中输出提示信息。

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

对jquery selector匹配的元素执行method操作,key作为传入的参数,其中method可以是下列jQuery方法中的任一个:attr, prop, csslabel用于在测试中输出提示信息。

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

对jquery selector匹配的元素执行method操作,keyvalue作为传入的参数。其中method可以是下列jQuery方法中的任一个:attr, prop, csslabel用于在测试中输出提示信息。

JavaScript是一种拥有强大表现力的动态类型语言,但是它几乎没有办法从编译器中得到任何帮助。因此,我们强烈建议对于用JavaScript所写的任何代码,都要有相对应的一组测试。我们给Anguar增加了很多可以让你更容易测试Angular程序的特性,所以没有理由不用它。

comments powered by Disqus