yaml文件规则说明.txt
bash
1、yaml 文件一级目录必须包括 name、request、extract、validate
2、在request一级目录下二级目录 必须包括 method、url
3、如果需要做接口关联的话,必须使用一级关键字:extract
get 请求 params 传参
post 请求
json传参,通过json关键字
表单传参 通过data关键字
文件格式 通过files关键字
如 json提取
extract:
access_token: access_token
正则表达提取
extract:
access_token: '"access_token":"(.*?)"'
当需要使用随机参数时 可以调用common_util.py 中get_random_value 方法
如
name: "ms${get_random_value(100,200)}"
common_util.py
bash
import random
class CommonUtil:
def get_random_value(self,min,max):
return random.randint(int(min),int(max))
requests_util.py
bash
import json
import re
import jsonpath as jsonpath
import requests
from pytestdemo.common.common_util import CommonUtil
from pytestdemo.common.yaml_util import read_config_file, read_extract_file, write_extract_file
class RequestsUtil:
base_url=""
def __init__(self,base,base_url):
self.base_url=read_config_file(base,base_url)
session=requests.Session()
def replace_value(self,data):
if data and isinstance(data,dict):
str=json.dumps(data)
else:
str=data
# 将变量替换成值
for a in range(1,str.count("{{")+1):
if "{{" in str and "}}" in str:
print(str)
start_index=str.index("{{")
end_index = str.index("}}")
print(start_index,end_index)
old_value=str[start_index:end_index+2]
new_value=read_extract_file(old_value[2:-2])
str=str.replace(old_value,new_value)
if data and isinstance(data,dict):
data=json.loads(str)
else:
data=str
return data
def replace_load(self,data):
if data and isinstance(data,dict):
str_value=json.dumps(data)
else:
str_value=data
# 将变量替换成值
for a in range(1,str_value.count("${")+1):
if "${" in str_value and "}" in str_value:
start_index=str_value.index("${")
end_index = str_value.index("}")
old_value=str_value[start_index:end_index+1]
fun_name=old_value[old_value.index("${")+2:old_value.index("(")]
params=old_value[old_value.index("(")+1:old_value.index(")")]
# 反射获取
new_value=getattr(CommonUtil(),fun_name)(*params.split(","))
str_value=str_value.replace(old_value,str(new_value))
if data and isinstance(data,dict):
data=json.loads(str_value)
else:
data=str_value
return data
def analysis_yml_send_reqeust(self,data):
data_key= dict(data).keys()
print(data_key)
if 'name' in data_key and 'request' in data_key and 'validate' in data_key:
# and 'extract' in data_key
request_key=dict(data["request"]).keys()
if 'method' in request_key and 'url' in request_key:
headers=None
method=data["request"]["method"]
del data["request"]["method"]
url=data["request"]["url"]
del data["request"]["url"]
if jsonpath.jsonpath(data,"$..headers") :
headers=data["request"]["headers"]
del data["request"]["headers"]
files=None
if jsonpath.jsonpath(data,"$..files"):
files=data["request"]["files"]
for key,value in dict(data["request"]["files"]).items():
files[key]=open(value,"rb")
del data["request"]["files"]
print(data["request"])
res = self.send_request(method=method
, url=url
, headers=headers
,files=files
, **data["request"]
)
return_json=res.json()
return_text=res.text
print(res.text)
if 'extract' in data_key:
for key,value in dict(data["extract"]).items():
# 正则表达式
extract_data=None
if "(.*?)" in value or "(.+?)" in value:
search_value=re.search(value,return_text)
if search_value:
extract_data=search_value.group(1)
else:
extract_data=return_json[value]
if search_value:
write_extract_file({key:extract_data})
else:
print("在request一级目录下二级目录 必须包括 method、url")
else:
print("1、yaml 文件一级目录必须包括 name、request、extract、validate")
def send_request(self,method,url,headers=None,**kwargs):
method=str(method).lower()
url=self.base_url+self.replace_value(url)
for key,value in kwargs.items():
if key in ["params","data","json"]:
kwargs[key]=self.replace_value(value)
kwargs[key] = self.replace_load(value)
res=RequestsUtil.session.request(method=method,url=url,headers=headers,**kwargs);
return res
yaml_util.py
bash
import os
import yaml
def get_path():
return os.path.abspath(os.getcwd().split("common")[0])
def read_config_file(one_node,two_node):
with open(f'{get_path()}/common/config.yml',encoding="utf-8") as f:
value=yaml.load(f,yaml.FullLoader)
# print(value[one_node][two_node])
return value[one_node][two_node]
def read_extract_file(node_name):
with open(f'{get_path()}/common/extract.yml',encoding="utf-8") as f:
value=yaml.load(f,yaml.FullLoader)
return value[node_name]
def write_extract_file(data):
with open(f'{get_path()}/common/extract.yml',encoding="utf-8",mode="a") as f:
yaml.dump(data,f,allow_unicode=True)
def clean_extract_file():
with open(f'{get_path()}/common/extract.yml',encoding="utf-8",mode="w") as f:
f.truncate()
def read_testcase_yaml(file_path):
print(f'{get_path()}{file_path}')
with open(f'{get_path()}{file_path}',encoding="utf-8") as f:
value = yaml.load(f, yaml.FullLoader)
return value
if __name__ == '__main__':
# print (read_config_file("base","base_php_url"))
print(read_testcase_yaml("\\testcases\\get_token.yml"))
config.yml
bash
base:
base_php_url: http://47.107.116.139
base_wx_url: https://api.weixin.qq.com
bash
import pytest
from pytestdemo.common.yaml_util import clean_extract_file
@pytest.fixture(scope="session",autouse=True)
def clean_extract():
clean_extract_file()
test_demo4.py
bash
import random
import pytest
from pytestdemo.common.requests_util import RequestsUtil
from pytestdemo.common.yaml_util import write_extract_file, read_testcase_yaml
class Test4Api:
access_token=""
@pytest.mark.parametrize("data",read_testcase_yaml("/testcases/get_token.yml"))
def test_get_token(self,data):
RequestsUtil("base","base_wx_url").analysis_yml_send_reqeust(data)
@pytest.mark.parametrize("data", read_testcase_yaml("/testcases/get_tags.yaml"))
def test_get_tags(self,data):
RequestsUtil("base", "base_wx_url").analysis_yml_send_reqeust(data)
@pytest.mark.parametrize("data", read_testcase_yaml("/testcases/update_tag.yml"))
def test_update_tag(self,data):
RequestsUtil("base", "base_wx_url").analysis_yml_send_reqeust(data)
@pytest.mark.parametrize("data", read_testcase_yaml("/testcases/uploadimg.yml"))
def test_uploadimg(self,data):
RequestsUtil("base", "base_wx_url").analysis_yml_send_reqeust(data)
get_token.yml
bash
- name: 获取鉴权码
request:
method: get
url: /cgi-bin/token
params:
grant_type: client_credential
appid: xxx
secret: xxx
extract:
access_token: '"access_token":"(.*?)"'
validate:
- eq:
- status_code
- 200
get_tags.yaml
bash
- name: 获取标签
request:
method: get
url: /cgi-bin/tags/get?access_token={{access_token}}
validate:
- eq:
- status_code
- 200
update_tag.yml
bash
- name: 修改标签
request:
method: post
url: /cgi-bin/tags/update?access_token={{access_token}}
json:
tag:
id: 23475
name: ms1213
keyss: "{{access_token}}"
validate:
- eq:
- status_code
- 200
uploadimg.yml
bash
- name: 修改标签
request:
method: post
url: /cgi-bin/tags/update?access_token={{access_token}}
json:
tag:
id: 23794
name: "ms${get_random_value(100,200)}"
validate:
- eq:
- status_code
- 200
uploadimg.yml
bash
- name: 修改标签
request:
method: post
url: /cgi-bin/media/uploadimg?access_token={{access_token}}
files:
media: C:\\Users\\Administrator\\Desktop\\1.jpg
validate:
- eq:
- status_code
- 200
思考问题登录失败 之后的用例需要停止执行