歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 使用 Python 在 Linux 上實現一鍵回歸測試

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

日期:2017/3/1 9:40:48   编辑:Linux編程

在 Linux 平台上進行大型項目開發過程中,測試人員需要定期(通常是每天),從代碼庫中更新代碼、編譯版本、運行全部測試腳本、收集並發布測試結果。這個過程既繁瑣又耗時。通常我們希望能在下班後能自動完成這一系列操作,本文將講述如何利用 Python 腳本輕松實現這一過程。

從代碼庫遷出代碼 ---- pexpect 的使用

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

清單 1. 用 pexpect 遷出代碼庫代碼
try:
 chkout_cmd = 'cvs co project_code' #從代碼庫遷出 project_code 的內容
 child = pexpect.spawn(chkout_cmd)
 child.expect('password:')
 child.sendline('your-password') #請替換"your-password"為真實密碼
 child.interact()
 except:
        pass #忽略遷出代碼中的錯誤

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

《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm

《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm

Python腳本獲取Linux系統信息 http://www.linuxidc.com/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm

編譯代碼和運行測試腳本 ---- subprocess 的使用

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

編譯代碼

清單 2. 用 subprocess 編譯代碼
build_cmd = 'build_command_for_your_code' #請在這裡配置編譯命令
 build_proc = subprocess.Popen(build_cmd, stdin=None, stdout=None, stderr=None, shell=True)
 build_proc.wait() #等待子進程結束
    assert (0 == build_proc.returncode)

在一些系統中我們編譯代碼采用的是腳本文件(如 shell 腳本),那麼我們仍然可以如下命令來完成代碼編譯工作。

清單 3. 用 subprocess 的 call 函數執行腳本文件
    subprocess.call(["code_compile.sh"])

運行測試腳本

在編譯完成代碼之後,我們同樣可以調用 subprocess.Popen 來創建子進程運行測試用例。如果測試人員的測試用例已經寫成了測試例腳本,我們則可以用 subprocess.call()來執行測試例腳本文件,代碼實現就不再贅述。有些系統會直接把詳細日志輸出到屏幕上,那麼我們可以用重定向命令"2>&1"把屏幕輸出寫文件。

清單 4. 用重定向命令把輸出寫文件
       ut_cmd = 'Your_unit_test_command  2>&1 > %s' %self.debug_log #debug_log 定義在__init__函數中,用來存儲詳細日志

測試結果存儲和發布 ---- XML 解析

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

清單 5. 共享目錄結構
    SharedFiles
    ├── Sprint10-20130823121500
    │   ├── log.txt
    │   └── summary
    ├── Sprint10-20130826152715
    │   ├── log.txt
    │   └── summary
    ├── Sprint10-20130828165235

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

清單 6. Sprint.xml 文件結構
<sprint-schedule>
 <min-sprint>10</min-sprint>
 <max-sprint>20</max-sprint>
 <sprint10>20130814</sprint10>
	 <sprint11>20130828</sprint11>
 … … 
 <sprint19>20131218</sprint19>
 <sprint20>20140101</sprint20>
    </sprint-schedule>

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

清單 7. xml 解析代碼
cur_date = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time())) # 首先獲取當前系統日期

xmldoc = minidom.parse(xml_file) 
 min_num_node = xmldoc.getElementsByTagName('min-sprint')[0]
 min_num = int(min_num_node.firstChild.data) #解析出迭代開發周期的起始周期

 max_num_node = xmldoc.getElementsByTagName('max-sprint')[0]
 max_num = int(max_num_node.firstChild.data) #解析出迭代開發周期的終止周期

    cur_num = min_num
#遍歷所有迭代周期,取出當前迭代周期的開始時間和當前的系統時間對比,從而確定當前位於哪一個迭代周期。
 while cur_num <= max_num : 
 node_name = 'sprint' + str(cur_num)
 cur_node = xmldoc.getElementsByTagName(node_name)[0] 
 sprint_date = cur_node.firstChild.data
 if sprint_date < cur_date[0:7]: 
 cur_num = cur_num + 1
 else:
            break

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

清單 8. 日志存儲代碼
log_dir = self.share_dir + '/Sprint' + str(cur_num) + '-' + cur_date #share_dir 為共享目錄,定義在初始化函數中
 os.mkdir(log_dir)
 os.system('mv %s %s' %(self.debug_fullname, log_dir)) #debug_fullname,詳細日志文件名(含目錄),定義在初始化函數中
    os.system('mv %s %s' %(self.sum_fullname, log_dir)) #sum_fullname,匯總日志的全路徑文件名,定義在初始化函數中

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

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-08/105599p2.htm

Copyright © Linux教程網 All Rights Reserved