在某些項目中,報表比對是測試的一大內容。比如,在某版本下生成baseline report作爲標準答案,新代碼進來後,再次生成report,跟baseline report作比較,確保改動沒有引入差異。報表多以excel文件形式導出,用工具進行excel文件比對十分有用。
Apache POI 是一個很好的處理microsoft office documents的java庫,通過它可以讀寫word文檔,讀寫Excel文件,讀寫power point文件,還有visio等等,功能十分強大。
Apache Poi 官方文檔請見鏈接link。
這裏,我建了一個maven項目,使用了poi裏面的xssf讀.xlsx格式的excel文件(如果想要操作.xls格式的excel文件,則必須使用poi裏面的hssf),然後比對source和target文件的差異,並將差異輸出。同時使用了JUnit進行代碼的單元測試。
工程已Push至github link。Jar包也已release至github link。
使用如下命令運行jar包:
java - jar excelComparison.jar sourceExcelPath targetExcelPath
代碼結構
代碼結構如下圖所示:
- SheetData類存儲sheet數據:sheet名,sheet有哪些列,sheet的column index與列名的映射關係(Map),最後是sheet的數據(List < List < String> >)
- WorkbookData類則是有若干個SheetData組成(List < SheetData >)
- Utility包裏的ExcelUtility類放了用來讀excel的靜態方法
- 最後DifferenceEngine類比較sheet數據並輸出差異
代碼運行結果
代碼運行結果如下所示,按照sheet輸出差異,sheet name取自source excel,Discrepancy summary將所有有差異的列及列名彙總起來(列名取自source excel),接下來按行將source和target單元格不一致的輸出
Sheet Name: [Sheet 1]
Discrepancy summary: Column A(title), Column C(album), Column D(isFound)
Row 7
Cell A7: source -- , target -- Title that not in source
Cell C7: source -- star, target -- @*&
Cell D7: source -- , target -- 0
Row 8
Target row null...
Row 9
Target row null...
Row 10
Target row null...
----------------------------------------------------
Sheet Name: [Sheet 2]
Discrepancy summary: Column A(555)
Row 3
Cell A3: source -- , target -- 777
----------------------------------------------------
Source excel does not have sheet 3
測試用例
已經在如下場景測試過工具,運行結果無誤:
- 普通情況下source和target sheet/行/列數量都一致時,source和target的差異正確識別輸出
- source cell或者target cell爲空時,差異正確識別輸出
- source sheet和target sheet行數不一致時,工具正常運行並輸出
- source sheet和target sheet列數不一致時,工具正常運行並輸出
- source和target的sheet數量不一致,工具正常運行並輸出
工具使用前提條件
要想工具正常運行,必須滿足以下條件:
- 必須是2007版的excel
- excel文件裏的列名不爲空
- source excel和target excel裏面的sheet必須是正確對應的,工具不會按照sheet name去匹配它們
- source excel和target excel裏的列名必須是正確對應的,工具不會智能去匹配它們
待完善的點
目前所有單元格都是按照String進行嚴格比對的。有些時候如果數值差異在一定範圍內也可以接受的話,工具則處理不了。後續可以添加配置文件,由用戶自行配置各個列的格式(String,或者value,或者date等等),以及value的tolerance