Robot Framework + Selenium2Library自動化測試系列(11) - 類型轉換和List:工時表查詢3

上一篇文章我們用工時記錄的xpath個數驗證了搜索結果和實際結果是否匹配。但是,光檢查工時表里的記錄數目對不對還不夠,考慮這么一種情況:萬一數目匹配,但最后顯示的記錄里多了一個其它員工的記錄怎么辦?假設我搜索Tester One返回了如下結果:

多了一個Tester Two的記錄。Tester One的xpath數目與在Excel表中的期望結果都是2,但實際搜索出來的總工時數是3。所以,我們還需要進一步對每一條數據進行驗證。

搜索欄中輸入Tester One先拿到每條記錄:

我的思路是逐行讀取每條記錄,每條有9列數據,把它們讀到list里然后再與輸入數據進行比較。

既然是逐行讀取,那肯定要用循環語句。我們已經在登錄那個例子中讀文件的操作里使用到了for語句。現在介紹一種更容易理解的寫法。如果用java寫For循環語句怎么寫?是不是for(int i = 0; i < count; i++)?這里的寫法差不多,看下圖,在Search Timesheet By Employee Name中繼續寫第二個檢查點:

第9行寫個comment,告知開始進行第二個檢查點的測試。第10行就是for循環的寫法,只是這里我把循環變量$i的初始值設成1。注意,雖然第5列寫的是${timesheetCount}+1,可實際最后一次循環的值是${timesheetCount}。如果這里你寫${timesheetCount},那循環就進行到${timesheetCount}-1就停了,永遠在前一個停,這里請注意。

很顯然,由于${timesheetCount}等于2,我們的循環語句只會循環兩次,每次拿出一條記錄。上篇文章已經用firebug找到了工時記錄的xpath了:

它們的xpath分別為:

第一條://table/tbody/tr[1]

第二條://table/tbody/tr[2]

用xpath可以訪問數據:比如第一條數據的訪問結果如下:

如果這里沒看懂的朋友請再復習下xpath的相關知識。沒問題后我們在ObjectRepository -> Timesheet.html中為xpath聲明變量${locTSTable_Records_Fields}:

這里我在xpath后面加了/td,以便一會兒訪問數據。又寫了個可替換的||ROW NUMBER||,因為第一次循環||ROW NUMBER||是1,第二次是2,以此類推:

第13行就是替換過程,${i_string}是${i}的字符串形式。上篇文章我們有一步避免了使用轉換,這次很不幸,躲不過去了。${i}在循環里默認是整型的,是integer,而Replace String不能用整型替換字符串,所以要在第12行轉換一下。轉換操作的關鍵字是Convert To String,參數就是一個integer,轉換完可以賦給一個字符串變量。在API文檔上我們還能看到ConvertTo Integer,Convert To Boolean等等,其實都是為了轉化設計的。

第13行第二列局部變量${locTSTable_Records_Fields_Row}存的是${locTSTable_Records_Fields}替換后的字符串,它的值在第一次循環執行到這里時應該是//table/tbody/tr[1]/td,看到這兒你就知道為什么我當時把${i}的初值設置成1了吧?可以通過循環變量把tr的角標索引巧妙賦值,因為每次循環讀一條記錄,其實就是讀一條xpath。好,現在我要把這條記錄里的每列數據都讀入到list里,然后一個一個和搜索關鍵字Tester One對比,看有沒有一樣的。如果有就證明工時記錄里包含關鍵字,測試通過,反之則失敗。有人說了,你傻啊,直接對比第一列姓名不就完了么?是這樣,有時候搜索功能并不在乎數據出現的位置,只要出現就算搜索成功。再一個,我也通過這么一種較復雜的驗證過程給大家講講如何聲明和使用list。

右擊Pages -> Timesheet.html創建Keyword“Get All Timesheet Fields”,用來寫把數據讀到list的過程。它有一個參數叫${locTSTable_Records_Fields_Row_Current},這個參數指的是當前的某一行,也就是某個tr。如果這是第一次循環,傳進來的值就是//table/tbody/tr[1]/td。

如下圖,第1行創建了一個空的list,之前說過,list的前綴是“@”,而創建list的關鍵字是Create List。如果想取每列數據還要用For循環語句進行遍歷,每條工時記錄是9列,我們完全可以用9+1=10作為循環終值。可這樣不好,因為如果開發人員以后每次加了一列或是減了一列那我們還得重新修改函數,很不方便,也不靈活。最好讓程序自動得知當前有多少列,不要把它寫死。所以第2行我還是用Get Matching Xpath Count,得到這條記錄/tr的xpath里有多少個td,也就是多少列,賦給一個叫${fieldCount}的局部變量:

循環過程如下3-6步:

再看一遍這7列數據作為提示:

字有點小,不過還是能看清楚的。這個例子中循環需要進行7次,但終值為8,所以在第三行用${fieldCount}+1表示。總共7個數據。看到這里你會發現什么?我們還可以用循環變量${j}當td的角標索引。當前參數是//table/tbody/tr[1]/td,我們需要做的就是第4行的連接字符串。這里我們和上次連接字符串的情況不同,td和[${j}]之間不需要空格,所以需要加個Separator=來區分。不明白的Ctrl+ALT+Space打開API就懂了。如果這是第一次循環,第4步結束的結果就應該是${locTSTable_Records_Fields_Column_Current} = //table/tbody/tr[1]/td[1]。第5行就是用Get Text關鍵字對xpath進行簡單的取值,第一次循環得到“Tester One”。最后一步,得到的數據放到咱們之前聲明的list中,用到的關鍵字是Append to List。這個關鍵字屬于一個名叫Collections的library,用之前請先引入ApplicationSpecific.html:

Append To List接受兩個參數,第一個是目標list,這里的用${fieldList}表示;是第二個是要放進list的數據變量。有人問為什么${fieldList}不寫成@{fieldList},它不是個List嗎?注意,List只有在聲明和作為返回值的時候才用“@”表示,賦值過程把它當成一個變量來寫。

7次循環過后,數據全部進入list。然后返回list到之前的函數,我直接在Return Value那里寫了:

List返回之后就簡單了,直接看看包不包含搜索關鍵字唄,用的語句是List Should Contain Value。在Search Timesheet By Employee Name中調用Get All Timesheet Fields:

List Should Contain Value也是個布爾函數,判斷列表里有沒有目標數據。它有兩個參數,列表以及目標數據。有的話測試通過,沒有測試失敗。

寫完這一步,整個程序的脈絡就清晰多了。首先對記錄進行循環,每讀取一條記錄,就在第13行調用Get All Timesheet Fields傳入當前記錄的xpath拿到所有列,然后通過對列的循環取值放入list,最后看list里有沒有要搜索的文字。雖然復雜,但一切看起來都正確。

到現在只是做完搜索Tester One的,那另外三個員工呢?還是讀文件那些東西,每次從文件里讀一個員工姓名以及期望的工時數目,然后調用Search Timesheet By Employee Name執行剩下的搜索操作。再建一個Keyword叫Search Timesheet作為這一系列操作的總函數,代碼如下:

最后回到TCTIMES-1,在第7行和第8行加上總函數Search Timesheet,這個test case就寫完了:

運行TCTIMES-1,測試通過。這就是關于工時表的第一個Test case,之后我會再帶著大家看一個例子。

這篇文章的源代碼在[Test10](https://github.com/cslm/cslm.robotframework/tree/master/Test10)里。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容