下面是一套基于 Python+Requests+pytest+allure+yaml+DDT+logs 的自动化测试框架示例:
-
Python 3.6 或更高版本
-
requests 库:用于发送 HTTP 请求和处理响应
-
pytest 测试框架:用于编写和运行测试用例
-
allure 测试报告工具:用于生成漂亮的测试报告
-
PyYAML 库:用于读取和解析 YAML 格式的配置文件
-
DDT 库:用于数据驱动测试
-
logging 库:用于记录日志信息
下面是一个示例目录结构:
- project - config - config.yml - data - data.csv - logs - app.log - tests - test_case.py - utils - api_client.py - logger.py - report.py - pytest.ini
- config: 存放配置文件
- data: 存放测试数据
- logs: 存放日志文件
- tests: 存放测试用例
- utils: 存放工具函数
config.yml 配置文件示例:
BASE_URL: https://api.example.com TIMEOUT: 30 HEADERS: Content-Type: application/json
data.csv 测试数据示例:
username,password,expected_code test1,test1password,200 test2,test2password,401
test_case.py 测试用例示例:
import pytest import allure from ddt import ddt, data, unpack from utils.api_client import APIClient @ddt class TestLogin: @allure.feature('Login') @allure.story('Login with valid credentials') @data(('test1', 'test1password', 200)) @unpack def test_login_with_valid_credentials(self, username, password, expected_code): api_client = APIClient() response = api_client.login(username, password) assert response.status_code == expected_code @allure.feature('Login') @allure.story('Login with invalid credentials') @data(('test2', 'test2password', 401)) @unpack def test_login_with_invalid_credentials(self, username, password, expected_code): api_client = APIClient() response = api_client.login(username, password) assert response.status_code == expected_code
api_client.py 工具函数示例:
import requests import yaml from utils.logger import logger class APIClient: def __init__(self): self.config = self.load_config() self.base_url = self.config['BASE_URL'] self.headers = self.config['HEADERS'] self.timeout = self.config['TIMEOUT'] def load_config(self): with open('config/config.yml', 'r') as f: return yaml.safe_load(f) def login(self, username, password): url = f'{self.base_url}/login' data = { 'username': username, 'password': password } logger.info(f'Sending login request to {url}') response = requests.post(url, json=data, headers=self.headers, timeout=self.timeout) logger.info(f'Received login response with status code {response.status_code}') return response
logger.py 工具函数示
import logging from logging.handlers import RotatingFileHandler import os class Logger: def __init__(self, name=__name__, log_file='app.log', log_level=logging.DEBUG): self.logger = logging.getLogger(name) self.logger.setLevel(log_level) formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s)') console
report.py 工具函数示例:
import os import shutil import allure from datetime import datetime def pytest_sessionfinish(session, exitstatus): report_dir = 'allure_report' report_zip = 'allure_report.zip' if os.path.exists(report_dir): shutil.rmtree(report_dir) os.system(f'allure generate allure_results -o {report_dir}') os.system(f'zip -r {report_zip} {report_dir}') allure.attach.file(report_zip, 'Test Report', attachment_type=allure.attachment_type.ZIP) def pytest_html_results_table_row(report, cells): if report.passed: del cells[:] cells.append(allure.model.TestResult.NONE) cells.append(allure.model.TestResult.PASSED) cells.append(report.nodeid) cells.append(report.head_line) cells.append(report.duration)
pytest.ini 配置文件示例:
[pytest] log_cli = 1 log_cli_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s) log_cli_date_format=%Y-%m-%d %H:%M:%S log_file = logs/app.log log_file_format = %(asctime)s [%(levelname)s] %(message)s (%(filename)s:%(lineno)s) log_file_date_format=%Y-%m-%d %H:%M:%S addopts = -s -q --alluredir allure_results
上述示例中,我们使用了 logging 模块记录日志信息,通过 PyYAML 库读取配置文件,使用 allure 生成测试报告,使用 DDT 实现数据驱动测试。在 pytest.ini 配置文件中,我们设置了日志的输出格式和位置,并使用了 pytest-allure 插件将测试结果输出到 allure_results 目录。
可以根据自己的需求和实际情况,对上述示例进行调整和扩展。