欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python移動(dòng)測試開發(fā)subprocess模塊項(xiàng)目實(shí)戰(zhàn)

 更新時(shí)間:2022年07月21日 16:53:06   作者:opentest-oper@#  
這篇文章主要為大家介紹了Python移動(dòng)測試開發(fā)subprocess模塊項(xiàng)目實(shí)戰(zhàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

一、背景

我們?nèi)粘y試中存在大量重復(fù)的造數(shù)操作,且流程較長,為了提升測試效率,我們搭建了數(shù)據(jù)構(gòu)造平臺(tái)。平臺(tái)采用了前端 + 腳本分離的形式,數(shù)據(jù)構(gòu)造腳本獨(dú)立存在,頁面和腳本的關(guān)聯(lián)關(guān)系通過頁面配置進(jìn)行綁定。

頁面配置中,包含了腳本的路徑以及啟動(dòng)命令,因此,運(yùn)行腳本的時(shí)候需要在服務(wù)器上啟動(dòng)子進(jìn)程中去執(zhí)行腳本命令。為了能夠了解腳本的執(zhí)行情況,還需要獲取腳本的執(zhí)行狀態(tài)以及執(zhí)行日志。

平臺(tái)后端語言是 Python,因此,選擇了 Python 中的 subprocess 模塊,本文重點(diǎn)闡述 subprocess 模塊在項(xiàng)目實(shí)戰(zhàn)中遇到的問題以及解決方案。

本文涉及的程序執(zhí)行環(huán)境如下:

Python 版本:3.8.3

操作系統(tǒng):windows server

二、subprocess 模塊基礎(chǔ)

subprocess 模塊允許我們啟動(dòng)一個(gè)新進(jìn)程,并連接到它們的輸入/輸出/錯(cuò)誤管道,從而獲取返回值。subprocess 模塊首先推薦使用的是它的 run 方法,更高級(jí)的用法可以直接使用 Popen 接口。

1. subprocess.run 方法

subprocess.run() 方法是 3.5 版本新增的,用于可以接受等待進(jìn)程執(zhí)行結(jié)束后獲取返回值的場景,如果可以滿足使用需求,官方推薦使用 run() 方法。
subprocess.run() 的執(zhí)行過程是同步的,腳本執(zhí)行結(jié)束之前是阻塞的,只有腳本結(jié)束之后才會(huì)返回 subprocess.CompletedProcess 對象。

2. subprocess.Popen 方法

subprocess.Popen() 是 subprocess 的核心,子進(jìn)程的創(chuàng)建和管理都靠它處理。Popen() 相當(dāng)于 run() 的高級(jí)版本,更加靈活,使開發(fā)人員能夠處理 run() 方法未涵蓋的更豐富的場景。subprocess.Popen() 是異步的,進(jìn)程啟動(dòng)以后,我們可以通過預(yù)先指定好的 stdout 和 stderr 來實(shí)時(shí)讀取到子進(jìn)程的輸出。

subprocess.Popen()常用參數(shù)介紹:

args:shell命令,可以是字符串或者序列類型(如:list,元組)

stdin, stdout, stderr:分別表示程序的標(biāo)準(zhǔn)輸入、輸出、錯(cuò)誤句柄

shell:如果該參數(shù)為 True,將通過操作系統(tǒng)的 shell 執(zhí)行指定的命令,args只能是String類型的參數(shù);該參數(shù)為False,args可以是序列類型。

Popen 對象常用方法:

poll(): 檢查進(jìn)程是否終止,如果終止返回 returncode,否則返回 None,項(xiàng)目中通過該方法返回判斷進(jìn)程是否執(zhí)行結(jié)束。

wait(timeout): 等待子進(jìn)程終止,如果進(jìn)程執(zhí)行時(shí)間較長,可以使用該方法來保證進(jìn)程執(zhí)行完整。

communicate(input,timeout): 和子進(jìn)程交互,發(fā)送和讀取數(shù)據(jù)。

send_signal(singnal): 發(fā)送信號(hào)到子進(jìn)程 。

terminate(): 停止子進(jìn)程,也就是發(fā)送SIGTERM信號(hào)到子進(jìn)程。

kill(): 殺死子進(jìn)程。發(fā)送 SIGKILL 信號(hào)到子進(jìn)程。

3. run 與 Popen 的同步/異步對比實(shí)驗(yàn)

Run() 和 Popen() 同步/異步的簡單對比如下:

從執(zhí)行結(jié)果可以看出,Popen 在子進(jìn)程執(zhí)行過程中就可以獲取到日志,run 需要等待進(jìn)程執(zhí)行完成才能獲取到日志。如果需要執(zhí)行的命令耗時(shí)很短,可以選擇 run 方法。因?yàn)槲覀兊臄?shù)據(jù)構(gòu)造流程通常比較長,需要實(shí)時(shí)獲取日志,所以選擇了 Popen。

三、遇到的問題與解決方案

在使用 Popen 的過程中也遇到了一些問題,下面將具體介紹一下遇到的問題以及解決方案。

如何保證獲取到完整的進(jìn)程執(zhí)行日志

subprocess.Popen() 可以獲取到執(zhí)行過程中的日志了,那我們?nèi)绾伪WC進(jìn)程日志獲取的完整性呢?我們來看下具體方案:

方案一:這是我們最開始采用的方案。通過獲取方法 poll() 返回的狀態(tài)碼來檢查進(jìn)程是否終止。如果終止,返回 returncode,否則返回 None,代碼如下:

該方案在使用的過程中存在問題。當(dāng)子程序已經(jīng)執(zhí)行完畢,日志還沒有獲取完整,會(huì)出現(xiàn)日志接收不全的情況。為了解決這種問題,保證日志的完整性,我們選擇通過判斷日志是否讀取完畢作為判斷依據(jù),詳細(xì)參見方案二。

方案二:通過判斷日志是否讀取完畢保證日志完整性。代碼如下:

這種方法看似解決了日志不全的問題,但是存在著一定的風(fēng)險(xiǎn)。日志為 None 無法有效保證子進(jìn)程執(zhí)行結(jié)束(雖然經(jīng)過多方實(shí)踐,暫時(shí)沒有發(fā)現(xiàn)日志為 None 但腳本未執(zhí)行結(jié)束的情況)。為了安全起見,我們還是需要兼顧一下進(jìn)程的執(zhí)行狀態(tài),具體參見方案三。

方案三:通過判斷 poll() 返回狀態(tài)和日志返回值,也就是說,程序狀態(tài)結(jié)束且返回對象為空,才表示子進(jìn)程已經(jīng)執(zhí)行結(jié)束,并且獲取到了完整的日志,代碼如下:

該方案已經(jīng)比較完善了,通過子進(jìn)程執(zhí)行結(jié)束并且執(zhí)行日志為 None,保證執(zhí)行日志的完整性。美中不足的是,日志信息可能會(huì)比實(shí)際的多一些,當(dāng)輸出先讀取完畢,子進(jìn)程還沒有結(jié)束,我們會(huì)獲取到一部分空行,為了日志的美觀度,我們可以進(jìn)一步優(yōu)化,獲取日志的時(shí)候,過濾掉空行,代碼如下:

通過判斷輸出流和進(jìn)程的執(zhí)行狀態(tài),完美的解決了上面的問題,保證了日志的完整性與正確性。

如何保證腳本進(jìn)程正常終止 當(dāng)腳本執(zhí)行以后,我們可能會(huì)因?yàn)槟承┰蛳虢K止腳本的運(yùn)行,如參數(shù)錯(cuò)誤等。 在我們項(xiàng)目代碼中,使用 Popen.terminate() 去終止進(jìn)程的時(shí)候,發(fā)現(xiàn)命令只終止了父進(jìn)程,喚起的子進(jìn)程仍然在執(zhí)行。

為了找到原因,先看一下項(xiàng)目中創(chuàng)建 Popen 的代碼:

參數(shù)介紹的時(shí)候提到過,shell 為 True 或 False 時(shí),command 的類型是有要求的。因?yàn)槲覀?command 傳值是 String 類型,參數(shù) shell 只能設(shè)置為 True。當(dāng) shell=True 的時(shí),程序會(huì)創(chuàng)建一個(gè) shell 進(jìn)程,command 是 shell 進(jìn)程的子進(jìn)程。

我們再來看下 Popen.terminate() 做了什么?官方的說明如下:

Stop the child. On POSIX OSs the method sends SIGTERM to the child. On Windows the Win32 API function TerminateProcess()is called to stop the child

也就是說,在 POSIX 系統(tǒng)中,該方法會(huì)發(fā)送 SIGTERM 信號(hào)給子進(jìn)程;

在 Windows 系統(tǒng)中,該方法會(huì)調(diào)用 Win32 提供的 API TerminateProcess() 方法。

原因很清晰了,當(dāng) shell=True 的時(shí)候,發(fā)送 SIGTERM 能夠殺死 shell 進(jìn)程,但是無法殺死它的子進(jìn)程(command);windows 系統(tǒng)中同理,TerminateProcess() 殺死了 shell 進(jìn)程,卻沒有殺死它的子進(jìn)程(command)。

解決方案如下:

方案一:比較優(yōu)雅的方式,創(chuàng)建 Popen 對象時(shí),將參數(shù) shell 設(shè)為 False。實(shí)踐發(fā)現(xiàn),當(dāng) shell=False 的時(shí)候,Popen.terminate() 方法的執(zhí)行結(jié)果是符合預(yù)期的;

subprocess.Popen(command, shell=False)

前面提到過,因?yàn)?command 格式問題,在我們項(xiàng)目中,shell 只能設(shè)置為 True,所以我們又探索了新的解決方案。

方案二:手動(dòng)終止進(jìn)程。使用第三方工具包 psutil,獲取全部的子進(jìn)程并逐一殺掉,該方法在 Linux 和 windows 平臺(tái)通用。代碼見下圖。

在 windows 服務(wù)器下,還可以用以下命令:

taskkill /t /f /pid {pid},強(qiáng)制殺掉指定進(jìn)程以及它的子進(jìn)程。

windows 平臺(tái)的方案無需第三方依賴,所以我們項(xiàng)目中選擇了該方案,項(xiàng)目代碼如下:

以上就是 Python 中的 subprocess 模塊在我們項(xiàng)目實(shí)踐中遇到的問題以及解決方案,希望可以給大家提供一些使用思路以及規(guī)避掉一系列問題,更多關(guān)于Python測試開發(fā)subprocess的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python中請使用isinstance()判斷變量類型

    Python中請使用isinstance()判斷變量類型

    這篇文章主要介紹了Python中請使用isinstance()判斷變量類型,本文先是給出了isinstance函數(shù)判斷變量類型的例子,并對isinstance 和 type的區(qū)別做了講解,需要的朋友可以參考下
    2014-08-08
  • Windows下安裝python2.7及科學(xué)計(jì)算套裝

    Windows下安裝python2.7及科學(xué)計(jì)算套裝

    這篇文章主要向大家介紹的是在windows系統(tǒng)下安裝python 2.7以及numpy安裝、six安裝、dateutil安裝、pyparsing安裝、matplotlib安裝和scipy安裝的方法,分享給大家,需要的小伙伴可以參考下,相對來說,windows下的安裝還是比較簡單的。
    2015-03-03
  • python中正則表達(dá)式 re.findall 用法

    python中正則表達(dá)式 re.findall 用法

    在python中,通過內(nèi)嵌集成re模塊,程序媛們可以直接調(diào)用來實(shí)現(xiàn)正則匹配。本文重點(diǎn)給大家介紹python中正則表達(dá)式 re.findall 用法,感興趣的朋友跟隨小編一起看看吧
    2018-10-10
  • Python使用scipy模塊實(shí)現(xiàn)一維卷積運(yùn)算示例

    Python使用scipy模塊實(shí)現(xiàn)一維卷積運(yùn)算示例

    這篇文章主要介紹了Python使用scipy模塊實(shí)現(xiàn)一維卷積運(yùn)算,結(jié)合實(shí)例形式分析了scipy模塊的功能及使用scipy模塊進(jìn)行一維卷積運(yùn)算的相關(guān)操作技巧,需要的朋友可以參考下
    2019-09-09
  • Python遠(yuǎn)程控制Windows服務(wù)器的方法詳解

    Python遠(yuǎn)程控制Windows服務(wù)器的方法詳解

    在很多企業(yè)會(huì)使用閑置的 Windows 機(jī)器作為臨時(shí)服務(wù)器,有時(shí)候我們想遠(yuǎn)程調(diào)用里面的程序或查看日志文件。本文分享了利用Python遠(yuǎn)程控制Windows服務(wù)器的方法,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • 七牛云的python sdk 批量刪除資源的操作方法

    七牛云的python sdk 批量刪除資源的操作方法

    今天做項(xiàng)目的時(shí)候用到七牛云,關(guān)于對資源的操作是在后端做的,用的SDK,這篇文章主要介紹了七牛云的python sdk 是如何 批量刪除資源的,需要的朋友可以參考下
    2021-10-10
  • Django項(xiàng)目在pycharm新建的步驟方法

    Django項(xiàng)目在pycharm新建的步驟方法

    在本篇文章里小編給大家整理的是一篇關(guān)于Django項(xiàng)目在pycharm新建的步驟方法,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-03-03
  • MATLAB數(shù)學(xué)建模之畫圖匯總

    MATLAB數(shù)學(xué)建模之畫圖匯總

    這篇文章主要介紹了MATLAB數(shù)學(xué)建模之畫圖匯總,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 在Python中實(shí)現(xiàn)貪婪排名算法的教程

    在Python中實(shí)現(xiàn)貪婪排名算法的教程

    這篇文章主要介紹了在Python中實(shí)現(xiàn)貪婪排名算法的教程,也是對學(xué)習(xí)算法的一個(gè)很好的演示,需要的朋友可以參考下
    2015-04-04
  • Python進(jìn)階之協(xié)程詳解

    Python進(jìn)階之協(xié)程詳解

    這篇文章主要為大家介紹了Python進(jìn)階之協(xié)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01

最新評(píng)論