隨著軟件開發(fā)在造車行業(yè)中占有越來越重要的地位,敏捷開發(fā)的思想在造車領(lǐng)域中也逐漸地被重視起來,隨之而來的是整車廠對(duì)自動(dòng)化測(cè)試需求越來越強(qiáng)烈。本文結(jié)合北匯信息在自動(dòng)化測(cè)試方面的豐富經(jīng)驗(yàn),簡(jiǎn)單介紹一下實(shí)施自動(dòng)化測(cè)試可能需要具備的技能及具體實(shí)踐流程。
自動(dòng)化測(cè)試城門-Python
要實(shí)現(xiàn)完全的自動(dòng)化測(cè)試,我們首先要做的是先實(shí)現(xiàn)半自動(dòng)化測(cè)試,即編寫自動(dòng)化測(cè)試腳本。俗話說Life is short,I use Python,Python作為一種簡(jiǎn)單易上手的高級(jí)編程語(yǔ)言,憑借其“無所不包”的庫(kù),成為測(cè)試腳本開發(fā)的不二之選。這里簡(jiǎn)單介紹一下,測(cè)試腳本開發(fā)常用的一些Python標(biāo)準(zhǔn)庫(kù)。
城門士卒-os庫(kù)
在編寫測(cè)試腳本時(shí),不可避免地會(huì)遇到對(duì)文件路徑的獲取及編輯,os庫(kù)里的path函數(shù)可以方便地實(shí)現(xiàn)這些操作,如絕對(duì)路徑獲取os.path.abspath()、路徑拼接os.path.join()、路徑存在判斷os.path.exist()等;如果你需要在Python中運(yùn)行測(cè)試工具提供的命令,那么os庫(kù)的system函數(shù)或popen函數(shù)可以讓你方便地調(diào)用cmd(Windows)或shell(Linux)。
城門士卒-sys庫(kù)
如果你所編寫的測(cè)試腳本有跨平臺(tái)運(yùn)行的需求,那么你可以通過sys庫(kù)的platform函數(shù)獲取腳本的運(yùn)行環(huán)境。根據(jù)運(yùn)行環(huán)境的不同,編寫不同的批處理命令;sys庫(kù)中的argv函數(shù),還可以為你的測(cè)試腳本提供簡(jiǎn)單的命令行接口,當(dāng)你的腳本需要接收外部傳遞的參數(shù)時(shí),你可以通過sys.argv[]方便地獲取。而如果你需要編寫更復(fù)雜更友好的命令行接口,你需要使用Python的另外一個(gè)標(biāo)準(zhǔn)庫(kù)argparse來實(shí)現(xiàn)。
城門隊(duì)長(zhǎng)-re庫(kù)
正則表達(dá)式是編寫測(cè)試腳本的必備技能,因?yàn)橛袝r(shí)我們會(huì)遇到復(fù)雜的文本處理,如在工程文件中查找需要修改的配置,并將其修改為我們所需要的內(nèi)容。此時(shí)一般的查找替換函數(shù)就很難實(shí)現(xiàn)這個(gè)功能,我們只能借助強(qiáng)大的re庫(kù)(正則表達(dá)式)來解決這個(gè)棘手的問題。re庫(kù)提供的函數(shù)有:
re.compile():編譯正則表達(dá)式,生成一個(gè) Pattern對(duì)象;
re.findall():搜索所有滿足條件的字符串;
re.match():從第一個(gè)字符開始匹配模式;
re.search():搜索第一個(gè)滿足條件的字符串,查找到第一個(gè)停止;
re.sub():替換滿足條件的字符串。
在使用re模塊時(shí),我們一般先用re.compile()將正則表達(dá)式編譯生成為一個(gè)Pattern對(duì)象,然后再基于這個(gè)對(duì)象進(jìn)行findall、match等操作,這樣既可以提高代碼的可讀性,也可以提高代碼的運(yùn)行效率。
使用正則表達(dá)式進(jìn)行查找替換是很方便的,但是在很多時(shí)候我們需要在匹配的字符串前后添加內(nèi)容,并且保留匹配的內(nèi)容,這時(shí)普通的查找替換是難以實(shí)現(xiàn)的。
如:希望將hour: minute格式后添加:00,形成hour: minute: seconds這種格式。此時(shí)可以采用如下方式來實(shí)現(xiàn):
查找的正則表達(dá)式:
替換為:
這里,我們?cè)谔鎿Q的字符中使用\1,來引用正則表達(dá)式中第一個(gè)分組匹配到的內(nèi)容,如果正則表達(dá)式中有多個(gè)分組,可以依次使用\2\3等進(jìn)行引用,可以使用\0來引用整個(gè)正則表達(dá)式的內(nèi)容。
小結(jié)
在掌握了Python基礎(chǔ)語(yǔ)法和這三個(gè)標(biāo)準(zhǔn)庫(kù)后,自動(dòng)化測(cè)試的大門就為我們敞開了。但是想要編寫一個(gè)可以驅(qū)動(dòng)測(cè)試工具進(jìn)行測(cè)試的腳本,我們還需要了解測(cè)試工具在headless模式[1]下的接口情況,如果工具提供的接口豐富,可以實(shí)現(xiàn)在headless模式(這里的headless模式是指在不使用工具GUI的情況下,以純命令行的方式進(jìn)行工具使用的模式)下對(duì)測(cè)試工程進(jìn)行配置和執(zhí)行等操作,那么我們的測(cè)試腳本開發(fā)工作將會(huì)順利地進(jìn)行。
但是如果工具提供的headless模式接口有限,無法滿足測(cè)試腳本的需求,那么進(jìn)入自動(dòng)化測(cè)試大門后,等待我們的就是另一個(gè)棘手的問題:如何對(duì)工程文件進(jìn)行解析與修改。考慮到大部分的工程文件都是XML格式的,因此后續(xù)我們就簡(jiǎn)單介紹一下如何通過Python解析和修改XML文件。
自動(dòng)化測(cè)試甕城——XML文件
甕城守備——XML解析
在Python的標(biāo)準(zhǔn)庫(kù)中,有專門處理XML文件的庫(kù),無需安裝第三方庫(kù)就可以使用Python進(jìn)行XML文件的解析,但是要想準(zhǔn)確地從XML文件中解析出想要的信息,我們首先需要簡(jiǎn)單了解一下XML的文件結(jié)構(gòu)。如下是一個(gè)簡(jiǎn)單的XML文檔。
其中Harry Potter元素的結(jié)構(gòu)如下圖所示:
注:圖片來源于w3school
在該XML文本中,根元素是 <2;bookstore>,文檔中的所有 <2;book> 元素都被包含在 <2;bookstore> 里。<2;book> 元素有 4 個(gè)子元素:<2;title>、< author>、<2;year>、<2;price>。每個(gè)子元素都包含一個(gè)文本內(nèi)容,但只有子元素title和元素book擁有屬性。
我們?cè)诮馕鯴ML時(shí),一般需要獲取的就是元素的屬性值以及元素的文本內(nèi)容。以下我們就簡(jiǎn)單介紹一下,如何通過python獲取元素的屬性值及文本內(nèi)容。
Python的XML庫(kù)提供了一個(gè)通過標(biāo)簽名稱獲取元素的函數(shù)getElementsByTagName(),該函數(shù)返回的是一個(gè)包含元素對(duì)象的list,通過調(diào)用元素對(duì)象的attributes方法,我們就可以方便地獲取元素的屬性值。如,我們可以使用如下命令獲取XML文件中第一個(gè)標(biāo)簽為title的lang屬性值:
root.getElementsByTagName("title")[0].attributes.getNamedItem("lang").nodeValue
獲取第一個(gè)標(biāo)簽為title的元素的文本信息的代碼如下:
root.getElementsByTagName("title")[0].firstChild.data
甕城參將——XML修改
XML元素的屬性和文本內(nèi)容修改很簡(jiǎn)單,在上小節(jié)中獲取對(duì)應(yīng)的元素信息后,直接對(duì)其進(jìn)行賦值即可。但是,修改后的信息保存在XML對(duì)象中。要完成對(duì)實(shí)際XML文件的修改,我們還需要用XML對(duì)象中的內(nèi)容覆蓋原有的XML文件,這一步存在很多棘手的問題。
在XML文件中,為了避免元素文本內(nèi)容中存在的特殊字符引起解析器錯(cuò)誤,在文本內(nèi)容中引入實(shí)體引用來替代可能導(dǎo)致錯(cuò)誤的字符,如回車 、雙引號(hào)"、單引號(hào)'。如果使用python的xml.dom.minidom庫(kù)解析并使用writexml輸出XML文件,該庫(kù)會(huì)將這些實(shí)體引用轉(zhuǎn)義為其實(shí)際字符進(jìn)行保存。如果不對(duì)XML對(duì)象中的內(nèi)容進(jìn)行處理,導(dǎo)出的XML文件將會(huì)存在很多錯(cuò)誤。
為了避免這個(gè)情況的出現(xiàn),我們需要使用之前小節(jié)介紹的正則表達(dá)式將這些字符再替換為其實(shí)體引用。這個(gè)過程需要我們能熟練使用正則表達(dá)式進(jìn)行文本查找與替換。
除了XML文件中的實(shí)體引用外,如果XML文件中存在中文字符,那么還有一個(gè)需要注意的事情:不要使用with openas的方式讀寫XML文件,要使用open指定文件的編碼為'utf-8’的方式,對(duì)XML文件進(jìn)行寫入。如下所示:
f =open(self.JenkinsJobXMLPath,'w',encoding="utf-8")
dom.writexml(f,indent='',addindent='\t',newl='',encoding='utf-8')
f.close()
小結(jié)
上述兩個(gè)問題是修改XML文件時(shí)普遍會(huì)遇到的問題。解決了這兩個(gè)問題,我們基本上就可以完美實(shí)現(xiàn)XML文件的修改了。此時(shí),我們就可以編寫自動(dòng)化程度更高的測(cè)試腳本,然而我們依然無法實(shí)現(xiàn)完全的自動(dòng)化測(cè)試,因?yàn)槲覀內(nèi)匀恍枰謩?dòng)地去執(zhí)行測(cè)試腳本。那么,我們?cè)撊绾螌?shí)現(xiàn)測(cè)試腳本的自動(dòng)執(zhí)行呢?這就需要我們打通自動(dòng)化測(cè)試的最后一個(gè)關(guān)卡,Jenkins。
自動(dòng)化測(cè)試總兵——Jenkins
Jenkins是一個(gè)開源、免費(fèi)的可擴(kuò)展持續(xù)集成引擎,主要用于:
- 持續(xù)、自動(dòng)地構(gòu)建/測(cè)試軟件項(xiàng)目;
- 監(jiān)控一些定時(shí)執(zhí)行的任務(wù)。
為了實(shí)現(xiàn)測(cè)試腳本的自動(dòng)化運(yùn)行,我們需要配置JenkinsJob,使Jenkins在設(shè)置的觸發(fā)條件滿足時(shí),自動(dòng)搭建測(cè)試腳本的運(yùn)行環(huán)境,然后執(zhí)行測(cè)試腳本,最后將測(cè)試結(jié)果發(fā)送給相關(guān)人員。因此我們需要了解Jenkins的源碼管理、構(gòu)建觸發(fā)器、構(gòu)建及郵件通知等設(shè)置。
總兵的連招1——源碼管理
Jenkins服務(wù)器最基本的作用是監(jiān)視版本控制器,當(dāng)版本庫(kù)有新的更改時(shí),檢出版本庫(kù)中的文件,或者,你可以選擇只是定期檢出版本庫(kù)中最新的文件。無論哪種方式,Jenkins與版本控制軟件的集成是必不可少的。
Jenkins開箱即用式支持Git、CVS和SVN,還通過插件與大量其他版本控制工具進(jìn)行集成,如ClearCase、Perforce、PVCS等等。
不同的版本控制軟件在Jenkins端的需要的配置并不相同,有的甚至差異很大。但是只要你熟悉你所使用的版本控制軟件,那么在Jenkins端,就可以很容易地對(duì)版本庫(kù)進(jìn)行配置。
以SVN為例,為了從SVN倉(cāng)庫(kù)中獲取源碼,我們需要提供相應(yīng)SVN版本庫(kù)的URL,在完成URL輸入后,Jenkins會(huì)檢查URL的有效性,如果所提供的URL要求身份認(rèn)證,Jenkins將會(huì)自動(dòng)提示選擇相應(yīng)的憑據(jù)以驗(yàn)證賬號(hào)信息,如下圖所示。
默認(rèn)情況下,Jenkins會(huì)將給定的代碼庫(kù)中的文件檢出到JenkinsJob的Workspace中。如果你需要將代碼庫(kù)檢出到指定的目錄中,你可以在Localmoduledirectory中輸入你想要的目錄名或相對(duì)Workspace的路徑。
如果你需要從多個(gè)SVN版本庫(kù)中獲取文件,可以點(diǎn)擊“Addmodule...”按鈕,來添加別的版本庫(kù)。
總兵的連招2——構(gòu)建觸發(fā)器
常用的構(gòu)建觸發(fā)器有周期性構(gòu)建和SCM輪詢構(gòu)建,兩者都是使用相同corn風(fēng)格語(yǔ)法進(jìn)行設(shè)置,如下圖所示。
我們只需要了解corn風(fēng)格的語(yǔ)法,就可以方便地進(jìn)行構(gòu)建觸發(fā)器的設(shè)置。corn風(fēng)格的語(yǔ)法包含五個(gè)由空格分隔的字段:
MINUTE HOUR DOM MONTH DOW
每個(gè)字段使用下面的值:
MINUTE小時(shí)內(nèi)的分鐘數(shù)(0-59)
HOUR一天的小時(shí)數(shù)(0-23)
DOM本月的天數(shù)(1-31)
MONTH月份(1-12)
DOW本周的一天(0-7),其中0和7都是星期日。
要為一個(gè)字段指定多個(gè)值,可以使用以下操作符:
- “*”代表一個(gè)字段的所有可能的值。如,“* * * * *”表示周期為一分鐘;
- 使用“M-N”定義范圍。如,在DOW中“1-5”表示周一到周五;
- 使用“/”定義范圍間隔時(shí)間。如,MINUTE字段“*/5”表示每5分鐘;
- 逗號(hào)分隔的列表表示有效值。如,MINUTE字段“15,45”表示在每小時(shí)的第15和第45分鐘運(yùn)行;
通常,我們只需要在這個(gè)字段中寫一行,但是對(duì)于更復(fù)雜的調(diào)度配置,我們可能需要寫多行。
總兵的連招3——構(gòu)建
在完成了之前的配置后,Jenkins應(yīng)該知道在何時(shí)從何處獲取測(cè)試工程及源碼。現(xiàn)在我們需要做的事情是,告訴Jenkins在獲取測(cè)試工程和源碼后該如何做。一般情況下,我們會(huì)將之前編寫的測(cè)試腳本放在測(cè)試工程的版本庫(kù)中,或者從專門的測(cè)試腳本庫(kù)中檢出到JenkinsJob的Workspace中,因此我們?cè)谶@里只需要執(zhí)行編寫好的測(cè)試腳本即可。
執(zhí)行腳本的方式可以根據(jù)具體腳本的運(yùn)行環(huán)境,選擇執(zhí)行Shell或Windows批處理命令。因此我們需要簡(jiǎn)單地了解Shell或Windows的常用批處理命令。為了避免編寫復(fù)雜的批處理命令,我們應(yīng)盡量把工作放在測(cè)試腳本中完成。本文以如下圖所示的簡(jiǎn)單的Windows批處理為例,簡(jiǎn)單介紹一下構(gòu)建步驟的編寫。
在上圖中,有兩行命令:
第一行的作用是將目錄由初始的Workspace目錄切換到Workspace下的Script目錄;
第二行的作用是運(yùn)行Script目錄中的測(cè)試腳本Script.py,并為該腳本傳遞一個(gè)參數(shù),該參數(shù)為Jenkins的環(huán)境變量JOB_NAME,即當(dāng)前JenkinsJob的名稱。
這樣就完成了對(duì)測(cè)試腳本的調(diào)用。
總兵的連招4——郵件通知
自動(dòng)化測(cè)試的一個(gè)重要環(huán)節(jié),就是將測(cè)試結(jié)果通知到相關(guān)人員,如開發(fā)\測(cè)試人員,或項(xiàng)目管理人員等。Jenkins對(duì)電子郵件提供了開箱即用的支持,我們可以在構(gòu)建后處理中勾選E-mail Notification,如下圖所示。然后輸入需要通知的人員郵箱,即可使Jenkins在構(gòu)建完成后,向指定的人員發(fā)送一封友好的電子郵件。
如果你想對(duì)郵件內(nèi)容進(jìn)行高度定制,那么E-mail Notification就無法滿足需求,我們需要安裝可編輯的電子郵件插件Editable Email Notification,來實(shí)現(xiàn)電子郵件的定制化工作。
在Editable Email Notification中,我們可以用HTML編寫電子郵件的內(nèi)容,并引用Jenkins的環(huán)境變量,這樣我們就可以在郵件中描述當(dāng)前JenkinsJob的測(cè)試執(zhí)行概況,讓收件人快速地了解當(dāng)前的測(cè)試狀態(tài)。但是這要求我們對(duì)HTML和Jenkins環(huán)境變量都有比較深的了解。
有些情況下,我們需要在郵件中執(zhí)行一些數(shù)據(jù)提取等復(fù)雜工作,比如將控制臺(tái)輸出中的一些數(shù)據(jù)在郵件中進(jìn)行展示,這時(shí)我們需要借助email-ext-plugin插件提供的Groovy接口,用Groovy編寫郵件內(nèi)容。
總之,Jenkins的郵件通知功能非常強(qiáng)大,我們可以在自動(dòng)化測(cè)試的工作中不斷進(jìn)行探索。
小結(jié)
本節(jié)簡(jiǎn)單介紹了Jenkins的傳統(tǒng)表單類型的FreestyleJob,然而目前Jenkins的發(fā)展方向是 Pipeline Job,Jenkins將Pipeline作為優(yōu)先開發(fā)項(xiàng)目。這就意味著Pipeline在應(yīng)用程序中是作為實(shí)體被設(shè)計(jì)和支持的,而不是通過在Jenkins中連接一堆任務(wù)而形成流水線。Pipeline類型的Job可以通過編程實(shí)現(xiàn),可以實(shí)現(xiàn)更復(fù)雜構(gòu)建邏輯和工作流,更重要的是在Pipeline中有專門的用于流水線編程的結(jié)構(gòu)化DSL,其可以在工作空間中輕松地實(shí)現(xiàn)文件共享功能。同時(shí)Pipeline具有全新的Jenkins可視化界面 ——BlueOcean,其為Pipeline的每個(gè)階段添加了圖形化的展示,如下圖所示。
因此我們?cè)谑煜ち吮韱晤愋偷?FreestyleJob后,可以嘗試將其轉(zhuǎn)換為Pipeline的Job,當(dāng)然目前并非所有的Jenkins插件都支持Pipeline,有些老舊的插件還無法支持Pipeline,我們需要根據(jù)實(shí)際的工作情況進(jìn)行Jenkins工程類型的選擇。
攻城總結(jié)
古人云:知所不豫,行且通焉。雖然通過本文,我們?nèi)娴亓私饬俗詣?dòng)化測(cè)試的流程,但是只有在自動(dòng)化測(cè)試的實(shí)踐中不斷探索,我們才能真正窺得自動(dòng)化測(cè)試的全貌。北匯信息作為專業(yè)的自動(dòng)化測(cè)試服務(wù)供應(yīng)商,也可以為客戶提供優(yōu)質(zhì)全面的自動(dòng)化測(cè)試服務(wù)。
-
自動(dòng)化測(cè)試
+關(guān)注
關(guān)注
0文章
214瀏覽量
26929 -
python
+關(guān)注
關(guān)注
56文章
4805瀏覽量
84929
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論