yaml是一种数据格式,支持注释,通过#注释
map对象,又称:字典dist {name: 百里}
数组:又称:列表list [{name: 白里1},{name: 白里2},{name: 白里3} ]
# MAP对象
# 两种格式
泡泡: {name: "泡泡"}
可可:
name: "可可"
# 数组
数组1: [{name: 可可1},{name: 可可2},{name: 可可3}]
数组2:
- name: "可可1"
- name: "可可2"
- name: "可可3"
import yaml
class YamlUtil:
def __init__(self,yaml_path):
self.yaml_path = yaml_path
# 读取 dist or list
def read_yaml(self):
with open(self.yaml_path,"r",encoding="utf-8") as f:
yaml_data = yaml.load(f,Loader=yaml.FullLoader)
return yaml_data
if __name__ == '__main__':
res = YamlUtil('test.yaml').read_yaml()
print(res)
# [{'name': '测试读取', 'request': {'method': 'GET', 'url': 'www.baidu.com', 'data': {'type': 'client'}}, 'validate': [{'equals': {'status': 200}}, {'contains': 'access_code'}]}]
import unittest
from ddt import file_data, ddt
@ddt
class GzhCase(unittest.TestCase):
# 这个装饰器可以读取文件
@file_data('test.yaml')
def test_01_get_token(self, **kwargs):
print(kwargs)
print(kwargs['name'])
print(kwargs['validate'])
if __name__ == '__main__':
unittest.main()
AttributeError: type object 'GzhCase' has no attribute 'test_01_get_token'
支持python2.7,推荐3.7
安装httprunner (pip install httprunner,pip install har2case)
建议使用低版本的httprunner进行联系,或者学习一些4.x的操作:httprunner4.x
五个命令
命令 | |
---|---|
httprunner | 主命令 |
hrun | httprunner的别名,用于运行yaml/json/pytest测试用例 |
hmake | httprunner make的别名,将yaml/json转化成pytest文件 |
har2case | httprunner har2case的别名,用于将har文件转化成yaml/json文件 |
locust | 用于性能测试 |
命令 | |
---|---|
har2case xxx.har | py文件的测试用例 |
har2case xxx.har -2y | yaml文件的测试用例 |
har2case xxx.har -2j | json文件的测试用例 |
D:\PyCharm\Code\demo3\httprunner>har2case getTianqi.har -2y
D:\PyCharm\Code\demo3\httprunner>hrun getTianqi.yml
这里我重新下载了hrun的版本 pip install httprunner==2.3.0
# demo_api.yml 写一条测试用例
name: 测试 api
variables:
var1: value1
var2: value2
request:
url: https://eolink.o.apispace.com/xhdq/common/joke/getJokesByRandom
method: POST
headers:
X-APISpace-Token: "xxxxxxxxxxxxxxxxxxx"
Authorization-Type: "apikey"
Content-Type: "application/x-www-form-urlencoded"
data:
pageSize: 5
validate:
- eq: ["status_code", 200]
python 中非常流行的客户端请求模块,功能强大,api清晰明了
request | |
---|---|
method | GET,OPTIONS,HEAD,POST,PUT,PATCH,DELETE |
url | 指定请求的url |
headers | 指定请求头参数 |
params | 指定查询字符串参数 |
json | 传json格式的参数 |
data | 传www-form表单参数 |
01 环境变量 |
request:
url: https://eolink.o.apispace.com/456456/weather/v001/now
method: GET
headers:
X-APISpace-Token: "xxxxxxxxxxxxxxxxxxxxxx"
Authorization-Type: "apikey"
params: # 指定查询的字符串
areacode: ${ENV(AREACODE)} # 调用环境变量
validate:
- eq: ["status_code", 200]
D:\PyCharm\Code\demo5_hrun>hrun api/demo_api.yml --log-level debug
INFO HttpRunner version: 2.3.0
INFO Loading environment variables from D:\PyCharm\Code\demo5_hrun\.env
# 这里创建了环境变量
DEBUG Set OS environment variable: AREACODE
...
================== request details ==================
# 可以看到查询的url中拼接了参数 areacode=101010100
url : 'https://eolink.o.apispace.com/456456/weather/v001/now?areacode=101010100'
02 全局变量 |
$xxx
调用全局变量# birth_api.yml
name: 测试 api2
# 定义全局变量
variables:
moon: "12"
day: "15"
request:
url: https://eolink.o.apispace.com/birthday-pwd/api/v1/xzw/birthday_pwd/
method: GET
headers:
xxxx: "xxxxx"
params:
moon: $moon
day: $day
validate:
- eq: ["status_code", 200]
03 httprunner_debugtalk.py |
${函数名()}
调用# debugtalk.py
import random
def get_moon():
moon = ["1","2","3","4","5","6","7","8","9","10","11","12"]
return random.choice(moon)
# birth_api.yml
params:
moon: ${get_moon()}
04 httprunner_baseurl |
# base_url提取url中公共的域名部分
base_url: https://eolink.o.apispace.com
request:
url: /birthday-pwd/api/v1/xzw/birthday_pwd/
05 断言 |
validate:
- eq: ["status_code", 201]
# 断言失败,实际与期望结果不符
DEBUG start to validate.
DEBUG extract: status_code => 200
ERROR
validate: status_code equals 201(int) ==> fail
200(int) equals 201(int)
validate:
#- eq: ["status_code", 200]
- {"check": "status_code", "comparator": "eq", "expect": 200}
- {"check": "content", "comparator": "contains", "expect": "message"}
- {"check": "content.message", "comparator": "eq", "expect": "OK"}
testcase
目录下定义接口依赖关系
config:
name: "获取项目列表信息配置"
base_url: https://eolink.o.apispace.com
# 测试步骤
teststeps:
-
name: 登录
api: api/login.yml
extract:
# 把响应报文中的 token 取出来
- # 创建一个token的变量
- token: content.token
-
name: 获取项目列表信息
# 在api/get_list.yml可以调用token ($token)
api: api/get_list.yml
name: 测试login
variables:
username: "kk"
password: "pwd"
base_url: https://eolink.o.apispace.com
request:
url: /api/login/
method: POST
headers:
Content-Type : "application/json"
json:
username: $username
password: $password
validate:
- {"check": "status_code", "comparator": "eq", "expect": 200}
config:
name: "登录接口配置"
base_url: https://eolink.o.apispace.com
teststeps:
-
name: $title
api: api/login.yml
validate:
- {"check": "status_code", "comparator": "eq", "expect": $status_code}
- {"check": "content", "comparator": "contains", "expect": $contain_msg}
config:
name: "接口套件"
testcases:
-
name: 登录接口套件
testcase: testcases/login_testcase.yml
parameters:
# 方式一: 直接在当前文件下,添加用例信息
- title-username-password-status_code-contain_msg:
- ["正常登陆","keyou1","123456",200,"token"]
- ["密码错误","keyou1","111111",400,"non_field_errors"]
- ["账号错误","keyou1111","123456",400,"non_field_errors"]
- ["用户名为空","","123456",400,"username"]
- ["密码为空","keyou1","",400,"password"]
parameters:
# 方式二:
- title-username-password-status_code-contain_msg: ${P(datas/account.csv)}
def get_account():
# 嵌套字典列表
accounts = [
{"title": "正常登陆", "username": "keyou1", "password": "123456", "status_code": 200, "contain_msg": "token"},
{"title": "密码错误", "username": "keyou1", "password": "111111", "status_code": 400, "contain_msg": "non_field_errors"},
{"title": "账号错误", "username": "keyou1111", "password": "123456", "status_code": 400, "contain_msg": "non_field_errors"},
{"title": "用户名为空", "username": "", "password": "123456", "status_code": 400, "contain_msg": "username"},
{"title": "密码为空", "username": "keyou1", "password": "", "status_code": 400, "contain_msg": "password"}
]
return accounts
${函数名()}
parameters:
# 方式三:
- title-username-password-status_code-contain_msg: ${get_account()}
# run.py
from httprunner.api import HttpRunner
httprun = HttpRunner()
httprun.run(r"D:\PyCharm\Code\demo5_hrun\testsuites\login_suit.yml")
print(httprun.summary)