python介面測試之token&session的處理
在前面我們介紹了使用postman,jmeter如何獲取token以及傳遞token,下面我們就來使用python語言來進行實現,在這裡我們使用第三方的庫requests,需要單獨的安裝下,安裝的命令是:
pip install -U requests
見安裝的截圖:
安裝成功後,如果可以在正常的導入,說明安裝OK,見截圖:
安裝好requests好後,我們就可以開始了,關於requests有不清楚的,可以看Python介面測試之requests(七),這裡我們直接來進行實戰,我們再來進行回顧下我們需要做的事情,我們需要做的就是登錄成功後,獲取token,後面的介面都需要這個參數,所以我們需要把獲取的token當作參數來進行傳遞,在這裡我們來思考一個問題,在python的函數中,為什麼會有返回值?返回值可以幹什麼?python中,函數的返回值是為了給另外一個函數傳遞參數,傳遞參數可以理解為是通過自動將對象賦值給本地變數名來實現。OK,下面我們就來使用實現這個過程,我們首先使用代碼來實現登錄的介面並且獲取返回的json字元串,見實現的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
importrequests
defgetToken():
r=requests.post(
url="https://ecapi.parkingwang.com/v4/login",
json={"username":"autoapi",
"password":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
"role":2},
headers={"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"},timeout=5)
returnr.json()
printgetToken()
見執行函數getToken後獲取的json字元串:
C:Python27python.exe D:/git/Python/UnitCI/blog/weke.py
{u"status":,u"msg":u"",u"data":
{u"token":u"ma7uW5KiqKpBYPQ6kBI1514038085951",u"id":600192,u"name":u"u81eau52a8u5316u6d4bu8bd5"}}
Process finishedwithexitcode
我們可以看到,獲取的內容是json字元串,經過反序列化後,數據類型是字典(dict),按字典的方式來獲取token就很簡單的,見獲取token的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
importrequests
defgetToken():
r=requests.post(
url="https://ecapi.parkingwang.com/v4/login",
json={"username":"autoapi","password":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92","role":2},
headers={"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"},timeout=5)
returnr.json()["data"]["token"]
見執行後,獲取的token字元串,見截圖:
下面來實現infoGet介面的測試,依據前面的案例我們知道,該介面的參數就是token,而且必須是和登錄成功後返回的token是一致,否則就會提示502的錯誤,token無效,我們來實現infoGet介面測試,見實現代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
importrequests
defgetToken():
r=requests.post(
url="https://ecapi.parkingwang.com/v4/login",
json={"username":"autoapi","password":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92","role":2},
headers={"Content-Type":"application/json;charset=UTF-8","Parkingwang-Client-Source":"ParkingWangAPIClientWeb"},timeout=5)
returnr.json()["data"]["token"]
definfoGet():
r=requests.post(
url="https://ecapi.parkingwang.com/v4/infoGet",
json={"token":getToken()},
headers={"Content-Type":"application/json;charset=UTF-8","Parkingwang-Client-Source":"ParkingWangAPIClientWeb"},timeout=5)
printr.json()
infoGet()
見執行infoGet函數後,返回的json字元串內容:
C:Python27python.exe D:/git/Python/UnitCI/blog/weke.py}
我們接著加一個介面,該介面為isSoonExpire,見測試該介面實現的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
importrequests
defgetToken():
r=requests.post(
url="https://ecapi.parkingwang.com/v4/login",
json={"username":"autoapi","password":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92","role":2},
headers={"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"},timeout=5)
returnr.json()["data"]["token"]
definfoGet():
r=requests.post(
url="https://ecapi.parkingwang.com/v4/infoGet",
json={"token":getToken()},
headers={"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"},timeout=5)
printr.json()
defisSoonExpire():
r=requests.post(
url="https://ecapi.parkingwang.com/v4/isSoonExpire",
json={"token":getToken()},
headers={"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"},timeout=5)
printr.json()
下面我們對代碼進行重構下,引入unittest,見重構後的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
importrequests
importunittest
classInterfaceTest(unittest.TestCase):
defsetUp(self):
self.url="https://ecapi.parkingwang.com/v4/"
self.headers={"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"}
self.timeout=5
deftearDown(self):
pass
defgetToken(self):
r = requests.post(
url=self.url+"login",
json={"username":"autoapi",
"password":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
"role":2},
headers=self.headers,timeout=self.timeout)
returnr.json()["data"]["token"]
deftest_infoGet(self):
"""驗證:測試infoGet介面是否正確"""
r = requests.post(
url=self.url+"infoGet",json={"token":self.getToken()},
headers=self.headers,timeout=self.timeout)
printr.json()
deftest_isSoonExpire(self):
"""驗證:測試isSoonExpire介面是否正確"""
r = requests.post(
url="https://ecapi.parkingwang.com/v4/isSoonExpire",
json={"token":self.getToken()},headers=self.headers,timeout=5)
printr.json()
if__name__ =="__main__":
unittest.main(verbosity=2)
如上的介面測試用例缺少斷言,在這裡特彆強調,沒有斷言的自動化測試用例是無效的,是沒有任何的價值的。至於具體斷言什麼,得格局具體的介面測試的業務來進行,我們對如上的介面添加斷言,見增加斷言後的介面測試代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
importrequests
importunittest
importtimeast
classInterfaceTest(unittest.TestCase):
defsetUp(self):
self.url="https://ecapi.parkingwang.com/v4/"
self.headers={"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"}
self.timeout=5
deftearDown(self):
t.sleep(1)
defgetToken(self):
r = requests.post(
url=self.url+"login",
json={"username":"autoapi",
"password":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
"role":2},
headers=self.headers,timeout=self.timeout)
returnr.json()["data"]["token"]
deftest_infoGet(self):
"""驗證:測試infoGet介面是否正確"""
r = requests.post(
url=self.url+"infoGet",json={"token":self.getToken()},
headers=self.headers,timeout=self.timeout)
self.assertEqual(r.json()["status"],)
self.assertEqual(r.json()["data"]["username"],"autoapi")
deftest_isSoonExpire(self):
"""驗證:測試isSoonExpire介面是否正確"""
r = requests.post(
url="https://ecapi.parkingwang.com/v4/isSoonExpire",
json={"token":self.getToken()},headers=self.headers,timeout=5)
self.assertEqual(r.json()["status"],)
self.assertEqual(r.json()["data"]["expire"],False)
if__name__ =="__main__":
unittest.main(verbosity=2)
執行上面的測試用例後,我們發現二個測試用例都調用了getToken()方法,而getToken()方法我們知道是登錄的介面,登錄成功後獲取token,言外之意也就是說登錄了二次,缺點很明顯,如果在N個測試用例,參數都需要token,都會調用getToken(),那麼也會出現登錄N次,很實現這個方法不是我們想要的,我們要實現的是不管有多少個介面測試用例,登錄只能是一次,如果登錄多次,會出現token無效502的問題,或者引起其他的問題,在這裡我們把登錄成功後的token存儲在文件中,然後從文件中讀取,這樣就可以登錄一次,見實現的代碼:
#!/usr/bin/env python
#-*-coding:utf-8-*-
importrequests
importunittest
importtimeast
importos
defgetHeaders():
"""獲取headers"""
return{"Content-Type":"application/json;charset=UTF-8",
"Parkingwang-Client-Source":"ParkingWangAPIClientWeb"}
deflogin():
"""把token寫入到文件中"""
r = requests.post(
url=self.url +"login",
json={"username":"autoapi",
"password":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
"role":2},
headers=getHeaders(),timeout=5)
withopen(base_dir(),"w")asf:
f.write(r.json()["data"]["token"])
defbase_dir():
"""獲取當前文件的目錄"""
returnos.path.join(os.path.dirname(__file__),"token.md")
defgetToken():
"""讀取存儲在文件中的token"""
withopen(base_dir(),"r")asf:
returnf.read()
classInterfaceTest(unittest.TestCase):
defsetUp(self):
self.url="https://ecapi.parkingwang.com/v4/"
deftearDown(self):
t.sleep(1)
deftest_infoGet(self):
"""驗證:測試infoGet介面是否正確"""
r = requests.post(url=self.url+"infoGet",
json={"token": getToken()},headers=getHeaders(),timeout=5)
self.assertEqual(r.json()["status"],)
self.assertEqual(r.json()["data"]["username"],"autoapi")
deftest_isSoonExpire(self):
"""驗證:測試isSoonExpire介面是否正確"""
r = requests.post(url=self.url+"isSoonExpire",
json={"token":getToken()},headers=getHeaders(),timeout=5)
self.assertEqual(r.json()["status"],)
self.assertEqual(r.json()["data"]["expire"],False)
if__name__ =="__main__":
unittest.main(verbosity=2)
代碼經過重構後,不管有多少個測試用例,我們的登錄只會進行一次。接下來我們會寫關於session這部分,python是如何解決的。
python處理session
下面我們使用python來處理session的部分,下面我們來看一個例子,登錄成功後,並沒有返回token,只是返回了請求成功的code,而是存儲session中,那麼我們應該如何來獲取session了,我們編寫該登錄的介面用例,看返回的json字元串是什麼,見實現的代碼以及輸出的截圖:
在截圖中我們看到,輸出的json字元串只有code是200的,再沒有什麼,但是後面的請求都需要帶上session,我們看下一個介面請求的內容,見截圖:
OK,那麼就說明我們登錄後必須得獲取session,見獲取session的代碼:
通過cookies.get_dict()就可以獲取session,見如上截圖中獲取的session內容,下面的就很簡單,我們在下一個介面用例中帶上session,見實現的碼:
執行如上的代碼後,我們發現代碼錯誤,錯誤的原因是test_access_datas()函數沒有帶上登錄成功後的session,所以導致錯誤,不帶session,一般直接就跳轉到了login的頁面,讓重新登錄,那麼如何解決了,我們只需要在test_access_datas()函數中,在介面請求中帶上session就可以了,見修改後執行的代碼:
TAG:python自動化測試 |