之前的學習中,我們已經將需要的插件都安裝好了,現在我們開始記錄一下一個包含token關聯的接口自動化框架的搭建全過程
我們的總體結構如下:
common:用來存放公共類 reports是生成報告temp是測試接口生成的json數據 ,用於生成報告的(詳細可看之前的報告生成文章)testcases用來存放測試用例,其它就是一些配置文件,運行程序和前後置
首先我們先對yaml數據的讀取,寫入,清除等方法進行封裝,屬於公共方法,因此我們在common下創建yaml_util.py代碼如下
import os
import yaml
#讀取
class YamlUtil:
# 讀取
def read_yaml(self,key):
with open(os.getcwd() + '/extract.yaml', encoding='utf-8', mode='r') as f:
value = yaml.load(f, yaml.FullLoader)
return value[key]
# 寫入
def write_yaml(self,data):
with open(os.getcwd() + '/extract.yaml', encoding='utf-8', mode='a') as f:
yaml.dump(data, stream=f, allow_unicode=True)
# 清空
def clear_yaml(self):
with open(os.getcwd() + '/extract.yaml', encoding='utf-8', mode='w') as f:
f.truncate()
# 讀取測試用例
def read_testcase(self,yaml_name):
with open(os.getcwd() + '\\testcases\\' + yaml_name, mode='r', encoding='utf-8') as f:
value = yaml.load(f, yaml.FullLoader)
return value
依舊在common中創建request_util.py文件,代碼如下:
import requests
import json
class RequestUtil:
sess= requests.session()
def send_request(self,method,url,datas=None,**kwargs):
method=str(method).lower() #轉換小寫
res=None
if method=="get":
res=RequestUtil.sess.request(method=method,url=url,params=datas,**kwargs)
elif method=="post":
if datas and isinstance(datas,dict):
datas=json.dumps(datas)
res=RequestUtil.sess.request(method=method, url=url, data=datas, **kwargs)
else:
pass
return res
這裡我只封裝了get和post兩種請求,如果要使用其它方法,自行加入即可。
創建一個get_token.yaml文件,用來存放我們登錄接口的用例,例如我的:
-
name: 獲取接口統一鑒權碼token接口
request:
method: post
url: https://***/jlcloud/api/login
data:
"account": "****"
"password": "014f4041514bc5dcb82845fe5efa3c54"
"project": "DEFAULT"
"teacherLogin": False
"clientId": "1"
"secret": ""
headers:
'Content-Type': 'application/json'
validate: None
-
name: 獲取接口統一鑒權碼token接口
request:
method: post
url: https://***/jlcloud/api/login
data:
"account": "***"
"password": "123456"
"project": "DEFAULT"
"teacherLogin": False
"clientId": "1"
"secret": ""
headers:
'Content-Type': 'application/json'
validate: None
yaml數據寫入規則請看我之前的文章,
第二個接口是獲取用戶信息的get請求,我創建userinfo.yaml來存放第二個接口的用例
-
name: 獲取接口統一鑒權碼token接口
request:
method: get
url: https://***/jlcloud/api/login/getUserInfo
data:
{}
headers:
'Content-Type': 'application/json'
validate: None
數據准備完成後,在testcases下創建一個test_login的py文件,這裡我們在test_login裡寫入代碼、
import pytest
import requests
import json
from common.request_util import RequestUtil
from common.yaml_util import YamlUtil
class TestRequest:
pass
@pytest.mark.parametrize("args_name",YamlUtil().read_testcase('get_token.yaml')) ##讀取測試用例的get_token.yaml文件中的參數及值,賦值給變量args_name
def test_login(self,args_name):
url=args_name['request']['url']
data = args_name['request']['data']
method= args_name['request']['method']
headers=args_name['request']['headers']
res = RequestUtil().send_request(method=method, url=url, datas=data, headers=headers)
print(res.text)
if "data" in res.text:
YamlUtil().write_yaml({"token":res.json()['data']}) #將token值寫入yaml文件,執行後根目錄生成extract.yaml文件,可在此查看提取的token
@pytest.mark.parametrize("userinfo", YamlUtil().read_testcase('userinfo.yaml'))##讀取測試用例的userinfo.yaml文件中的參數及值,賦值給變量userinfo
def test_userinfo(self, userinfo):
token = YamlUtil().read_yaml('token') # 讀取token的值
url = userinfo['request']['url']+'?token='+token #我這裡的url需要帶上token
data = userinfo['request']['data']
method = userinfo['request']['method']
headers = userinfo['request']['headers']
res = RequestUtil().send_request(method=method, url=url, datas=data, headers=headers)
print(res.text)
在根目錄下創建conftest.py,注意這個文件名稱是pytest框架寫死的不能更改,常用來處理測試用例的前置條件。並用fixture標記一些函數,例如連接數據庫的操作、或者我們這種token值變化,每次運行前就需要清除一下等
這裡我們在測試時進行yaml數據清除
import pytest
from common.yaml_util import YamlUtil
@pytest.fixture(scope="function")
def exe_sql():
print("用例執行之前")
yield
print("用例執行之後")
#在所有的接口請求之前執行
@pytest.fixture(scope="session",autouse=True)
def clear_extract():
YamlUtil().clear_yaml()
在根目錄新建run.py文件
import pytest
import os
if __name__ == '__main__': # pytest運行模式
pytest.main()
os.system("allure generate ./temp -o ./reports --clean") ##生成測試報告
運行後,目錄中會自動生成temp的json數據,以及reports裡的的index.html文件,打開文件即可查看報告,如下:
這樣一個簡單的框架就搭建好了,當然這只是很初步的一個框架,很多問題使用這個框架是無法實現的,例如動態參數問題,數據太大的問題等,後續我在學習的過程中會繼續跟進,歡迎各位前輩指點,討論~