背景
最近參與了一個(gè)項(xiàng)目,團(tuán)隊(duì)有自動(dòng)化測(cè)試訴求,但是測(cè)試人員沒(méi)有編程能力,開(kāi)發(fā)人員也沒(méi)有精力幫忙,探索了已有的自動(dòng)化測(cè)試工具,滿足不了團(tuán)隊(duì)需求后,決定自己造個(gè)輪子。
- Postman
Postman是一個(gè)不需要編碼能力,且十分方便的自動(dòng)化測(cè)試工具,由于項(xiàng)目中很多測(cè)試的驗(yàn)證點(diǎn)需要驗(yàn)證數(shù)據(jù)庫(kù)里面數(shù)據(jù)的正確性,如果用Postman的話需要為測(cè)試創(chuàng)建一些沒(méi)有必要的HTTP API。很遺憾, 這個(gè)輪子不滿足我們的要求。
- Rest-assured
我們探索的第二個(gè)工具是Rest-assured. 雖然他對(duì)API測(cè)試相關(guān)操作封裝了很簡(jiǎn)潔美觀的DSL, 由于其直接是Java代碼,像數(shù)據(jù)庫(kù)校驗(yàn)什么的毫無(wú)困難。但是要編寫(xiě)基于Rest-assured的自動(dòng)化測(cè)試,還得有一定的編碼基礎(chǔ),很遺憾,這個(gè)輪子我們用不來(lái)。
- Cucumber
Cucumber支持自然語(yǔ)言形式編寫(xiě)自動(dòng)化測(cè)試,自然語(yǔ)言調(diào)用的是代碼,如果對(duì)cucumber做了足夠好的封裝,編寫(xiě)測(cè)試的人不需要編寫(xiě)代碼也能寫(xiě)自動(dòng)化測(cè)試。那就需要做足夠通用的封裝,所以Pandaria就是基于cucumber jvm封裝的HTTP(S) API自動(dòng)化測(cè)試的DSL。Cucumber本身功能非常實(shí)用,使用pandaria依然能夠直接使用cucumber jvm的所有功能。
Pandaria
在測(cè)試團(tuán)隊(duì)缺乏編碼能力,以及需要驗(yàn)證數(shù)據(jù)庫(kù)的需求背景下,我們嘗試著基于cucumber做封裝,使不會(huì)寫(xiě)代碼的測(cè)試人員也能編寫(xiě)自動(dòng)化測(cè)試。之后我們很驚訝的發(fā)現(xiàn)這種方式非常有效,所以將這個(gè)工具分享出來(lái),希望能對(duì)有相同訴求的團(tuán)隊(duì)有所幫助。
測(cè)試HTTP API
Scenario: simple get
* uri: /users/me
* send: GET
* status: 200
* verify: '$.username'='jakim'
* verify: '$.age'=18
使用pandaria寫(xiě)API自動(dòng)化測(cè)試,就像上面這樣,只需要使用抽象好的關(guān)鍵字,描述發(fā)送請(qǐng)求的過(guò)程,以及編寫(xiě)你的驗(yàn)證條件即可。
上述代碼解讀: 往相對(duì)路徑uri為/users/me的地址發(fā)送GET請(qǐng)求,并驗(yàn)證返回狀態(tài)為200,且返回體里面json path為$.username的值為'jakim',json path $.age處的值為18。
驗(yàn)證數(shù)據(jù)庫(kù)
* query:
"""
SELECT NAME, AGE FROM USERS
"""
* verify: '$[0].name'='jakim'
* verify: '$[0].age'=18
或者
* query: select.sql
* verify: '$[0].name'='jakim'
* verify: '$[0].age'=18
select.sql
SELECT NAME, AGE FROM USERS
測(cè)試人員只用寫(xiě)SQL就能像校驗(yàn)json一樣校驗(yàn)數(shù)據(jù)庫(kù)內(nèi)容。上述代碼會(huì)使用SQL語(yǔ)句SELECT NAME, AGE FROM USERS到數(shù)據(jù)庫(kù)中查詢,并驗(yàn)證返回結(jié)果的第1行的name和age屬性。
準(zhǔn)備測(cè)試數(shù)據(jù)可以直接執(zhí)行SQL文件:
* execute sql: prepare_users.sql
* execute sql:
"""
insert into users(name) values('test');
"""
等待功能
自動(dòng)化測(cè)試經(jīng)常需要等待一件事情完成,特別是異步操作時(shí),這時(shí)候通常的做法是等待一定的時(shí)間,驗(yàn)證結(jié)果,如果不通過(guò),則重試一定的次數(shù),直到驗(yàn)證成功,或者超過(guò)最大次數(shù)失敗。使用Pandaria可以這么寫(xiě):
* wait: 1000ms times: 3
* uri: /sequence
* send: GET
* response body:
"""
3
"""
上述代碼會(huì)往/sequence發(fā)請(qǐng)求,并驗(yàn)證返回消息體是否等于3,如果等于則繼續(xù)往下執(zhí)行,如果失敗則等待1000ms,然后重試,如果重試超過(guò)最大3次,則測(cè)試失敗。
也可以等待數(shù)據(jù)庫(kù)中數(shù)據(jù)滿足某個(gè)條件
* wait: 1000ms times: 3
* query: select.sql
* verify: '$[0].name'='jakim'
* verify: '$[0].age'=18
變量
很多時(shí)候restful api的uri的路徑中包含數(shù)據(jù)庫(kù)自增長(zhǎng)的ID, 其可能是一個(gè)異步操作生成,導(dǎo)致我們不能直接從API返回結(jié)果中拿到,只能從數(shù)據(jù)庫(kù)中根據(jù)測(cè)試數(shù)據(jù)的條件查找,并在后續(xù)API測(cè)試中使用,使用pandaria我們可以這么寫(xiě):
* query:
"""
select id from users where name='test-user-name';
"""
* var: 'auto_generated_id'<-'$[0].id'
* uri: /users/${auto_generated_id}
* send: GET
* verify: '$.id'=${auto_generated_id}
* verify: '$.name'='test-user-name'
上述代碼首先從數(shù)據(jù)庫(kù)查出自增長(zhǎng)的id,然后使用<-操作符將結(jié)果中的id定義為名為auto_generated_id的變量,并在后續(xù)的操作中使用這個(gè)變量。
總結(jié)
Pandaria目前還在持續(xù)開(kāi)發(fā)中,我們發(fā)現(xiàn)其已經(jīng)能對(duì)我們團(tuán)隊(duì)帶來(lái)切實(shí)的效率提升,故借此機(jī)會(huì)分享出來(lái),希望能幫助到類(lèi)似的團(tuán)隊(duì)。