Tellurium 自動化測試框架由方劍於 2007 年 6 月創建,2008 年 6 月遷至 Google Code 開源,定期發布版本(當前 0.7.0)。核心歷時兩年,衍生出 UDL、Core、Engine、Widget 擴展、Maven Archetype、Trump、Tellurium IDE、TelluriumWorks 及參考專案等子項目。該框架源於 Selenium,但擁有截然不同的測試理念:多數 Web 測試框架(如 Selenium)聚焦單個 UI 元素,而 Tellurium 將多個 UI 元素視為一個 Widget 整體,稱作 UI Module。
以 Google 搜索頁面為例,Tellurium 表示如下:
ui.Container(uid: "GoogleSearchModule", clocator: [tag: "td"]){
InputBox(uid: "Input", clocator: [title: "Google Search"])
SubmitButton(uid: "Search", clocator: [name: "btnG", value: "Google Search"])
SubmitButton(uid: "ImFeelingLucky", clocator: [value: "I'm Feeling Lucky"])
}
UI Module 是嵌套 UI 元素、tag 與 attribute 的集合。採用 UI Module 後,Tellurium 更具表述性,對變化響應更智能,易於表示動態 Web 內容,維護性更強。
type "GoogleSearchModule.Input","Tellurium test"、click "GoogleSearchModule.Search"。Selenium 是最流行的開源自動化 Web 測試框架,提供瀏覽器測試、Selenium Grid、IDE「錄製回放」等獨特優勢。但存在問題:
Selenium 測試代碼範例:
setUp("https://www.google.com/","*chrome");
selenium.open("/");
selenium.type("q","Selenium test");
selenium.click("//input[@value='Google Search' and @type='button']");
問題在於:
q 含義不明。Tellurium 正是為解決 Selenium 多數問題而生:
Tellurium 通過 UI Module 概念進行自動化測試,用對象封裝 Web UI 元素,無需手動生成重構定位器。UI Module 是簡單復合 UI 對象,由嵌套基本 UI 對象組成。
兩種運行模式:
定義 UI Module:
ui.Form(uid: "issueSearch", clocator: [action: "list", method: "GET"]) {
Selector(uid: "issueType", clocator: [name: "can", id: "can", direct: "true"])
TextBox(uid: "searchLabel", clocator: [tag: "span", text: "for"])
InputBox(uid: "searchBox", clocator: [type: "text", name: "q", id: "q"])
SubmitButton(uid: "searchButton", clocator: [value: "Search", direct: "true"])
}
測試方法:
public void searchIssue(String type,String issue){
select "issueSearch.issueType",type
keyType "issueSearch.searchBox",issue
click "issueSearch.searchButton"
waitForPageToLoad 30000
}
若需將 Selector 改為輸入框,僅更新 UI Module 與對應命令:
// UI Module 中 Selector 改為 InputBox
type "issueSearch.issueType",type // 原 select 改為 type
// 其余不變
包含圖書分類列表,每分類含圖書列表。UI Module 簡單:
ui.Container(uid: "GoogleBooksList", clocator: [tag: "table", id: "hp_table"]) {
List(uid: "subcategory", clocator: [tag: "td", class: "sidebar"], separator: "div") {
Container(uid: "{all}") {
TextBox(uid: "title", clocator: [tag: "div", class: "sub_cat_title"])
List(uid: "links", separator: "p") {
UrlLink(uid: "{all}", clocator: [:])
}
}
}
}
ui.StandardTable(uid: "GT", clocator: [id: "xyz"], ht: "tbody"){
TextBox(uid: "{header: first} as One", clocator: [tag: "th", text: "one"], self: true)
TextBox(uid: "{header: 2} as Two", clocator: [tag: "th", text: "two"], self: true)
TextBox(uid: "{header: last} as Three", clocator: [tag: "th", text: "three"], self: true)
TextBox(uid: "{row: 1,column -> One} as A", clocator: [tag: "div", class: "abc"])
Container(uid: "{row: 1,column -> Two} as B"){
InputBox(uid: "Input", clocator: [tag: "input", class: "123"])
Container(uid: "Some", clocator: [tag: "div", class: "someclass"]){
Span(uid: "Span", clocator: [tag: "span", class: "x"])
UrlLink(uid: "Link", clocator: [:])
}
}
TextBox(uid: "{row: 1,column -> Three} as Hello", clocator: [tag: "td"], self: true)
}
元數據 first、數字、last 指定 header 位置。{row: 1,column -> One} as A 表示 UI 元素(TextBox)處於第一行,與 header "One" 同列。測試代碼乾淨:
getText "GT.A"
keyType "GT.B.Input",input
click "GT.B.Some.Link"
waitForPageToLoad 30000
作者簡介
方劍,喬治亞理工學院電子與計算機工程博士,某 IT 公司高級軟體工程師,致力於企業級應用軟體設計實現,Tellurium 自動化測試框架創建者。