上兩篇我們結(jié)合數(shù)據(jù)驅(qū)動討論了page object模型,分別用了Excel和csv進(jìn)行演示。其中Excel參與的演示項目叫SeleniumExcelDataDrivenPOM,現(xiàn)在打開這個項目,看Test.java文件:
雖然我們已經(jīng)把object,測試步驟和驗證過程都加到了LoginPage.java中,可現(xiàn)在這個主類還是很長。關(guān)鍵問題不是長,而是非常冗余。比如我現(xiàn)在再寫一個關(guān)于登錄模塊的用例,比如驗證登錄失敗吧,除了測試步驟和驗證過程不一樣之外,你要把開頭的driver初始化,打開網(wǎng)頁,最大化網(wǎng)頁,讀取測試數(shù)據(jù)源等等等等重寫一遍。有多少個測試用例你就得寫多少遍這些步驟,非常麻煩。所以,我們需要把一個更加標(biāo)準(zhǔn)的系統(tǒng)來簡化我們的工作量。從這篇開始,我就帶著大家繼續(xù)一點點改進(jìn)我們的數(shù)據(jù)驅(qū)動測試系統(tǒng),搭建一個框架雛形。
所謂的自動化測試框架,我理解就是一個標(biāo)準(zhǔn)化的測試系統(tǒng),其特征是一致、復(fù)用、擴(kuò)展性強(qiáng):
我先不解釋這幾個詞,大家可以隨著程序的改進(jìn)慢慢體會這幾個詞。其實市面上已經(jīng)有不少自動化的測試框架,很多還是開源的,比如Robot Framework等等,有的公司用現(xiàn)成的框架,有的公司在其基礎(chǔ)上擴(kuò)展改進(jìn)。不得不說現(xiàn)在純寫代碼搞框架已經(jīng)是越來越少了,因為維護(hù)起來有些困難。這一點隨著程序改進(jìn)大家也能慢慢體會。有些人問那為什么你不直接討論現(xiàn)成框架呢?知其然知其所以然,之所以我一定要帶著各位一點一點改進(jìn),嘗試搭建框架過程,就是想讓大家熟悉一個自動化測試系統(tǒng)的內(nèi)部結(jié)構(gòu),便于以后大家理解其它的現(xiàn)成框架,同時也鍛煉了寫代碼的能力,有助于未來在現(xiàn)成框架的基礎(chǔ)上進(jìn)行小規(guī)模擴(kuò)展。當(dāng)然,我也分別寫了Robot Framework,TestNG,和Cucumber的教程供大家學(xué)習(xí)。不過我強(qiáng)烈建議你們先別走,先跟著我把框架的結(jié)構(gòu)搞清楚:)
我們開始改,因為讀取數(shù)據(jù)源大多數(shù)測試用例都需要,所以我先把讀取數(shù)據(jù)源的步驟封裝在一個方法里,并寫到另一個類中。從現(xiàn)在開始我也要規(guī)范包名,之前介紹過包名的規(guī)范,用的是“所在公司的互聯(lián)網(wǎng)域名.公司名.項目名.功能名”這個格式,我新增一個包命名為叫com.testalliance.hrsystem.test,里面專門放測試過程中需要的一些前提或條件:
然后在該包下創(chuàng)建一個叫Test.java的文件,把讀取數(shù)據(jù)源的步驟放進(jìn)去。因為com.test里已經(jīng)有一個叫Test.java的文件了,一個項目里最好不要有兩個同名文件,把com.test改成com.testalliance.hrsystem.managers(為什么起名為managers一會兒再說),然后它下面的Test.java改成TestRunner.java:
讀取數(shù)據(jù)源的步驟封裝在Test.java的getTestData()方法中:
第33行我修改了一下,以前testDataCell位置是直接寫死了兩列,但這里我動態(tài)求了列數(shù),因為有些用例的測試數(shù)據(jù)Excel表格可能是兩列,有些可能是多列,我們不好把握。那么現(xiàn)在TestRunner就可以簡化一些了,直接調(diào)用方法。這樣,以后寫其它test case需要測試數(shù)據(jù)時直接調(diào)用就行了,唯一注意的地方就是傳入的文件不一樣罷了。還一點,以前我們用的都是文件的絕對路徑,這回我改成了相對路徑。System.getProperty("user.dir")返回的是項目的路徑,你只需要在后面加上剩余的部分就行了。這么做的好處就是一不用寫大長串,二如果項目的路徑改了你也不用修改,System.getProperty("user.dir")會自動定位到新的項目。我們以后最好使用相對路徑。
順帶著把另外兩個包名也改過來:
接下來就該把另一部分重復(fù)的代碼挪出去了,也就是driver初始化,打開網(wǎng)頁,最大化網(wǎng)頁,關(guān)閉driver這幾步,每個測試用例都會用到。仔細(xì)想一下,初始化driver屬于一個測試過程的準(zhǔn)備步驟,而關(guān)閉driver屬于掃尾步驟,嚴(yán)格說它們都是在控制管理driver實例,那可不可以單獨創(chuàng)建一個管理driver的類,然后把它們也封裝到相應(yīng)的方法里呢?我們在com.testalliance.hrsystem.managers中新建一個類叫DriverManager.java:
然后粘貼如下代碼:
初始化和關(guān)閉driver分別封裝在preTest()和cleanUp()里。同樣,未來使用它們時直接調(diào)用即可。打開網(wǎng)頁和最大化網(wǎng)頁這兩步其實可以放在LoginPage.java中,因為我們一般都把網(wǎng)址當(dāng)作是一個特殊的object并寫在object repository中。打開loginPage.properties,把網(wǎng)址填進(jìn)去:
然后把這兩步寫入LoginPage.java:
回到TestRunner.java中,對它們分別調(diào)用:
現(xiàn)在問題來了,TestRunner.java里面目前只有一個測試用例,如果我想再加一個呢?TestRunner.java已經(jīng)是主類了,我總不能再繼續(xù)追加吧?那所有的用例豈不都寫在一起了?所以,測試用例也要挪出去。我再建一個包com.testalliance.hrsystem.tests.login,目的是裝所有和login相關(guān)的測試用例。再新建一個類叫TCLogin1.java(同時也把存數(shù)據(jù)的文件名稱改成TCLogin1.xlsx):
把TestRunner.java里面的內(nèi)容全部挪到TCLogin1.java里,注意把路徑中的文件名也改過來:
封裝的方法叫test(),這樣我們只用在TestRunner.java中直接實例化TCLogin1并調(diào)用test()方法即可:
這篇的改進(jìn)就到這兒。如果這時你再給登錄模塊添加一個測試用例,起名為TCLogin2.java,那它也可以被TestRunner類調(diào)用、控制,有幾個管幾個。TestRunner類就好像一個中控一樣管理著測試用例的調(diào)度:
這下明白為什么把TestRunner.java和DriverManager.java所在的包叫做managers了吧?一個管理測試用例,一個管理其核心driver。下一篇我們新增幾個登錄模塊的用例,大家再體會一下。
這篇文章的源代碼在SeleniumExcelDataDrivenFrame1項目里邊。