當一個應用的複雜度、大小在增加時,使得依靠人工去測試新特性的可靠性、抓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之前或者之後運行,不管它是否通過。
除了上述元素外,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 的資料整理,後續繼續增加相關資料,謝謝大家對本站的支援!