httprunner 用 yaml 文件实现接口自动化框架很好用,最近在看 pytest 框架,于是参考 httprunner的用例格式,写了一个差不多的 pytest 版的简易框架
项目结构完全符合 pytest 的项目结构,pytest 是查找 test_.py 文件,我这里是查找 test_.yml 文件,唯一不同的就是这个地方
以前写test_*.py 的测试用例,现在完全不用写了,全部写yaml 文件就行,项目结构参考

只需在 conftest.py 即可实现,代码量超级少
pytest 7.x最新版
- def pytest_collect_file(parent, file_path):
- # 获取文件.yml 文件,匹配规则
- if file_path.suffix == ".yml" and file_path.name.startswith("test"):
- return YamlFile.from_parent(parent, path=file_path)
-
pytest 5.x以上版本
- import pytest
- import requests
-
-
- def pytest_collect_file(parent, path):
- # 获取文件.yml 文件,匹配规则
- if path.ext == ".yml" and path.basename.startswith("test"):
- # print(path)
- # print(parent)
- # return YamlFile(path, parent)
- return YamlFile.from_parent(parent, fspath=path)
-
-
- class YamlFile(pytest.File):
- # 读取文件内容
- def collect(self):
- import yaml
- raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))
- for yaml_case in raw:
- name = yaml_case["test"]["name"]
- values = yaml_case["test"]
- yield YamlTest.from_parent(self, name=name, values=values)
-
- class YamlTest(pytest.Item):
- def __init__(self, name, parent, values):
- super(YamlTest, self).__init__(name, parent)
- self.name = name
- self.values = values
- self.request = self.values.get("request")
- self.validate = self.values.get("validate")
- self.s = requests.session()
-
- def runtest(self):
- # 运行用例
- request_data = self.values["request"]
- # print(request_data)
- response = self.s.request(**request_data)
- print("\n", response.text)
- # 断言
- self.assert_response(response, self.validate)
-
- def assert_response(self, response, validate):
- '''设置断言'''
- import jsonpath
- for i in validate:
- if "eq" in i.keys():
- yaml_result = i.get("eq")[0]
- actual_result = jsonpath.jsonpath(response.json(), yaml_result)
- expect_result = i.get("eq")[1]
- print("实际结果:%s" % actual_result)
- print("期望结果:%s" % expect_result)
- assert actual_result[0] == expect_result
pytest 4.x 以下版本
- import pytest
- import requests
- # 作者-上海悠悠 QQ交流群:717225969
- # blog地址 https://www.cnblogs.com/yoyoketang/
-
-
- def pytest_collect_file(parent, path):
- # 获取文件.yml 文件,匹配规则
- if path.ext == ".yml" and path.basename.startswith("test"):
- # print(path)
- # print(parent)
- return YamlFile(path, parent)
-
-
-
- class YamlFile(pytest.File):
- # 读取文件内容
- def collect(self):
- import yaml
- raw = yaml.safe_load(self.fspath.open(encoding='utf-8'))
- for yaml_case in raw:
- name = yaml_case["test"]["name"]
- values = yaml_case["test"]
- yield YamlTest(name, self, values)
-
-
- class YamlTest(pytest.Item):
- def __init__(self, name, parent, values):
- super(YamlTest, self).__init__(name, parent)
- self.name = name
- self.values = values
- self.request = self.values.get("request")
- self.validate = self.values.get("validate")
- self.s = requests.session()
-
- def runtest(self):
- # 运行用例
- request_data = self.values["request"]
- # print(request_data)
- response = self.s.request(**request_data)
- print("\n", response.text)
- # 断言
- self.assert_response(response, self.validate)
-
- def assert_response(self, response, validate):
- '''设置断言'''
- import jsonpath
- for i in validate:
- if "eq" in i.keys():
- yaml_result = i.get("eq")[0]
- actual_result = jsonpath.jsonpath(response.json(), yaml_result)
- expect_result = i.get("eq")[1]
- print("实际结果:%s" % actual_result)
- print("期望结果:%s" % expect_result)
- assert actual_result[0] == expect_result
-
断言这部分,目前只写了判断相等,仅供参考,支持jsonpath来提取json数据
在项目的任意目录,只要是符合test_开头的yml文件,我们就认为是测试用例
test_login.yml的内容如下
- - test:
- name: login case1
- request:
- url: http://49.235.x.x:7000/api/v1/login/
- method: POST
- headers:
- Content-Type: application/json
- User-Agent: python-requests/2.18.4
- json:
- username: test
- password: 123456
- validate:
- - eq: [$.msg, login success!]
- - eq: [$.code, 0]
-
-
- - test:
- name: login case2
- request:
- url: 49.235.x.x:7000/api/v1/login/
- method: POST
- headers:
- Content-Type: application/json
- User-Agent: python-requests/2.18.4
- json:
- username: test
- password: 123456
- validate:
- - eq: [$.msg, login success!]
- - eq: [$.code, 0]
-
运行用例,完全符合pytest的只需用例风格,支持allure报告
pytest -v
- D:\soft\api_pytest_1208>pytest -v
- ====================== test session starts ======================
- platform win32 -- Python 3.6.6, pytest-4.5.0, py-1.9.0,
- cachedir: .pytest_cache
- rootdir: D:\soft\api_pytest_1208
- plugins: allure-pytest-2.8.6
- collected 4 items
-
- data/test_login.yml::login case1 PASSED [ 25%]
- data/test_login.yml::login case2 PASSED [ 50%]
- data/test_login1.yml::login case1 PASSED [ 75%]
- data/test_login1.yml::login case2 PASSED [100%]
-
- =================== 4 passed in 1.34 seconds ====================
allure报告
pytest --alluredir ./report
目前是把 yaml 文件下每个 test 当一个用例执行,后续还可以加上提取参数,参数关联更高级的功能!
这可能是B站最详细的pytest自动化测试框架教程,整整100小时,全程实战!!!