使用 Python 在 Linux 上實現一鍵迴歸測試

發表於2017-11-10

從程式碼庫遷出程式碼 —- pexpect 的使用

測試人員從程式碼庫(例如 CVS )遷出程式碼的過程中,需要手動輸入訪問密碼,而 Python 提供了 Pexpect 模組則能夠將手動輸入密碼這一過程自動化。當然 Pexpect 也可以用來和 ssh、ftp、passwd、telnet 等命令列進行自動化互動。這裡我們以 CVS 為例展示如何利用 Pexpect 從程式碼庫遷出程式碼。

清單 1. 用 pexpect 遷出程式碼庫程式碼

在清單 1 中,我們用命令”cvs co project_code”從程式碼庫中遷出了 project_code 的內容,我們也可以用該命令來更新已經遷出的程式碼。只需要將命令”cvs update” 傳給類 pexpect.spawn()即可,詳細的實現請參考程式碼檔案。這裡 interact()函式是必須的,用來在互動的方式下控制該子程式。有時程式碼庫中會存在目錄不一致行情況,遷出程式碼會因報錯終止,所以需要異常處理(try … execpt)來忽略該錯誤。

編譯程式碼和執行測試指令碼 —- subprocess 的使用

測試人員獲取最新的程式碼之後,就要對原始碼進行編譯,並且執行測試用例。Python 語言提供了多種方法如 os.system()/os.popen()來執行一條命令,這裡我們推薦用 subprocess 模組來建立子程式,完成程式碼編譯和執行測試用例。因為 subprocess 支援主程式和子程式的互動,同時也支援主程式和子程式是同步執行還是非同步執行。由於本文中的各個功能模組有都先後依賴關係,所以全部採用的是主程式和子程式同步模式執行。

編譯程式碼

清單 2. 用 subprocess 編譯程式碼

在一些系統中我們編譯程式碼採用的是指令碼檔案(如 shell 指令碼),那麼我們仍然可以如下命令來完成程式碼編譯工作。

清單 3. 用 subprocess 的 call 函式執行指令碼檔案

執行測試指令碼

在編譯完成程式碼之後,我們同樣可以呼叫 subprocess.Popen 來建立子程式執行測試用例。如果測試人員的測試用例已經寫成了測試例指令碼,我們則可以用 subprocess.call()來執行測試例指令碼檔案,程式碼實現就不再贅述。有些系統會直接把詳細日誌輸出到螢幕上,那麼我們可以用重定向命令”2>&1″把螢幕輸出寫檔案。

清單 4. 用重定向命令把輸出寫檔案

測試結果儲存和釋出 —- XML 解析

我們的專案採用敏捷開發,為了更好的反應敏捷開發週期,我們希望儲存日誌的目錄名不但能夠指明的具體日期,同時也能反映敏捷(迭代)開發階段,這樣相關人員在檢視相應目錄中的日誌時,能夠清楚的明白日誌實在在哪個迭代週期的哪一天產生的。本文使用檔案 summary 作為執行測試用例後生成的彙總日誌,用檔案 log.txt 用來儲存詳細日誌。如下圖所示,在共享目錄 SharedFiles 中儲存了一些列迭代週期中的日誌。

清單 5. 共享目錄結構

為了能夠讓目錄名反映敏捷開發週期,我們需要自己定義一個配置檔案(txt 或 xml 均可)。由於 Python 已經很好的支援了 XML 解析,並且 XML 檔案作為配置也是當前的流行趨勢。本文就以 XML 解析為例進行說明。本文使用的 XML 檔名是 Sprint.xml,清單 6 是該 xml 的概要內容

清單 6. Sprint.xml 檔案結構

關於 xml 解析 Python 提供了多種方法。本文采用 minidom 對 xml 檔案進行解析,清單 7 是相關處理程式碼。

清單 7. xml 解析程式碼

這樣 cur_num 就指向了當前的迭代開發週期。然後,我們就可以根據當前日期和開發階段建立對應的日誌目錄名了,最後把執行結果儲存到該目錄下,參見清單 8 實現。

清單 8. 日誌儲存程式碼

關於測試結果的釋出,本文並沒有把測試結果以自動化的形式傳送郵件,而是手動在每個開發週期結束時,群發郵件給相關人員。或者在驗證失敗後,通知相關的開發人員,這是由於作者所在團隊專案程式碼提交頻率不是很高。在更大型的專案中,往往需要增加自動傳送郵件的功能,相關實現本文不再贅述。

也談介面設計 —- getopt 的使用

在日常的測試過程中,我們並不是每次都要遷出程式碼,編譯程式碼,執行測試用例和收集測試結果。這樣就需要我們能夠有選擇的執行部分程式功能,例如只執行測試用例和收集結果。這裡我們提供了 4 個執行選澤:

選項 1:遷出程式碼–>編譯版本–>執行測試用例–>收集測試結果

選項 2:更新程式碼–>編譯版本–>執行測試用例–>收集測試結果

選項 3:編譯版本–>執行測試用例–>收集測試結果

選項 4:執行測試用例–>收集測試結果

當然我們還需要提供幫助資訊,以方便不熟悉該指令碼實現的人員使用。python 也提供了 getopt 模組讓我們輕鬆實現上述功能。實現程式碼參見清單 9

清單 9. 命令列寫解析程式碼

如果我們在執行的過程中想中斷(如利用 Ctrl+C)一鍵迴歸測試程式的執行時,有時我們會發現雖然主程式已經被終止,但子程式仍在執行。我們能否在中斷主程式的同時也中斷子程式呢?答案當然是肯定的,我們可以用訊號處理函式捕獲訊號(如捕獲 Ctrl+C 產生的中斷訊號),然後在顯式終止對應的子程式。這裡就需要我們在建立子程式的時候,先儲存子程式 ID,當然把子程式 ID 儲存到初始化函式中,是個不錯的選擇,清單 10 是相關實現。

清單 10. 訊號處理程式碼

這裡我們需要在初始化函式中註冊要捕獲的訊號,並且建立成員變數用來儲存子程式的 ID,詳細實現請參見清單 11。

基於物件的設計 —- class 的使用

最後終於輪到 class 登場了,提到 class 我們就不能不談建構函式(初始化函式)和解構函式。之前我們多次提到初始化函式,初始化函式允許我們定義一些變數,這些變數在整個類物件的生存週期內均有效。由於本文沒有向系統申請資源,就再不定義解構函式了。

清單 11. 初始化處理程式碼

通常我們不需要太關注設計風格,只要 Python 指令碼能完成我們的測試要求即可。對於較小的指令碼,幾條 Python 指令順序執行即可。為了模組功能複用和可讀性,我們通常會把功能模組封裝成函式。本文將實現的所有函式都封裝到一個類中,使得該指令碼更加一體化。

清單 12. class 框架結構程式碼

結束語

Python 語言是一個易學易用的指令碼語言,筆者沒有多久的 Python 開發經驗,不過其他語言有的功能在 Python 中大都可以找到對應的實現,這也是筆者能夠在很短的時間內完成該測試指令碼的原因。因此,筆者把該語言和使用該語言完成一鍵迴歸測試介紹給大家,希望對大家有所幫助。正像筆者說的其他語言有的功能在 Python 中大都可以找到對應的實現,同樣,如果大家對某一種特定的指令碼語言或者開發語言特別熟悉,也完全可以採用所熟悉的語言來完成一鍵迴歸測試的工作。


下載資源


相關主題


相關文章