2023最新pytest+yaml接口自动化测试框架封装总结

1. 框架封装基础


以下是框架封装的技术基础,打好这些基础的话,能够很轻松地封装出来框架

对于基础还有欠缺的话,建议针对性精进:

1. 扎实的Python语言基础

  • 函数、类

  • 文件读写

  • 处理报错

  • 数据结构

  • 标准库

  • 测试框架库(unittest、pytest)

2. 丰富的接口测试经验

  • 请求方法

  • 请求参数

  • 响应类型

  • 数据的位置、数量

  • 接口关联

  • 数据驱动

3. 良好的代码审美

  • 文件名称

  • 变量名称

  • 代码逻辑

  • 嵌套if或者嵌套for

  • if和for彼此嵌套

  • 注释和日志记录

4. 优雅的架构设计

  • yaml文件自动读取

  • yaml文件自动保存

  • yaml内容动态替换

  • 兼容单用例测试和数据驱动测试

  • 兼容关联变量和参数化变量

  • 兼容数据提取的位置和顺序

  • 兼容数据的二次处理(类型转换、加密解密、数据库查询)

  • 兼容自定义配置

2. 框架封装目标


pytest+yaml接口自动化测试框架的设计目标有4个:

1.用法简单

测试执行人员仅需编辑yaml文件即可使用框架,完成接口自动化测试

2. 功能丰富

框架应实现以下功能,可供直接使用:

1. 项目配置

2. 接口请求

3. 接口关联

4. 接口断言

5. 数据驱动测试

6. 数据库断言

7. 日志记录

8. 测试报告

9. 其他项目特定需求

3. 维护方便

以下是框架封装的技术基础,打好这些基础的话,能够很轻松地封装出来框架

对于基础还有欠缺的话,建议针对性精进:

4. 扩展性好

用例文件应可以与框架代码分离使用,以便:

  • 为迁移测试平台打好基础

  • 为接口性能测试打好基础

3. 框架文件结构


1. 面向框架维护人员

 |--commons  # 框架核心,单独维护,和项目用例分离
 |   |`--cases.py   # 加载测试用例
 |   |`--databases.py  # 链接数据库
 |   |`--exchange.py  # 数据交换和注入
 |   |`--files.py  # 文件加载读写
 |   |`--funcs.py# 热加载函数
 |   |`--models.py# 定义用例规范
 |   |`--session.py# 二次开发requests
 |   |`--settings.py  # 加载配置文件
 |    `--templates.py  # 模板引擎
 |--requirements.txt# 框架依赖文件
 |--run.py  # 框架入口文件

2. 面向框架使用人员

 |-- data   # 数据文件
 |   |`-- private.pem  # rsa 私钥
 |    `-- public.pem  # rsa 公钥
 |-- pytest.ini # 配置文件
 `-- testcases # yaml用例存放目录

以下文件为自动生成

 |-- extract.yaml  # 数据提取文件
 |-- pytes.log # 日志文件
 |-- report  # 测试报告
 |-- temp  # 项目临时文件

4. 框架使用方法


面向框架使用人员

0. 新建空的项目

1. 编辑用例文件

title: 登录 # 用例名称

 request: # 请求参数
   method: POST
   url: https://api.tttt.one/rest-v2/login/access_token
   json:
     email: sanmu@qq.com
     password: 123123
 ​
 extract: # 响应解析
   code: [ status_code, (.*), 0 ]
 ​
 validate:
   equals: # 断言相等
     状态码断言:
       - 422     # 预期状态码
       - ${code}# 实际状态码,解析出来的变量

2. 编辑配置文件

[pytest]
 # allure报告配置
 addopts = --alluredir=temp --clean-alluredir
 ​
 ​
 # 日志文件配置
 log_file = pytes.log
 log_file_level = info
 log_file_format   = %(levelname)-8s %(asctime)s [%(name)s:%(lineno)s]  : %(message)s
 log_file_date_format  = %Y-%m-%d %H:%M:%S
 ​

3. 启动框架执行用例

框架执行前:只有2个文件,基本符合框架封装目标

框架执行命令:

 python D:\api_framework\main.py

框架执行后:

再看具体内容

终端输出

日志文件

临时变量

测试报告

4. 更复杂的用例

 feature: 用户相关
 story: 注册
 ​
 title: ${title}# P.1.用例标题使用参数化变量
 ​
 request:
   method: POST
   url: ${base_url}/login/sign_up   # C.也可以只写/login/sign_up
   json:
     email: ${email}            # P.2.参数使用变量
     password: ${str(password)}# P.3. 参数使用变量
 ​
 extract:
   code: [ status_code, (.*), 0 ]# R.1. 提取数据,用于断言或接口关联
 ​
 validate:
   equals: # 断言相等
     状态码断言:
       - ${assert_code}         # P.3. 断言也使用变量
       - ${code}                # R.2. 使用提前到的变量进行断言
 ​
 parametrize:
   - ["title","email","password","assert_code"]
   - ["账号为空","","11111111", 422]
   - ["密码均为空","1111111@qq.com","", 422]
   - ["账号密码均为空","","", 422]
   - ["账号不符合邮箱规则","11111111","1111111", 422]
   - ["注册成功","sanmu_01@qqqqqq.com","password", 200 ]
   - ["注册成功","sabmu_02@qq.com","password", 200 ]

变量的来源及优先级如下:

  1. C: 配置文件中的变量(全局常量,保存在pytest.ini)

  1. P:参数化中的变量 (DDT,保存在当前文件)

  1. R:接口响应中的变量 (接口关联,保存在extract.yaml)

如果变量相同,根据优先级取值,

如果变量名不同,可相互共存

执行结果

日志文件

测试报告

基本实现框架封装目标!

5. 框架运行流程


面向框架维护人员

1. 加载配置文件

settings.py 在框架中最先被运行,

它会加载pytest.ini中的内容,以便其他代码使用配置

如果对框架编写猴子补丁,可以考虑放在此文件中

2. 加载用例文件

cases.py 文件随后运行,搜索yaml用例文件,并自动交易yaml内容是否用例规范

  1. 搜索范围

默认为当前目录及子目录、若要指定自定目录,在配置文件中指定

例如,yaml用例文件在tests目录中,则在pytest.ini添加以下内容

 [api_test]
 case_path = 'tests'
  1. 用例规范

yaml用例【必须】包含以下字段

title:  # 用例名称
request: # 请求参数
extract: # 数据提取公式
validate: # 用例断言

根据业务场景,【可选】添加以下字段

feature: # alluer注解
story: # alluer注解
parametrize: # 数据驱动测试

缺少必填字段,校验失败

增加其他字段,自动清除

3. 生成pytest用例

case.py 文件搜索到yaml文件中后,生成pytest用例

在此环节完成数据驱动测试、allure注解

并在pytest用例中定义了接口关联和自定义断言

4. 执行用例

  1. 发送请求:session.py

  1. 接口关联:exchanger.py

  1. 热加载: funcs.py

  1. 自定义断言: models.py

5. 生成测试报告

这个没啥好说的,调用allure就是

os.system("allure generate temp -o report --clean")

6. 框架源码下载


不免费提供,有意购买可私聊

<think>我们正在构建一个基于Python接口自动化测试框架,使用pytestYAML。根据引用内容,框架的主要组件包括: - Python:主开发语言 - Requests:用于发送HTTP请求 - Pytest:测试执行与用例管理 - YAML:用于管理测试数据 - Allure:生成测试报告(可选,但常见) - Logging:用于日志记录 搭建步骤一般包括: 1. 项目结构设计 2. 封装HTTP请求(使用requests) 3. 测试数据管理(YAML文件) 4. 测试用例编写(使用pytest) 5. 测试执行与报告生成(pytest结合Allure) 6. 日志配置 下面我们按照步骤详细说明。 ### 1. 项目结构设计 典型的项目结构如下: ``` project/ ├── common/ # 公共模块 │ ├── __init__.py │ ├── request_util.py # 封装requests │ └── log_util.py # 日志配置 ├── testcases/ # 测试用例 │ ├── __init__.py │ └── test_demo.py # 测试用例文件 ├── testdata/ # 测试数据(YAML文件) │ └── demo_data.yml ├── conftest.py # pytest全局配置 ├── pytest.ini # pytest配置文件 └── requirements.txt # 依赖包 ``` ### 2. 封装HTTP请求 在`common/request_util.py`中,我们可以封装一个发送请求的类,例如: ```python import requests import logging class RequestUtil: def __init__(self): self.session = requests.Session() def send_request(self, method, url, **kwargs): logging.info(f"请求方法: {method}, 请求URL: {url}, 请求参数: {kwargs}") resp = self.session.request(method, url, **kwargs) # 可以在这里添加统一的响应处理,比如状态码检查、日志记录等 logging.info(f"响应状态码: {resp.status_code}, 响应内容: {resp.text}") return resp ``` ### 3. 测试数据管理(YAMLYAML文件用于存储测试数据,例如`testdata/demo_data.yml`: ```yaml test_case1: method: get url: http://httpbin.org/get params: key1: value1 key2: value2 expected_status: 200 ``` ### 4. 测试用例编写 使用pytest编写测试用例,结合YAML数据驱动。我们可以使用`pytest.mark.parametrize`来实现数据驱动。但是,为了更灵活地使用YAML,我们可以先读取YAML文件,然后参数化。 在`testcases/test_demo.py`中: ```python import pytest import yaml from common.request_util import RequestUtil # 读取YAML文件 def load_testdata(file_path): with open(file_path, 'r', encoding='utf-8') as f: data = yaml.safe_load(f) return data # 获取测试数据 test_data = load_testdata('../testdata/demo_data.yml') class TestDemo: @pytest.mark.parametrize('case_name, case_data', test_data.items()) def test_api(self, case_name, case_data): req = RequestUtil() method = case_data['method'] url = case_data['url'] params = case_data.get('params', {}) expected_status = case_data['expected_status'] resp = req.send_request(method, url, params=params) assert resp.status_code == expected_status ``` ### 5. 配置pytest 在项目根目录创建`pytest.ini`文件: ```ini [pytest] addopts = -v --alluredir=./allure-results testpaths = testcases python_files = test_*.py python_classes = Test* python_functions = test_* ``` ### 6. 日志配置 在`common/log_util.py`中配置日志: ```python import logging import os def setup_logging(): log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' logging.basicConfig(level=logging.INFO, format=log_format) # 在项目初始化时调用 setup_logging() ``` ### 7. 安装依赖 创建`requirements.txt`文件: ``` requests pytest pyyaml allure-pytest ``` 安装依赖: ```bash pip install -r requirements.txt ``` ### 8. 运行测试并生成报告 运行测试: ```bash pytest ``` 生成Allure报告(需要先安装Allure命令行工具): ```bash allure serve ./allure-results ``` ### 9. 使用conftest.py进行全局配置 `conftest.py`可以用于定义pytest的fixture,例如我们可以在这里初始化日志和请求工具。 ```python import pytest from common.log_util import setup_logging from common.request_util import RequestUtil @pytest.fixture(scope="session", autouse=True) def init_logging(): setup_logging() @pytest.fixture(scope="class") def req(): return RequestUtil() ``` 然后测试用例中可以这样使用: ```python class TestDemo: @pytest.mark.parametrize('case_name, case_data', test_data.items()) def test_api(self, req, case_name, case_data): method = case_data['method'] url = case_data['url'] params = case_data.get('params', {}) expected_status = case_data['expected_status'] resp = req.send_request(method, url, params=params) assert resp.status_code == expected_status ``` ### 注意事项 - 路径问题:读取YAML文件时,注意相对路径。上述示例中,测试用例文件在`testcases`目录,YAML文件在`testdata`目录,所以使用`../testdata/demo_data.yml`。也可以使用绝对路径,但建议通过配置文件管理路径。 - 封装扩展:根据实际需求,可以进一步封装断言、数据库操作等。 - 环境配置:可以设计多环境配置(如测试环境、生产环境),通过配置文件或命令行参数切换。 以上就是一个基本的框架搭建指南。根据实际项目需求,可以在此基础上进行扩展和优化。 §§相关问题§§ 1. 如何设计数据驱动测试,使得测试数据和测试用例分离? 2. 在接口自动化测试中,如何处理登录状态的保持(如cookies或token)? 3. 如何使用Allure报告来增强测试结果的可视化? 4. 如何将接口自动化测试框架集成到持续集成(CI)系统中? 5. 在接口测试中,如何对接口返回的复杂数据结构(如嵌套JSON)进行断言?</think>### Python + Pytest + YAML 接口自动化测试框架搭建指南 #### 1. 框架核心组件 ```mermaid graph TD A[测试框架] --> B[Python] A --> C[Requests] A --> D[Pytest] A --> E[YAML] A --> F[Allure] A --> G[Logging] ``` #### 2. 搭建步骤 **步骤1:环境准备** ```bash # 创建虚拟环境 python -m venv venv source venv/bin/activate # 安装依赖 pip install requests pytest pyyaml allure-pytest pytest-html ``` **步骤2:项目结构设计** ``` project/ ├── common/ # 公共模块 │ ├── request_util.py # 请求封装 │ └── log_util.py # 日志工具 ├── testcases/ # 测试用例 │ ├── __init__.py │ └── test_api.py # 测试脚本 ├── testdata/ # 测试数据 │ └── api_data.yml # YAML数据文件 ├── conftest.py # pytest全局配置 ├── pytest.ini # pytest配置文件 └── requirements.txt # 依赖清单 ``` **步骤3:封装HTTP请求(request_util.py)** ```python import requests import logging class RequestUtil: def __init__(self): self.session = requests.Session() logging.basicConfig(level=logging.INFO) def send_request(self, method, url, **kwargs): """统一请求入口""" logging.info(f"请求参数: {method} {url} {kwargs}") resp = self.session.request(method, url, **kwargs) logging.info(f"响应状态: {resp.status_code}, 响应内容: {resp.text[:200]}") return resp ``` **步骤4:YAML测试数据管理(testdata/api_data.yml)** ```yaml login_test: description: "用户登录接口测试" request: method: POST url: "/api/login" headers: Content-Type: "application/json" json: username: "testuser" password: "Pass123" validate: - eq: [status_code, 200] - contains: [content, "token"] ``` **步骤5:测试用例编写(testcases/test_api.py)** ```python import pytest import yaml from common.request_util import RequestUtil # 加载YAML测试数据 def load_testdata(file_path): with open(file_path, 'r') as f: return yaml.safe_load(f) test_data = load_testdata('../testdata/api_data.yml') class TestAPI: @pytest.mark.parametrize("case_name", test_data.keys()) def test_api(self, case_name): data = test_data[case_name] req = RequestUtil() resp = req.send_request( data['request']['method'], data['request']['url'], headers=data['request'].get('headers', {}), json=data['request'].get('json', {}) ) # 断言验证 for validate in data['validate']: key, expected = validate['eq'] if key == "status_code": assert resp.status_code == expected elif key == "content": assert expected in resp.text ``` **步骤6:配置全局Fixture(conftest.py)** ```python import pytest @pytest.fixture(scope="session", autouse=True) def setup(): print("\n>>> 测试开始 <<<") yield print("\n>>> 测试结束 <<<") ``` **步骤7:Pytest配置(pytest.ini)** ```ini [pytest] addopts = -v --alluredir=./allure-results --html=report.html testpaths = testcases python_files = test_*.py python_classes = Test* python_functions = test_* ``` #### 3. 执行测试 ```bash # 运行测试 pytest # 生成Allure报告 allure serve allure-results # 生成HTML报告(直接查看report.html) ``` #### 4. 关键优化点 1. **参数化驱动**:通过YAML实现测试数据与代码分离 2. **动态关联**:使用`pytest`的`fixture`处理token传递 ```python @pytest.fixture def auth_token(): # 获取登录token并传递给测试用例 return get_token() ``` 3. **异常处理**:在请求封装中添加重试机制 ```python from tenacity import retry, stop_after_attempt @retry(stop=stop_after_attempt(3)) def send_request(self, method, url, **kwargs): ... ``` 4. **多环境配置**:使用`pytest-base-url`插件切换测试环境 ```bash pytest --base-url https://api.test.com ``` #### 5. 框架优势 1. **可维护性**:YAML数据驱动便于非技术人员维护测试用例 2. **扩展性**:模块化设计支持添加数据库校验、消息队列等组件 3. **可视化报告**:Allure提供多维度测试分析 4. **CI/CD集成**:通过`pytest`命令轻松接入Jenkins/GitHub Actions[^3]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值