apiobject模式(學習代碼:部門管理增刪改查自動化測試框架)
1.代碼目錄
-接口測試po模式訓練
-api
-__init__.py
-department.py
-firstwork.py
-baseapi.py
-data
-config.yml
-interface
-__init__.py
-test_department.py
-utils.py
-logs
apitest.log
2.代碼
api代碼
baseapi.py
class BaseApi:
#設置logging
fileHandler = logging.FileHandler(filename="../logs/apitest.log")
#設置日志等級
logging.getLogger().setLevel(0)
#設置日志內(nèi)容格式
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s %(module)s:%(lineno)d %(message)s')
fileHandler.setFormatter(formatter)
#設置生效
logging.getLogger().addHandler(fileHandler)
def log_info(self,msg):
'''
寫日志的方法
:param msg: 要打印都日志的信息
:return: info級別的日志
'''
return logging.info(msg)
def send_api(self,req):
'''
對requests進行二次封裝
:param req:
:return:返回接口響應結(jié)果
'''
self.log_info("----------request data----------")
self.log_info(req)
r = requests.request(**req)
self.log_info("----------response data----------")
self.log_info(r.json())
return requests.request(**req)
firstWork.py
'''
企業(yè)微信調(diào)用部門接口前,需要信息認證
'''
import requests
import pytest
from 接口測試po模式訓練.api.send_api import BaseApi
class firstWork(BaseApi):
def __init__(self, corpid, corpsecret):
self.token = self.get_access_token(corpid, corpsecret)
def get_access_token(self,corpid,corpsecret):
'''
獲取access_token
:return:
'''
# corpid = "ww02f9f41e1958d910"
# corpsecret = "v_xbPx4VWhwQkiz7lZz3JJWcPH_WQOly3UvfTYZjyHo"
# 請求地址
url =f" https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={corpsecret}"
#把接口封裝到字典中
req = {
"method": "GET",
"url": url,
}
# 調(diào)用方法對字典解包,發(fā)出get請求(原始響應結(jié)果)
r = self.send_api(req)
print(r.json())
token = r.json()["access_token"]
return token
department.py
'''
接口信息描述:不加斷言,不加測試數(shù)據(jù),只寫方法
每個方法需返回接口響應體
'''
import requests
from 接口測試po模式訓練.api.firstWork import firstWork
from 接口測試po模式訓練.interface.utils import Utils
class Department(firstWork):
#描述接口方法時,將測試數(shù)據(jù)以參數(shù)形式展示,方便后面測試腳本調(diào)用接口中的方法進行傳參測試
def create_department(self,create_data):
'''
創(chuàng)建部門
:return:
'''
params = {
"access_token": self.token
}
create_url = 'https://qyapi.weixin.qq.com/cgi-bin/department/create'
# 發(fā)送請求
#r1 = requests.post(create_url, params=params, json=create_data)
#把接口內(nèi)容封裝到字典里面
req = {
"method": "POST",
"url": create_url,
"params": params,
"json": create_data
}
#調(diào)用接口封裝方法解包接口,發(fā)出請求
r = self.send_api(req)
print(r.json())
return r.json()
def update_department(self,update_data):
'''
更新部門
:return:
'''
update_url = f"https://qyapi.weixin.qq.com/cgi-bin/department/update?access_token={self.token}"
#r2 = requests.post(update_url, json=update_data)
#把接口內(nèi)容進行封裝
req = {
"method": "POST",
"url": update_url,
"json": update_data
}
#調(diào)用封裝方法解包接口內(nèi)容,發(fā)出請求
r = self.send_api(req)
return r.json()
def get_department(self):
'''
獲取部門
:return:
'''
get_data ={
}
get_url = f'https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token={self.token}'
#r3 = requests.get(get_url, params=get_data)
#把接口內(nèi)容進行封裝
req ={
"method":"GET",
"url": get_url,
"params":get_data
}
#調(diào)用接口封裝方法對接口內(nèi)容進行解包
r = self.send_api(req)
return r.json()
def delete_department(self,depart_id):
'''
刪除部門
:return:
'''
url = 'https://qyapi.weixin.qq.com/cgi-bin/department/delete'
params = {
"access_token":self.token,
"id":depart_id
}
#r4 = requests.get(url, params)
#把接口內(nèi)容進行封裝
req = {
"method": "GET",
'params': params,
"url": url
}
#調(diào)用接口函數(shù)對接口內(nèi)容進行解包,發(fā)送請求
r = self.send_api(req)
return r.json()
def clear_department(self):
'''
清理已經(jīng)存在的部門
:return:
'''
#查詢當前存在的部門
depart_list = self.get_department()
#提取部門id
id_list = Utils.base_jsonpath(depart_list,"$..id")
#id 為1 的最基礎的父部門,不能刪除
for i in id_list:
if i !=1:
#調(diào)用刪除部門的接口完成清除操作
self.delete_department(i)
測試代碼
utils.py
# -*- coding:UTF-8 -*-
'''
@Project : 607project
@file : utils.PY
@Date : 2021/10/18 11:53
@Author : Fairy
'''
import yaml
from jsonpath import jsonpath
class Utils:
@classmethod
def base_jsonpath(cls, obj, json_expr):
'''
封裝jsonpath斷言方法
:param obj: 要斷言的json格式的響應內(nèi)容
:param json_expr: jsonpath表達式
:return: 斷言結(jié)果
'''
return jsonpath(obj, json_expr)
@classmethod
def get_yaml_data(cls, file_path):
'''
封裝yaml文件讀取方法
:param file_path:yaml文件路徑
:return:返回字典格式y(tǒng)aml文件
'''
with open(file_path) as f :
datas =yaml.safe_load(f)
return datas
test_department.py
'''
測試用例
'''
from 接口測試po模式訓練.api.department import Department
from 接口測試po模式訓練.interface.utils import Utils
import allure
import pytest
'''
第一版框架
1.根據(jù)ApiObject模式完成了分層
2.從firstWork中獲取token,department中描述接口完成身份認證
3.測試用例中通過setup_class實例化接口描述的類
4.測試用例中傳入測試數(shù)據(jù),完成斷言
'''
@allure.feature("部門管理")
class TestDepartment:
def setup_class(self):
#獲取通訊錄管理的token參數(shù)
conf_data = Utils.get_yaml_data("../data/config.yml")
corpid = conf_data["corpid"]["qiyeceshi"]
corpsecret = conf_data["secret"]["department_secret"]
#實例化部門類
self.department = Department(corpid, corpsecret)
#清除部門數(shù)據(jù)
self.department.clear_department()
#準備測試數(shù)據(jù)
#創(chuàng)建部門的測試數(shù)據(jù)
self.depart_id = 5
self.create_data = {
"name": "天津研發(fā)中心",
"name_en": "TJ",
"order": 11,
"id": self.depart_id,
"parentid": 1
}
#更新部門的測試數(shù)據(jù)
self.update_data = {
"id": self.depart_id,
"name": "天津研發(fā)中心——更新"
}
# self.delete_data = {
# "id": self.depart_id
# }
@allure.story("部門操作場景用例")
def test_department_scene(self):
'''
部門增刪改查測試
:return:
'''
# 創(chuàng)建部門
with allure.step("創(chuàng)建部門"):
self.department.create_department(self.create_data)
#查詢創(chuàng)建是否成功
with allure.step("查詢部門創(chuàng)建結(jié)果"):
res1 = self.department.get_department()
#assert res1["department"][6]["name"] == "天津研發(fā)中心"
#通過jsonpath斷言
name_list = Utils.base_jsonpath(res1,"$..name")
print(name_list)
assert "天津研發(fā)中心" in name_list
print(res1)
# 更新部門
with allure.step("更新部門"):
self .department.update_department(self.update_data)
# #查詢更新是否成功
with allure.step("查詢部門更新結(jié)果"):
res2 = self.department.get_department()
#assert res2["department"][3]["name"]=="天津研發(fā)中心——更新"
#通過jsonpath斷言
name_list = Utils.base_jsonpath(res2,"$..name")
print(name_list)
assert "天津研發(fā)中心——更新" in name_list
# 刪除部門
with allure.step("刪除部門"):
self.department.delete_department(self.depart_id)
#查詢刪除是否成功(通過驗證刪除一個部門后,部門列表的長度)
with allure.step("查詢部門刪除結(jié)果"):
res3 = self.department.get_department()
#assert len(res3["department"])==4
#通過jsonpath斷言
id_list = Utils.base_jsonpath(res3,"$..id")
#操作的部門id刪除后不在部門id列表中
assert self.depart_id not in id_list