Protractor是為Angular JS應用量身打造的端到端測試框架。它可以真實的驅動瀏覽器,自動完成對web應用的測試。Protractor驅動瀏覽器使用的是WebDriver標準,所以使用起來與其他語言實現的WebDriver庫大體相同。當然,我說大體相同那肯定還是有不同的地方。一旦不注意這些不同的地方就會坑到你(我就被成功坑過,所以才有了這篇文章)。
Protractor編寫測試的核心是查詢DOM元素,與其互動,然後檢視互動後的狀態與你的期望是否一致。所以查詢DOM元素並與之互動顯的非常重要。Protractor提供了一個全域性函式element,其接受一個Locator物件並返回一個ElementFinder物件。該函式會返回單個元素。如果你想返回多個元素,可以使用element.all函式,其接受一個Locator物件並返回ElementArrayFinder物件。ElementFinder物件有一組方法,用於元素互動,比如click(),getText(),sendKeys等。
Locator物件的建立主要使用全域性的by物件,其提供一些API來生成Locator物件以供element或element.all函式使用。
比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
可以看出前兩個Locator的建立方法與其他語言實現的WebDriver的用法基本一樣,而後幾個則專為AngularJS應用設計的,方便在基於AngualrJS框架下寫的web應用中查詢頁面元素。這是第一處不同。
另一處不同其他語言實現的WebDriver庫使用Locator找到的元素型別是WebElement,而Protractor則返回的是ElementFinder物件。兩者不同之處是在於ElementFinder物件不會立即與瀏覽器互動,根據指定的Locator來查詢到頁面上的元素;而只有當你呼叫了ElementFinder物件的方法時,它才會真正的與瀏覽器進行互動。一些常用的方法有以下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
請注意這些方法都是非同步的。所有的方法返回的是一個promise(我就吃過這個虧,以為返回的是值)。所以比如你想輸出一個元素的值,應該這麼寫:
1 2 3 |
|
如果你使用expect方法來驗證元素的值時,expect方法會幫你取出promise中值,所以你只用這麼寫:
1
|
|
還有不同的地方在於Protractor支援對元素查詢時進行鏈式呼叫。這樣的功能相當實用。你可以組合element和element.all兩個函式來定位元素。並且Protractor還提供了幾個輔助方法來更方便你的使用。
1 2 3 |
|
element.all函式提供的輔助方法有:
- filter: 提供一個過濾器過濾其中的元素。
1 2 3 4 5 |
|
-
get: 根據索引獲取指定元素。如 element.all(by.css(‘myclass’)).get(0);
-
first: 獲取第一個元素。 element.all(by.css(’myclass’)).first();
-
last: 獲取最後一個元素,用法同上。
-
count:獲取元素個數。
此外還提供了each,map,reduce等方法對列表進行各種操作。
element函式提供的輔助方法有:
-
locator: 返回locator物件。
-
getWebElement: 返回該ElementFinder包裹的WebElement物件。
-
all: 查詢其一組子元素。
-
element: 查詢其子元素。
-
isPresent: 元素是否在頁面上展示。
總結起來,Protractor與其它的WebDriver語言實現的區別如下:
-
Protractor專為AngualrJS應用定製,其自身包含了很多wait操作,保證AngularJS指令碼執行完畢後才進行下一步操作,保證了測試的穩定性與健壯性。
-
Protractor設計的By物件針對AngularJS應用提供了很多實用方法,在定義AngularJS應用頁面時更加輕鬆。
-
element函式返回的是ElementFinder物件,其不會立即與瀏覽器互動,除非呼叫ElementFinder物件的方法。
-
呼叫ElementFinder物件的方法返回的是一個promise。(這點很重要)
-
Protractor在定位元素時支援鏈式呼叫。