上幾篇利用數(shù)據(jù)驅(qū)動配合POM搭建了一個自動化測試框架雛形,其實(shí)目前已經(jīng)滿足我們的需要了。但除了數(shù)據(jù)驅(qū)動之外,測試界還有一種廣泛利用的驅(qū)動方式,叫做關(guān)鍵字驅(qū)動肺孤。這篇我們就討論一下它罗晕。
先說什么是關(guān)鍵字济欢。在寫測試程序時,我們免不了要對頁面上的元素進(jìn)行操作小渊,比如輸入法褥、點(diǎn)擊、刷新等等酬屉。之前我們都是以代碼的形式表現(xiàn)這些操作的半等,輸入是調(diào)用sendKeys()方法,點(diǎn)擊是click()呐萨,刷新是refresh()杀饵。通常執(zhí)行一個test case經(jīng)常需要調(diào)用這幾個方法。比如我們還是用示例網(wǎng)站演示一下登錄步驟谬擦,測試步驟如下:
1. 打開http://cslm-test.com/hrsystem/index.php切距;
2. 輸入用戶名"1001";
3. 輸入密碼"123"惨远;
3. 點(diǎn)擊登錄按鈕(斷言點(diǎn):home按鈕出現(xiàn)在home.php頁)谜悟;
4. 退出(斷言點(diǎn):登錄按鈕出現(xiàn)在index.php頁)。
程序如下:
sendKeys()和click()各調(diào)用兩次北秽。這還是一個很簡單的測試程序葡幸,試想如果測試步驟足夠多,那我們會一直不停地來回使用它們贺氓。有人就覺得煩了蔚叨,他們想如果每種操作只寫一遍就好了,這樣只要根據(jù)不同情況傳入不同的參數(shù)就行掠归。比如上面例子中的兩次輸入操作缅叠,它們都用sendKeys(),只不過參數(shù)不同虏冻,一個是員工代號肤粱,一個是密碼。這兩個參數(shù)的元素位置不同厨相,使用的測試數(shù)據(jù)也不同:
注意劃紅線的部分领曼,咱們介紹POM那篇說過,我們用object來表示網(wǎng)頁元素的定位過程蛮穿,所以我就也把object標(biāo)上了庶骄。除了object和測試數(shù)據(jù)不同,定位器也有可能不一樣践磅,只不過這個例子中恰好都用id定位器单刁。看出點(diǎn)端倪來了吧府适,只要根據(jù)不同情況替換這三個地方的東西就可以了羔飞》握粒總結(jié)一下,一個相同點(diǎn):它們都是輸入操作逻淌;三個不同點(diǎn): 定位器么伯,object,和測試數(shù)據(jù)卡儒。
如果把這一個相同點(diǎn)三個不同點(diǎn)提取出來放在一個文件里并寫成程序田柔,是不是可以用下面這個格式表達(dá)呢?
我們的做法是逐行掃描文件骨望,如果第一列是“輸入操作”硬爆,則把后三列的值拿出來拼到下面的driver.findElement()語句中,如果不是則跳過锦募。很明顯摆屯,這兩行都滿足條件,第一行讀完后輸入了員工代號糠亩,第二行讀完后輸入了密碼虐骑。整個過程中我們把重復(fù)調(diào)用sendKeys()的過程替換成了讀文件的過程,然后根據(jù)情況傳參數(shù)而已赎线,這樣driver.findElement(...).sendKeys()只用寫一遍廷没。是不是我們的目的達(dá)到了?文件中第一列的條件垂寥,也可以說指令颠黎,就是所謂的關(guān)鍵字。
這兩行數(shù)據(jù)順序不能亂滞项,顛倒了就變成先輸密碼再輸員工代碼了狭归,就不對了。所以文判,設(shè)計一個關(guān)鍵字驅(qū)動的文件一定要遵循test case的執(zhí)行順序过椎。我現(xiàn)在把例子中所有的操作都變成關(guān)鍵字寫在文件里:
從第二行打開瀏覽器,一直到最后一行的驗證戏仓,每一行都是一個操作疚宇,而且它們都按照順序?qū)懴聛怼W⒁馍脱辏皇敲總€關(guān)鍵字都需要后面三列敷待,有些操作比如像點(diǎn)擊,就不需要最后一列測試數(shù)據(jù)仁热,因為不需要輸入任何東西榜揖;打開最大化瀏覽器窗口這些操作甚至什么參數(shù)都不用。設(shè)計文件時要具體步驟具體分析。按照這種思路举哟,我們可以把它變成代碼:
看這段偽代碼钳幅。在一行一行讀文件時,如果當(dāng)前行的第一列關(guān)鍵字是“Input Text”炎滞,那就調(diào)用enter方法,該方法傳遞四個參數(shù)诬乞,后三個正好是文件后三列的數(shù)據(jù)册赛,也就是定位器、object震嫉、測試數(shù)據(jù)森瘪。因為定位器可能是8種中的任意一種,所以需要用條件語句再進(jìn)行判斷票堵。同理扼睬,如果當(dāng)前行的第一列是別的關(guān)鍵字,那就調(diào)用別的相關(guān)方法悴势〈坝睿看到了吧,這里面最關(guān)鍵的就是關(guān)鍵字與元素操作的匹配:
所以特纤,最終程序如下:
第50行開始對文件進(jìn)行逐行掃描军俊,每次取一行查看第一列,我用變量keyword表示捧存。如果keyword匹配下面任意一個關(guān)鍵字粪躬,則調(diào)用相關(guān)操作的方法。所有操作方法在第117行到第165行昔穴。注意第168行镰官,由于每個關(guān)鍵字觸發(fā)的操作都需要判斷定位器,所以我把定位器判斷的過程單獨(dú)提出來放到getObject()方法中吗货,返回元素對應(yīng)的object泳唠。執(zhí)行一下:
這就是一個簡單的關(guān)鍵字驅(qū)動示例,你可以用把自動化測試中任何一個操作寫成一個關(guān)鍵字卿操【欤看完這個例子,想必大家也明白了關(guān)鍵字驅(qū)動害淤,原理無非是把元素操作與關(guān)鍵字匹配扇雕,然后根據(jù)test case的步驟在文件中羅列需要的關(guān)鍵字,最后根據(jù)不同的操作分別處理窥摄。牢記兩個關(guān)鍵點(diǎn):第一镶奉,用關(guān)鍵字驅(qū)動時文件中裝的是test case,關(guān)鍵字排列順序要與測試步驟一致;第二哨苛,關(guān)鍵字與元素操作匹配鸽凶。
討論數(shù)據(jù)驅(qū)動時還介紹了page object model,關(guān)鍵字驅(qū)動也可以用POM設(shè)計模式建峭。我們給它改一下玻侥。首先項目結(jié)構(gòu)如下:
先把元素的object提取出來寫在LoginPage.properties中:
然后把讀取object、定位器判斷亿蒸、操作方法都挪到LoginPage.java中:
主類Test.java中只剩下讀取關(guān)鍵字和關(guān)鍵字匹配過程:
通過實(shí)例化LoginPage得到的對象調(diào)用相關(guān)方法完成test case凑兰。再次執(zhí)行一下:
以上就是關(guān)鍵字驅(qū)動的介紹,原理就是把元素操作與關(guān)鍵字匹配边锁,然后根據(jù)test case的步驟在文件中羅列需要的關(guān)鍵字姑食,最后根據(jù)不同的操作分別處理。數(shù)據(jù)驅(qū)動和關(guān)鍵字驅(qū)動各有各的特點(diǎn)茅坛,數(shù)據(jù)驅(qū)動通過把測試數(shù)據(jù)從test case中分離避免了test case的重寫音半,而關(guān)鍵字驅(qū)動則通過把元素操作與關(guān)鍵字匹配從而減少了測試步驟了重寫,代碼量大大下降贡蓖。市面上用得比較多的測試框架就是基于關(guān)鍵字驅(qū)動設(shè)計的曹鸠,有些甚至不用你寫代碼就可以使用,因為每一個關(guān)鍵字背后的代碼人家都替你寫好了斥铺。比如有一個叫Robot Framework的框架就能實(shí)現(xiàn)這點(diǎn)物延,而且還很受歡迎。如果感興趣請看我的Robot Framework + Selenium2Library文集繼續(xù)仅父。
這篇文章的源代碼是SeleniumExcelKeywordDrivenPOM項目叛薯。
本篇知識點(diǎn)及注意事項:
1. 關(guān)鍵字驅(qū)動測試的原理就是把元素操作與關(guān)鍵字匹配,然后根據(jù)test case的步驟在文件中羅列需要的關(guān)鍵字笙纤,最后根據(jù)不同的操作分別處理耗溜。
2. 用關(guān)鍵字驅(qū)動時文件中裝的是test case,關(guān)鍵字排列順序要與測試步驟一致省容。