一、Fiddler抓包工具的配置和使用
在編寫(xiě)網(wǎng)關(guān)自動(dòng)化腳本之前,得先學(xué)會(huì)如何抓包,這里以Fiddler為例。會(huì)抓包的同學(xué)可以跳過(guò)這一步,當(dāng)然看看也是沒(méi)壞處的……
局域網(wǎng)絡(luò)配置
將要進(jìn)行抓包的手機(jī)與電腦連入同一局域網(wǎng),電腦才能夠抓到手機(jī)APP的請(qǐng)求,這里介紹一種我們?cè)谑褂玫木W(wǎng)絡(luò)配置方法。
首先使用電腦A布置一個(gè)我們抓包需要的局域網(wǎng)。下載獵豹WiFi(網(wǎng)上有很多這種工具360免費(fèi)WiFi、百度WiFi等,隨意下載一個(gè)就好,這里我們以獵豹WiFi為例),安裝完后創(chuàng)建一個(gè)WiFi即可。
然后使用抓包的電腦B連接剛剛建立的WiFi,連接好后查看電腦B的IP地址。

用測(cè)試手機(jī)連接剛剛建立的WiFi,在局域網(wǎng)設(shè)置中將其代理改為電腦B的IP地址,端口號(hào):8888,保存即可。


Fiddler配置
Fiddler的安裝,在網(wǎng)上下載最新的版本就可以,這里給出一個(gè)我安裝的4.5版本的鏈接http://sq.jd.com/bFPg1z,下載安裝,步驟就省略了,下一步..下一步即可。
安裝完成后打開(kāi)Fiddler,在菜單欄Tools->Fiddler Options->Connections,勾選Allow remote computers to connect,默認(rèn)的端口號(hào)為8888,這里不需要修改,在修改手機(jī)代理設(shè)置時(shí)注意與這里一致。

因?yàn)槲覀兯枰ト〉幕旧隙际蔷〇|到家有關(guān)的請(qǐng)求,所以我們可以設(shè)置只抓取我們所需要的請(qǐng)求,如圖,選中右方Filters,在下方Hosts設(shè)置中選擇Show only the follow Hosts,然后填入我們所需要抓取請(qǐng)求的Host,比如這里填入的是京東到家Android線上和預(yù)發(fā)布的Host。

到這里Fiddler的基本配置就完成了,接下來(lái)就可以開(kāi)始抓包啦。
Fiddler抓包實(shí)例
開(kāi)啟Fiddler,確定本機(jī)網(wǎng)絡(luò)連接,查看本機(jī)IP、Fiddler端口號(hào)。
本機(jī)IP:192.168.191.2
Fiddler端口號(hào):8888
手機(jī)連接同一局域網(wǎng),設(shè)置代理。


打開(kāi)手機(jī)京東到家應(yīng)用,清空電腦Fiddler遺留抓取結(jié)果,點(diǎn)擊如圖所示按鈕,點(diǎn)擊第一個(gè)Remove all即可。

下拉刷新京東到家首頁(yè),抓取其HTTP請(qǐng)求。


分析Fiddler抓包數(shù)據(jù)。在右上方結(jié)果框中選擇Inspectors->Raw即可看到請(qǐng)求的URL、Cookie和Host等有關(guān)信息。在右下方結(jié)果框中選擇JSON就能看到請(qǐng)求返回的JSON字符串。這里的JSON字符串是我們判斷請(qǐng)求是否成功的重要依據(jù)。

提示:在每次抓取時(shí)重復(fù)下步驟3中清空結(jié)果列表的操作,可以更容易地找到需要抓取的請(qǐng)求。
二、Jmeter的基本使用
Jmeter的安裝配置
下載Jmeter。我們使用的Jmeter版本是2.1.3,大家可以在\\192.168.202.207\share\pengyun中直接下載apache-jmeter-2.13.zip即可,里面已經(jīng)安裝了需要的jar包和插件。
安裝JDK。Jmeter2.1.3需要安裝JDK 6或以上版本,沒(méi)有安裝的同學(xué)記得安裝,還是給大家一個(gè)鏈接吧,http://sq.jd.com/VaGwoP,需要的同學(xué)可以下載,安裝完成后配置環(huán)境變量即可,參考鏈接http://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.html。
安裝Jmeter。解壓即可,無(wú)需多言。
第一個(gè)Jmeter腳本
這里很難對(duì)Jmeter做一個(gè)全面的介紹,而且我也只是了解了一些皮毛,所以就在實(shí)例中一一介紹吧,所有配置齊全之后,就開(kāi)始我們的第一條腳本吧。下面的步驟說(shuō)得比較詳細(xì),比較啰嗦,請(qǐng)勿急躁。
抓取需要的請(qǐng)求。這一步是在Fiddler中完成的,如果你是從頭看到這的,那么這一步的內(nèi)容就可以省略了。這里我們就以前面抓到的京東到家首頁(yè)的請(qǐng)求為例。下圖那個(gè)很重要的結(jié)果等會(huì)要用到。

運(yùn)行Jmeter。在安裝目錄下的bin文件夾里打開(kāi)jmeter.bat,后面的黑框能夠輸出一些斷言結(jié)果。在右面的名稱(chēng)那里可以修改你要?jiǎng)?chuàng)建的測(cè)試腳本的名稱(chēng),默認(rèn)是測(cè)試計(jì)劃。

創(chuàng)建線程組。測(cè)試計(jì)劃右鍵選添加->Threads->線程組。

修改名稱(chēng)。修改線程組名稱(chēng)并不重要,根據(jù)自己的需要修改就行。由于我們執(zhí)行腳本一般在需要的時(shí)候執(zhí)行一次就可以,并不需要其他的配置,所以下方的線程屬性就保持默認(rèn)值即可(在進(jìn)行壓力測(cè)試的時(shí)候就需要進(jìn)行配置了)。

添加HTTP請(qǐng)求。右鍵線程組選擇HTTP請(qǐng)求。

填寫(xiě)HTTP請(qǐng)求相關(guān)信息。這一步是關(guān)鍵,需要根據(jù)步驟1中Fiddler里那段很重要的信息去填寫(xiě)。名稱(chēng)自行修改,Host、協(xié)議、請(qǐng)求方法、請(qǐng)求路徑都能夠在抓取到的信息中獲取,拷貝過(guò)來(lái)就行。
注意:HTTP請(qǐng)求有GET和POST兩種,不同的請(qǐng)求記得選擇不同的請(qǐng)求方法!?。?/b>


添加Cookie管理器。右鍵線程組選擇Cookie管理器。將抓取到的信息添加至Cookie管理器中。


添加結(jié)果樹(shù)。到這里這條Case就算是編寫(xiě)完成了,在運(yùn)行之前我們還需要添加一個(gè)結(jié)果樹(shù),來(lái)查看Case運(yùn)行的結(jié)果。右鍵線程組選擇查看結(jié)果樹(shù)添加。

運(yùn)行。在上方找到運(yùn)行按鈕運(yùn)行即可。注意,如果有多個(gè)線程組或者多個(gè)HTTP請(qǐng)求,點(diǎn)擊運(yùn)行后都會(huì)全部一起運(yùn)行。

結(jié)果分析。點(diǎn)擊結(jié)果樹(shù)即可查看運(yùn)行結(jié)果,綠色為成功,紅色為失敗。在右邊點(diǎn)擊相應(yīng)數(shù)據(jù)就能夠看到返回的JSON字符串了。

這樣我們的第一條Jmeter腳本就基本完成了,基本所有的HTTP請(qǐng)求都是大同小異,多練習(xí)寫(xiě)幾條基本就能手到擒來(lái)了。結(jié)果樹(shù)和Cookie管理器每個(gè)線程組添加一個(gè)就夠用了。
三、Jmeter使用標(biāo)準(zhǔn)化
實(shí)際上,完成上面兩個(gè)步驟并不算是真正學(xué)會(huì)了腳本的編寫(xiě),因?yàn)槟_本中最重要的一部分是它的斷言,斷言是來(lái)判斷網(wǎng)關(guān)返回JSON結(jié)果是否正確和完整的重要手段。下面的內(nèi)容寫(xiě)得比較啰嗦,麻煩大家一定要耐心點(diǎn),別睡著!
參數(shù)化
1、簡(jiǎn)介
在寫(xiě)過(guò)一些腳本之后大家可能就會(huì)發(fā)現(xiàn),所謂的寫(xiě)腳本無(wú)非就是不停地復(fù)制,粘貼,復(fù)制,粘貼……于是大家肯定會(huì)想一些讓自己能更快復(fù)制粘貼的方法。參數(shù)化的方法就能在簡(jiǎn)化這個(gè)過(guò)程的同時(shí)讓大家更清晰地認(rèn)識(shí)到URL的結(jié)構(gòu)。
URL其實(shí)就是很多個(gè)參數(shù)組成的,而里面的參數(shù)一般是會(huì)加密的,為了更好地了解URL的結(jié)構(gòu),可以對(duì)URL進(jìn)行解碼,這個(gè)百度一下大把解碼工具可以用,都是在線的,很是方便。這里給個(gè)參考的鏈接http://meyerweb.com/eric/tools/dencoder/,URL粘進(jìn)去點(diǎn)Decode即可。
解碼結(jié)果如下:

從解碼后的URL里可以看出其中很多參數(shù)的值,appName、signKey、screen、body等都是。經(jīng)過(guò)對(duì)大量URL的分析,發(fā)現(xiàn)所有京東到家請(qǐng)求URL中有很多參數(shù)是不變的。更具體來(lái)說(shuō),根據(jù)請(qǐng)求的不同,只有signKey、body和functionId這三個(gè)參數(shù)是發(fā)生改變的,其余的參數(shù),在賬號(hào)和手機(jī)設(shè)備不變的情況下是不會(huì)發(fā)生變化的。這樣的話(huà),我們把那些不變的參數(shù)放在一起統(tǒng)一管理,每次在寫(xiě)新的腳本的時(shí)候,只需要改變那三個(gè)不同的參數(shù)就可以了。
2、實(shí)現(xiàn)方法
1)設(shè)置參數(shù)。在線程組右鍵選擇添加->配置原件->用戶(hù)定義的變量。

然后在定義變量的頁(yè)面點(diǎn)擊下方添加按鈕進(jìn)行URL參數(shù)的添加,這里參考解碼后的URL,將其中的參數(shù)逐一進(jìn)行添加。從下圖中可以看到,除了signKey、body和funtionId這三個(gè)參數(shù)外,其與參數(shù)都被添加。我們也能夠發(fā)現(xiàn)這些參數(shù)大都是和手機(jī)型號(hào)、系統(tǒng)、app名稱(chēng)版本等信息有關(guān)的,只要手機(jī)設(shè)備不更換、到家版本不更新,這套參數(shù)是可以一直用下去的。當(dāng)然大家在使用自己設(shè)備和賬號(hào)的時(shí)候記得更新下這些參數(shù)。


2)給請(qǐng)求添加參數(shù)?;氐降郊沂醉?yè)的HTTP請(qǐng)求,這時(shí)候我們已經(jīng)不需要在路徑的框里粘貼上那條很長(zhǎng)很長(zhǎng)的URL了。那么怎么使用上一步中的參數(shù)呢?看了下面這張圖就明白了。這里引用參數(shù)的方法是${參數(shù)名}??梢钥吹较旅娴谋碇械膮?shù)是通請(qǐng)求一起發(fā)送的參數(shù),也就是說(shuō)是這些參數(shù)組成了原來(lái)的那條很長(zhǎng)很長(zhǎng)的URL。
注意下圖表中框出的三個(gè)參數(shù),就是前面一直在提到的每個(gè)請(qǐng)求都不同的那三個(gè)參數(shù),signKey、body、functionId。那么以后再寫(xiě)新的腳本的時(shí)候,只需要改這三個(gè)參數(shù),其他的地方都不需要改動(dòng)。注意:下面的body參數(shù)是經(jīng)過(guò)解碼的,所以應(yīng)當(dāng)勾選后面的編碼框。
3、實(shí)例
說(shuō)了這么多,大家肯定會(huì)覺(jué)得沒(méi)有必要這么麻煩,直接復(fù)制粘貼不就好了么,那么下面就舉一個(gè)例子來(lái)體現(xiàn)下參數(shù)化的好處。按照上面的步驟設(shè)置添加好參數(shù)后,首頁(yè)的腳本應(yīng)當(dāng)是可以運(yùn)行了,下面我們以首頁(yè)為基準(zhǔn),來(lái)寫(xiě)一條新的腳本,以秒殺頁(yè)面為例。
第一步:使用Fiddler抓取秒殺頁(yè)面的請(qǐng)求,對(duì)URL進(jìn)行解碼。注意標(biāo)記的三個(gè)參數(shù)一會(huì)要用。

第二步:選擇"首頁(yè)"腳本,右鍵點(diǎn)擊選擇復(fù)制,選擇"京東到家"線程組,右鍵點(diǎn)擊粘貼,其實(shí)就是把首頁(yè)的腳本復(fù)制一份。于是線程組里又出現(xiàn)了一個(gè)新的首頁(yè)。

第三步:選擇新復(fù)制的首頁(yè)腳本,將其名稱(chēng)改為"秒殺頁(yè)面",然后把參數(shù)列表中的那三個(gè)參數(shù)改為第一步中對(duì)應(yīng)的值,然后Ctrl+S保存就可以啦。

是的,只需要這三步,就可以完成一個(gè)腳本,整個(gè)過(guò)程不超過(guò)一分鐘。以后寫(xiě)每個(gè)腳本都可以用這三步實(shí)現(xiàn)。當(dāng)然,后續(xù)給腳本加上斷言之后還需要改動(dòng)斷言。
響應(yīng)斷言
如果你是從開(kāi)頭一步一步讀過(guò)來(lái)的,那么你現(xiàn)在一定能夠很快地寫(xiě)出一條腳本,這時(shí)候就有一個(gè)問(wèn)題出現(xiàn)了,腳本寫(xiě)完了,可以運(yùn)行了,也可以看到運(yùn)行返回的結(jié)果了,那怎么能知道返回的結(jié)果是不是正確呢?是不是完整呢?這里先介紹一種簡(jiǎn)單的判斷方式:響應(yīng)斷言。
右鍵點(diǎn)擊HTTP請(qǐng)求添加->斷言->響應(yīng)斷言。

這里的響應(yīng)斷言主要是針對(duì)HTTP請(qǐng)求返回的JSON字符串的,我們一般使用的是包括斷言,就是返回的結(jié)果是否包含我們需要的信息。斷言文本的截取可以在運(yùn)行結(jié)果樹(shù)里進(jìn)行,將結(jié)果顯示類(lèi)型改為T(mén)ext(當(dāng)然也可以JSON格式和Text格式對(duì)比著找),找出需要斷言的信息。
需要注意的是響應(yīng)斷言支持正則表達(dá)式,這可以對(duì)一些經(jīng)常變化但格式固定的內(nèi)容做一些斷言。下圖中最后一條斷言就是正則表達(dá)式,其內(nèi)容表達(dá)的是秒殺剩余時(shí)間是否大于0小于3600秒。這個(gè)可以根據(jù)檢測(cè)點(diǎn)的需要去添加。想學(xué)習(xí)正則表達(dá)式的同學(xué)可以戳鏈接:http://deerchao.net/tutorials/regex/regex.htm。
當(dāng)然,響應(yīng)斷言的缺點(diǎn)很明顯,它的格式過(guò)于固定,不能滿(mǎn)足一些檢查點(diǎn)的需求操作,比如比較大小,檢查字段值是否為空。還有就是正則表達(dá)式會(huì)將所有符合格式的內(nèi)容都篩選出來(lái),不容易具體查出我們需要的內(nèi)容。
它的優(yōu)點(diǎn)就是比較簡(jiǎn)單,對(duì)于一些固定的內(nèi)容可以起到很好的判斷作用,比如下面第一條斷言
,這個(gè)可以基本斷言出請(qǐng)求是成功的,另外對(duì)于首頁(yè)樓層之類(lèi)的信息也很適合用響應(yīng)斷言。



在寫(xiě)完正則斷言后,要驗(yàn)證它的正確與否,可以在結(jié)果樹(shù)中,將結(jié)果顯示類(lèi)型改為RegExp Tester,然后將斷言復(fù)制到下方的Regular expression中,點(diǎn)擊Test就可以看到匹配的結(jié)果。

Bean Shell斷言
使用了響應(yīng)斷言之后,可能能夠解決一部分的檢查點(diǎn),但是肯定還有很多檢查點(diǎn)是通過(guò)響應(yīng)斷言覆蓋不了的。這里給大家介紹另外一種斷言的方式,Bean Shell斷言,說(shuō)白了也就是通過(guò)寫(xiě)代碼來(lái)解析返回的JSON字符串,提取有用的信息,進(jìn)行相應(yīng)的檢測(cè)。我對(duì)于Bean Shell的腳本語(yǔ)言也沒(méi)有什么了解,基本都是使用簡(jiǎn)單的JAVA代碼來(lái)實(shí)現(xiàn)的(真的是很簡(jiǎn)單的代碼,除了if還是if,連else都沒(méi)有)。在響應(yīng)斷言里實(shí)現(xiàn)不了的功能,也基本都可以通過(guò)代碼來(lái)實(shí)現(xiàn)。
1、JSON的基礎(chǔ)結(jié)構(gòu)
要解析JSON字符串,就要對(duì)JSON做一定的了解,實(shí)際只要知道JSON的基礎(chǔ)結(jié)構(gòu)就可以。JSON有兩種結(jié)構(gòu),對(duì)象和數(shù)組,通過(guò)這兩種結(jié)構(gòu)可以表示各種復(fù)雜的結(jié)構(gòu)。希望大家能夠自己百度了解下JSON的結(jié)構(gòu),下面大概對(duì)JSON的基礎(chǔ)結(jié)構(gòu)介紹一下,僅供參考。
對(duì)象:表示為用"{}"括起來(lái)的內(nèi)同,其數(shù)據(jù)結(jié)構(gòu)為{name1:value1,name2:value2,…}的鍵值對(duì)的結(jié)構(gòu),name為屬性名,value為對(duì)應(yīng)的屬性值,這個(gè)屬性值的類(lèi)型有數(shù)字、字符串、對(duì)象、數(shù)組幾種。如下圖的例子,返回的JSON字符串中,result就是一個(gè)對(duì)象,其中的city、address、title等都是對(duì)象的屬性值。

數(shù)組:表示為用"[]"括起來(lái)的內(nèi)容,其數(shù)據(jù)結(jié)構(gòu)為[object1,object2,…],其中object是JSON對(duì)象。如下圖中的例子,result表示的是一個(gè)數(shù)組,它的第0個(gè)和第1個(gè)元素分別是一個(gè)對(duì)象,對(duì)象中又有各自的屬性。

經(jīng)過(guò)對(duì)象、數(shù)組的組合就可以組成復(fù)雜的數(shù)據(jù)結(jié)構(gòu)了,明白了上面兩點(diǎn),就基本夠用了,JSON的解析就是一個(gè)不斷深入尋找所需信息的過(guò)程。
2、Bean Shell斷言編寫(xiě)
Bean Shell斷言實(shí)際上就是通過(guò)對(duì)JSON字符串的解析找到需要檢測(cè)的數(shù)據(jù)進(jìn)行相應(yīng)的檢測(cè)比對(duì)的過(guò)程。下面通過(guò)一個(gè)例子來(lái)具體說(shuō)明下其編寫(xiě)方式。
因?yàn)槭謾C(jī)APP上會(huì)顯示商店名稱(chēng)、商店圖片、營(yíng)業(yè)時(shí)間、商店評(píng)分和滿(mǎn)免運(yùn)費(fèi)的信息,所以這里我們對(duì)這些信息做一下檢查,在請(qǐng)求返回的JSON結(jié)果中找到對(duì)應(yīng)的字段:storeName、imgUrl、serviceTimes、shopFreeFreight和scoreAvg。


在HTTP請(qǐng)求點(diǎn)擊右鍵,選擇Bean Shell斷言,添加Bean Shell元件。

添加完成后就可以開(kāi)始編寫(xiě)B(tài)ean Shell腳本了,這里的代碼就是對(duì)上方JSON返回串的解析,其中JSONObject是前面所說(shuō)的對(duì)象,JSONArray就是數(shù)組了。里面輸出的錯(cuò)誤信息會(huì)輸出到Jmeter剛打開(kāi)時(shí)后面的那個(gè)黑框里。其余的JAVA語(yǔ)句都是很常用的if、for語(yǔ)句,相信只要明白了JSON結(jié)構(gòu),編寫(xiě)這里就很easy啦!

當(dāng)然了,為什么不用一些更復(fù)雜的代碼實(shí)現(xiàn)更強(qiáng)大的功能呢,原因有兩個(gè),一個(gè)是我的編碼水平還很有限,以后會(huì)不斷學(xué)習(xí)增加代碼實(shí)現(xiàn)的功能,另一個(gè)原因就是Jmeter里的Bean Shell感覺(jué)比較low,如果代碼出現(xiàn)錯(cuò)誤(語(yǔ)法錯(cuò)誤之類(lèi)的),很難定位到是什么地方出現(xiàn)了問(wèn)題,所以簡(jiǎn)單的代碼能夠讓你更容易地運(yùn)行和維護(hù)代碼。
四、網(wǎng)關(guān)腳本
這個(gè)教程可能還是會(huì)漏掉很多東西,大家在一開(kāi)始編寫(xiě)腳本的時(shí)候可能還會(huì)遇到一些不懂的地方,這個(gè)可以去git上下載我最新上傳的腳本以供參考,或者直接來(lái)問(wèn)我就好,腳本地址:
1.4.1線上地址:http://source.jd.com/app/gateway-auto-ant141
1.4.1預(yù)發(fā)地址:http://source.jd.com/app/gateway-auto-ant141-pre
因?yàn)槟_本經(jīng)常會(huì)Cookie過(guò)期或者有新的更新,所以git上的腳本會(huì)實(shí)時(shí)更新,當(dāng)發(fā)現(xiàn)腳本出現(xiàn)大量錯(cuò)誤的時(shí)候,試試去git上下載份新的腳本試試看。