寫在前面
本文我們一起來學習如何使用Robot Framework 的RequestsLibrary庫,涉及POST、GET接口測試,RF用例分層封裝設計等內容。
接口
接口測試是我們最常見的測試類型之一,主要用於檢測外部系統與系統之間以及內部各個子系統之間的交互點。測試的重點是要檢查數據的交換,傳遞和控制管理過程,以及系統間的相互邏輯依賴關系等。--摘自百度百科
RequestsLibrary
RequestsLibrary是基於reuqests庫定義的一個Robot Framework 庫。requests就不用介紹了吧,GitHub上面超過36k star的超級Python項目。
安裝
pip install requests
pip install robotframework-requests
簡單使用
*** Settings ***
Documentation http請求Demo
Library Collections
Library RequestsLibrary
*** Variables ***
${host} http://httpbin.org
*** Test Cases ***
Post 請求Demo
[Tags] Post main
${data} Create Dictionary name=Detector age=18
create session httpbin ${host}
${response} post request httpbin /post params=${data}
should be equal as integers ${response.status_code} 200
${resp} to json ${response.content}
should not be empty ${resp["args"]}
dictionary should contain key ${resp["headers"]} Host
dictionary should contain value ${resp["headers"]} httpbin.org
Get 請求Demo
[Tags] Get
${data} Create Dictionary name=Detector age=18
create session httpbin ${host}
${response} get request httpbin /get params=${data}
should be equal as integers ${response.status_code} 200
${resp} to json ${response.content}
should not be empty ${resp["args"]}
dictionary should contain key ${resp["headers"]} Host
dictionary should contain value ${resp["headers"]} httpbin.org
上面這是一個簡單的Demo,我們在*** Settings ***中引入了標准庫Collections和剛安裝的RequestsLibrary,在*** Variables ***中定義了全局變量${host}。
然后開始寫測試用例了,以Post 請求Demo為例,我們一起來看看用例里面包含了些什么:
第一行:我們給當前用例指定了Tag,一個用例是可以指定多個Tag的,非常靈活,用法我們在前一篇中有介紹
第二行:我們創建了一個一個字典並賦值給了變量${data},作為后續的數據傳入
第三行:我們創建了一個HTTP會話,並給它取了一個別名httpbin
第四行:我們根據根據前一行創建的會話別名查找會話,並在會話中發送POST請求
第五行:我們對接口的接口的結果碼進行了斷言,因為RF所有的數據都是以字符串方式存儲的,所以使用將should be equal as integers把他們作為int進行比較
第六行:我們將接口響應的內容使用RequestsLibrary庫的關鍵字to json轉化為了JSON
第七行:我們對轉化后的JSON的的args數據進行了不能為空的斷言
第八行:我們使用Collections的dictionary should contain key關鍵字對返回數據headers中是否含有Host進行了斷言
第九行:我們對返回數據的headers中Host字段的值進行了斷言
注: 在RF中,單條用例某個步驟執行失敗,后續步驟在沒有做特殊配置的情況下 都會略過不執行。
分層封裝(數據驅動測試)
上面的示例中寫了兩個測試用例,除了因為要體現GET、POST外還有另外一個作用,那就是引出分層封裝。細心的伙伴可能已經注意到了:我們兩個用例有很多一樣的操作。
根據一個功能如果需要重復使用兩次以上就應該抽象成一個獨立的函數的原則,特別當我們有多個用例都是使用同樣的操作,只是每次輸入的參數不一樣的時候,我們應該把公共操作獨立出來。
這個封裝的操作在RF中有兩種實現方式:
- 在Robot用例文件中直接封裝
- 自定義函數,實現相關功能的關鍵字進行調用
我們今天介紹第一種,第二種方式我們會在介紹如何自定義關鍵字的時候介紹。
簡單封裝
我們先來看看簡單的封裝的例子,僅對請求的和數據轉化的細節進行封裝,這種方式在擴展的時候非常靈活:
*** Test Cases ***
Package Post
[Tags] packaged req
${data} Create Dictionary name=Detector age=18
${resp} POST Req ${data}
should not be empty ${resp["args"]}
dictionary should contain key ${resp["headers"]} Host
dictionary should contain value ${resp["headers"]} httpbin.org
*** Keywords ***
POST Req
[Arguments] ${data}
Create Session api ${host}
${response} Post Request api /post params=${data}
should be equal as integers ${response.status_code} 200
${resp} to json ${response.content}
[Return] ${resp}
可以看到,我們通過*** Keywords ***定義了關鍵字POST Req,定義過程中分別使用[Arguments]、[Return]來接收和返回的數據。
POST Req中整合了創建HTTP會話,轉化接口返回結果等步驟,,調用和其他的RF庫自帶關鍵字沒有什么區別。
高度封裝
我們再來看看高度封裝,這種方式會將所有的細節全部封裝,優點是用例簡潔,只保留傳入參數和預期結果,缺點是靈活性低,不易擴展:
*** Test Cases ***
packaged test
[Template] Packaged POST Req
name host Content-Length=0
name host name Content-Length=0
*** Keywords ***
Packaged POST Req
[Arguments] ${data} ${Hosts} @{args} &{HostValue}
Create Session api ${host}
${response} Post Request api /post params=${data}
should be equal as integers ${response.status_code} 200
${resp} to json ${response.content}
# log ${resp}
dictionary_should_contain_sub_dictionary ${resp["headers"]} ${HostValue}
run keyword if ${args} log ${args}
... ELSE should not be empty ${resp["args"]}
*** Keywords ***解析:
第一行: 我們定義了Packaged POST Req能接受的參數,可選參數:@{args}、&{HostValue}與Python中*args、**args對應;
第六行: 我們使用了新的關鍵字dictionary_should_contain_sub_dictionary來斷言字典包含場景;
第七行: 我們使用了新的關鍵字run keyword if來判斷${args}是否為空,然后根據這個條件作出不同的操作。
運行上面的用例查看測試報告,可以看到packaged test這一個用例其實在內部運行了兩次。分別覆蓋了@{args} 是否為空的情況。

在實際編寫用例的過程中,建議兩種方式組合使用,響應參數簡單的使用第二種方式,響應參數復雜度較高的使用第一種,方便靈活擴展。
總結
- RequestsLibrary 庫的安裝使用
- 數據驅動測試(分層用例封裝)
