一个完整的企业级接口自动化测试解决方案
接口自动化测试作为现代软件开发流程的核心环节,已成为保障系统质量、提升交付效率的关键手段。本项目基于Python技术栈,构建了一套完整的接口自动化测试解决方案,旨在为开发团队提供高效、稳定、易维护的API测试框架。
本项目选择 Restful Booker API 作为被测系统:
技术组件 | 版本 | 用途说明 |
---|---|---|
Python | 3.8+ | 主要编程语言,提供丰富的测试生态 |
pytest | 7.4.3 | 现代化测试框架,支持丰富的插件 |
requests | 2.31.0 | HTTP客户端库,用于API调用 |
PyMySQL | 1.1.0 | MySQL数据库连接和操作 |
loguru | 0.7.2 | 现代化日志记录库 |
allure-pytest | 2.13.2 | 美观的测试报告生成 |
Faker | 19.12.0 | 测试数据生成库 |
Jinja2 | 3.0+ | 模板引擎,用于报告生成 |
Jenkins | 2.0+ | 持续集成平台 |
接口自动化测试项目/
├── 配置管理
│ ├── config/
│ │ ├── config.py # 主配置文件
│ │ └── database.py # 数据库配置
│ ├── .env # 环境变量配置
│ ├── pytest.ini # pytest配置
│ └── conftest.py # pytest全局配置
│
├── 测试用例
│ └── testcases/
│ ├── test_auth.py # 认证接口测试(5个用例)
│ └── test_booking.py # 预订管理测试(16个用例)
│
├── ️ 工具服务
│ └── utils/
│ ├── api_client.py # HTTP客户端封装
│ ├── database_helper.py # 数据库操作封装
│ ├── logger.py # 日志工具
│ └── report_generator.py # 报告生成器
│
├── 数据管理
│ ├── data/
│ │ ├── test_data.json # 测试数据配置
│ │ └── sql/ # SQL脚本目录
│ ├── logs/ # 日志文件目录
│ └── reports/ # 测试报告目录
│
├── 执行脚本
│ ├── run_tests.py # 主测试执行脚本
│ ├── install.py # 环境安装脚本
│ ├── init_database.py # 数据库初始化脚本
│ ├── generate_test_data.py # 测试数据生成脚本
│ └── test_example.py # 功能验证脚本
│
├── 项目文档
│ ├── README.md # 项目说明文档
│ ├── QUICKSTART.md # 快速开始指南
│ └── 项目总结.md # 项目总结报告
│
├── CI/CD配置
│ ├── Jenkinsfile # Jenkins流水线配置
│ └── requirements.txt # Python依赖包
│
└── 其他文件
├── .gitignore # Git忽略文件
└── LICENSE # 开源协议
目录/文件 | 说明 | 重要程度 |
---|---|---|
config/ |
配置文件目录,包含所有配置相关文件 | ⭐⭐⭐⭐⭐ |
testcases/ |
测试用例目录,包含所有测试脚本 | ⭐⭐⭐⭐⭐ |
utils/ |
工具类目录,提供各种工具函数 | ⭐⭐⭐⭐⭐ |
data/ |
数据目录,包含测试数据和SQL脚本 | ⭐⭐⭐⭐ |
reports/ |
报告目录,存放生成的测试报告 | ⭐⭐⭐⭐ |
logs/ |
日志目录,存放运行日志 | ⭐⭐⭐ |
run_tests.py |
主执行脚本,提供便捷的测试执行 | ⭐⭐⭐⭐⭐ |
Jenkinsfile |
CI/CD配置,用于持续集成 | ⭐⭐⭐⭐ |
组件 | 版本要求 | 说明 |
---|---|---|
操作系统 | Windows 10+, macOS 10.14+, Ubuntu 18.04+ | 支持主流操作系统 |
Python | 3.8+ | 推荐使用Python 3.9或3.10 |
MySQL | 5.7+ | 可选,用于测试结果存储 |
Git | 2.0+ | 用于代码版本管理 |
# 检查Python版本
python3 --version
# 输出示例: Python 3.9.7
# 检查pip版本
pip3 --version
# 输出示例: pip 21.2.4
组件 | 用途 | 安装方式 |
---|---|---|
Allure | 生成美观的测试报告 | npm install -g allure-commandline |
Jenkins | 持续集成平台 | 官网下载安装 |
Docker | 容器化部署 | 官网下载安装 |
# 1. 克隆项目
git clone <项目地址>
cd 接口自动化测试项目
# 2. 运行自动安装脚本
python3 install.py
# 3. 验证安装
python3 test_example.py
# 1. 创建虚拟环境
python3 -m venv venv
source venv/bin/activate
# 2. 升级pip
pip install --upgrade pip
# 3. 安装依赖
pip install -r requirements.txt
# 4. 配置环境变量
cp .env.example .env
# 编辑.env文件,配置数据库等信息
# 5. 初始化数据库(可选)
python3 init_database.py
# 6. 验证安装
python3 test_example.py
# 1. 创建虚拟环境
python -m venv venv
venv\Scripts\activate
# 2. 升级pip
pip install --upgrade pip
# 3. 安装依赖
pip install -r requirements.txt
# 4. 配置环境变量
copy .env.example .env
# 使用记事本编辑.env文件
# 5. 初始化数据库(可选)
python init_database.py
# 6. 验证安装
python test_example.py
如果需要使用数据库功能:
# 1. 启动MySQL服务
# Mac: brew services start mysql
# Windows: net start mysql
# Linux: sudo systemctl start mysql
# 2. 创建数据库
mysql -u root -p
CREATE DATABASE api_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 3. 配置.env文件
DATABASE_ENABLED=true
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=api_test
# 4. 初始化数据库
python3 init_database.py
运行验证脚本确保所有组件正常工作:
python3 test_example.py
预期输出:
============================================================
接口自动化测试项目 - 功能验证
============================================================
测试模块导入...
✅ config.config
✅ utils.logger
✅ utils.api_client
✅ utils.database_helper
✅ 所有模块导入成功
⚙️ 测试配置...
✅ 配置验证通过
测试API客户端...
✅ API客户端连接正常
️ 测试数据库连接...
✅ 数据库连接正常
测试认证API...
✅ 认证API正常
============================================================
测试结果总结
============================================================
总测试数: 6
通过数: 6
失败数: 0
通过率: 100.0%
所有测试通过!项目配置正确,可以开始使用。
# 运行冒烟测试(推荐首次使用)
python3 run_tests.py --suite smoke
# 查看帮助信息
python3 run_tests.py --help
# 执行所有测试
python3 run_tests.py
# 执行冒烟测试(核心功能验证)
python3 run_tests.py --suite smoke
# 执行回归测试(全面功能验证)
python3 run_tests.py --suite regression
# 执行认证相关测试
python3 run_tests.py --suite auth
# 执行预订管理测试
python3 run_tests.py --suite booking
# 在生产环境执行测试
python3 run_tests.py --env production
# 在测试环境执行测试
python3 run_tests.py --env staging
# 使用4个进程并发执行
python3 run_tests.py --parallel 4
# 自动检测CPU核心数并发执行
python3 run_tests.py --parallel auto
# 生成HTML报告
python3 run_tests.py --report html
# 生成Allure报告
python3 run_tests.py --report allure
# 生成所有类型报告
python3 run_tests.py --report both
# 详细输出模式
python3 run_tests.py --verbose
# 禁用数据库功能
python3 run_tests.py --no-db
# 清理旧的测试结果
python3 run_tests.py --clean
# 组合使用
python3 run_tests.py --suite regression --parallel 4 --verbose --report both
# 基础执行
pytest
# 按标记执行
pytest -m smoke # 冒烟测试
pytest -m regression # 回归测试
pytest -m "auth or booking" # 认证或预订测试
pytest -m "smoke and not slow" # 冒烟测试但排除慢速测试
# 按文件执行
pytest testcases/test_auth.py # 执行认证测试文件
pytest testcases/test_booking.py # 执行预订测试文件
# 按测试方法执行
pytest testcases/test_auth.py::TestAuth::test_auth_with_valid_credentials
# 并发执行
pytest -n 4 # 4进程并发
pytest -n auto # 自动检测进程数
# 生成报告
pytest --html=reports/report.html --self-contained-html
pytest --alluredir=reports/allure-results
# 详细输出
pytest -v # 详细模式
pytest -s # 显示print输出
pytest -vv # 更详细模式
# 失败重试
pytest --maxfail=1 # 第一个失败后停止
pytest --tb=short # 简短的错误信息
# 初始化数据库
python3 init_database.py
# 查看数据库状态
python3 -c "
from utils.database_helper import DatabaseHelper
from config.config import Config
from utils.logger import setup_logger
logger = setup_logger()
db = DatabaseHelper(Config, logger)
print('数据库连接正常')
"
# 生成测试数据
python3 generate_test_data.py
# 查看生成的数据
cat data/test_data.json
# 查看最新日志
tail -f logs/api_test.log
# 查看错误日志
tail -f logs/api_test_error.log
# 搜索特定内容
grep "ERROR" logs/api_test.log
grep "test_auth" logs/api_test.log
# 生成并打开HTML报告
python3 run_tests.py --report html
open reports/report.html # Mac
start reports/report.html # Windows
xdg-open reports/report.html # Linux
# 生成Allure数据
python3 run_tests.py --report allure
# 启动Allure服务查看报告
allure serve reports/allure-results
# 生成静态Allure报告
allure generate reports/allure-results -o reports/allure-report --clean
# 生成自定义报告(需要数据库)
python3 -c "
from utils.report_generator import ReportGenerator
from utils.database_helper import DatabaseHelper
from config.config import Config
from utils.logger import setup_logger
logger = setup_logger()
db = DatabaseHelper(Config, logger)
generator = ReportGenerator(db)
generator.generate_html_report('reports/custom_report.html')
print('自定义报告生成完成')
"
# 查看自定义报告
open reports/custom_report.html
# 启用调试日志
export LOG_LEVEL=DEBUG
python3 run_tests.py --suite smoke --verbose
# 单步调试特定测试
pytest testcases/test_auth.py::TestAuth::test_auth_with_valid_credentials -s -vv
# 测试网络连接
curl -I https://restful-booker.herokuapp.com/ping
# 测试API可用性
python3 -c "
import requests
response = requests.get('https://restful-booker.herokuapp.com/ping')
print(f'状态码: {response.status_code}')
print(f'响应: {response.text}')
"
# 测试数据库连接
mysql -h localhost -u root -p -e "SELECT 1"
# 检查数据库配置
python3 -c "
from config.config import Config
print(f'数据库主机: {Config.DB_HOST}')
print(f'数据库端口: {Config.DB_PORT}')
print(f'数据库名称: {Config.DB_NAME}')
print(f'数据库启用: {Config.DATABASE_ENABLED}')
"
测试模块 | 用例数量 | 覆盖功能 | 执行时间 |
---|---|---|---|
认证测试 | 5个 | 用户认证、权限验证 | ~10秒 |
预订管理 | 16个 | CRUD操作、异常处理 | ~30秒 |
总计 | 21个 | 完整业务流程 | ~40秒 |
@pytest.mark.smoke
, @pytest.mark.auth
@pytest.mark.regression
, @pytest.mark.auth
@pytest.mark.smoke
, @pytest.mark.booking
@pytest.mark.smoke
, @pytest.mark.booking
{
"firstname": "John",
"lastname": "Doe",
"totalprice": 100,
"depositpaid": true,
"bookingdates": {
"checkin": "2024-01-01",
"checkout": "2024-01-02"
},
"additionalneeds": "Breakfast"
}
@pytest.mark.smoke
, @pytest.mark.booking
@pytest.mark.regression
, @pytest.mark.booking
@pytest.mark.regression
, @pytest.mark.booking
@pytest.mark.regression
, @pytest.mark.booking
@pytest.mark.regression
, @pytest.mark.booking
@pytest.mark.regression
, @pytest.mark.booking
{
"valid_booking_data": {
"firstname": "John",
"lastname": "Doe",
"totalprice": 100,
"depositpaid": true,
"bookingdates": {
"checkin": "2024-01-01",
"checkout": "2024-01-02"
},
"additionalneeds": "Breakfast"
}
}
{
"invalid_booking_data": {
"firstname": "",
"lastname": "",
"totalprice": -1,
"depositpaid": "invalid",
"bookingdates": {
"checkin": "invalid-date",
"checkout": "invalid-date"
}
}
}
# 执行命令
python3 run_tests.py --suite smoke --verbose
# 预期输出
============================================================
接口自动化测试执行脚本
============================================================
执行时间: 2025-06-29 09:45:37
测试套件: smoke
测试环境: production
并发进程: 1
报告类型: both
详细模式: 是
数据库功能: 启用
============================================================
==================================================
接口自动化测试开始执行
开始时间: 2025-06-29 09:45:38
==================================================
=== test session starts ===
collected 21 items / 17 deselected / 4 selected
testcases/test_auth.py::TestAuth::test_auth_with_valid_credentials PASSED [ 25%]
testcases/test_booking.py::TestBooking::test_ping_health_check PASSED [ 50%]
testcases/test_booking.py::TestBooking::test_get_booking_list PASSED [ 75%]
testcases/test_booking.py::TestBooking::test_create_booking PASSED [100%]
==================================================
接口自动化测试执行完成
结束时间: 2025-06-29 09:45:42
退出状态: 0
==================================================
============================================================
测试执行总结
============================================================
✅ 测试执行成功
退出代码: 0
结束时间: 2025-06-29 09:45:42
报告位置:
HTML报告: reports/report.html
Allure报告: reports/allure-results
自定义报告: reports/custom_report.html
============================================================
# 执行命令
python3 run_tests.py --suite regression
# 预期统计
总用例数: 17个
通过用例: 15-17个
失败用例: 0-2个
跳过用例: 0个
执行时间: 30-60秒
通过率: 85-100%
# 执行命令
python3 run_tests.py --parallel 4
# 预期性能
执行时间: 减少50-70%
资源占用: CPU使用率提升
稳定性: 无并发冲突
成功率: 与串行执行一致
成功认证响应:
{
"token": "abc123def456ghi789"
}
失败认证响应:
{
"reason": "Bad credentials"
}
获取预订列表:
[
{"bookingid": 1},
{"bookingid": 2},
{"bookingid": 3}
]
创建预订成功:
{
"bookingid": 123,
"booking": {
"firstname": "John",
"lastname": "Doe",
"totalprice": 100,
"depositpaid": true,
"bookingdates": {
"checkin": "2024-01-01",
"checkout": "2024-01-02"
},
"additionalneeds": "Breakfast"
}
}
获取预订详情:
{
"firstname": "John",
"lastname": "Doe",
"totalprice": 100,
"depositpaid": true,
"bookingdates": {
"checkin": "2024-01-01",
"checkout": "2024-01-02"
},
"additionalneeds": "Breakfast"
}
404 未找到:
状态码: 404
响应体: Not Found
405 方法不允许:
状态码: 405
响应体: Method Not Allowed
接口类型 | 平均响应时间 | 95%响应时间 | 最大响应时间 |
---|---|---|---|
认证接口 | < 2秒 | < 3秒 | < 5秒 |
查询接口 | < 1.5秒 | < 2.5秒 | < 4秒 |
创建接口 | < 2秒 | < 3秒 | < 5秒 |
更新接口 | < 2秒 | < 3秒 | < 5秒 |
删除接口 | < 1.5秒 | < 2.5秒 | < 4秒 |
测试类型 | 目标成功率 | 实际成功率 | 说明 |
---|---|---|---|
冒烟测试 | 100% | 100% | 核心功能必须全部通过 |
回归测试 | ≥95% | 95-100% | 允许少量非核心功能失败 |
并发测试 | ≥90% | 90-100% | 考虑网络波动影响 |
压力测试 | ≥85% | 85-95% | 高负载下的表现 |
资源类型 | 预期使用量 | 实际使用量 | 优化建议 |
---|---|---|---|
内存 | < 100MB | 50-80MB | 正常范围 |
CPU | < 50% | 20-40% | 正常范围 |
网络 | < 10MB | 5-8MB | 正常范围 |
磁盘 | < 50MB | 20-30MB | 日志和报告 |
-- 测试结果表
DESCRIBE test_results;
+---------------+------------------------------------------+------+-----+-------------------+
| Field | Type | Null | Key | Default |
+---------------+------------------------------------------+------+-----+-------------------+
| id | int(11) | NO | PRI | NULL |
| test_name | varchar(255) | NO | | NULL |
| test_class | varchar(255) | NO | | NULL |
| test_method | varchar(255) | NO | | NULL |
| test_status | enum('PASS','FAIL','SKIP','ERROR') | NO | | NULL |
| test_duration | decimal(10,3) | YES | | 0.000 |
| error_message | text | YES | | NULL |
| test_data | json | YES | | NULL |
| created_time | timestamp | NO | | CURRENT_TIMESTAMP |
| updated_time | timestamp | NO | | CURRENT_TIMESTAMP |
+---------------+------------------------------------------+------+-----+-------------------+
-- 查看测试结果数据
SELECT test_name, test_status, test_duration
FROM test_results
ORDER BY created_time DESC
LIMIT 5;
-- 预期结果
+----------------------------------+-------------+---------------+
| test_name | test_status | test_duration |
+----------------------------------+-------------+---------------+
| test_auth_with_valid_credentials | PASS | 2.156 |
| test_ping_health_check | PASS | 1.234 |
| test_get_booking_list | PASS | 1.567 |
| test_create_booking | PASS | 2.345 |
+----------------------------------+-------------+---------------+
-- 查看API调用日志
SELECT request_method, request_url, response_status_code, response_time
FROM api_logs
ORDER BY created_time DESC
LIMIT 5;
-- 预期结果
+----------------+------------------------------------------+----------------------+---------------+
| request_method | request_url | response_status_code | response_time |
+----------------+------------------------------------------+----------------------+---------------+
| POST | /auth | 200 | 1.534 |
| GET | /ping | 201 | 1.522 |
| GET | /booking | 200 | 1.234 |
| POST | /booking | 200 | 2.156 |
+----------------+------------------------------------------+----------------------+---------------+
报告概览:
详细信息:
Overview页面:
Suites页面:
Graphs页面:
测试统计:
总测试数: 21
通过: 20 (95.2%)
失败: 1 (4.8%)
跳过: 0 (0%)
错误: 0 (0%)
总执行时间: 45.67秒
平均执行时间: 2.17秒
API调用统计:
总API调用: 45次
成功调用: 44次 (97.8%)
失败调用: 1次 (2.2%)
平均响应时间: 1.65秒
2025-06-29 09:45:23 | INFO | 开始执行测试: test_auth_with_valid_credentials
2025-06-29 09:45:23 | INFO | 步骤: 准备有效的认证数据
2025-06-29 09:45:23 | INFO | 发送API请求: POST https://restful-booker.herokuapp.com/auth
2025-06-29 09:45:25 | INFO | 收到API响应: 状态码200, 响应时间1.534秒
2025-06-29 09:45:25 | INFO | ✓ 断言通过: 状态码验证通过
2025-06-29 09:45:25 | INFO | ✓ 断言通过: token字段验证通过
2025-06-29 09:45:25 | INFO | 测试执行完成: test_auth_with_valid_credentials, 状态: 完成, 时长: 2.156秒
2025-06-29 09:45:30 | ERROR | ✗ 断言失败: 状态码验证失败
2025-06-29 09:45:30 | ERROR | 期望值: 200
2025-06-29 09:45:30 | ERROR | 实际值: 500
2025-06-29 09:45:30 | ERROR | 错误: API请求失败
2025-06-29 09:45:30 | ERROR | 异常详情: ConnectionError: Failed to establish connection
现象: 网络连接超时或失败
预期处理:
现象: 数据库连接失败
预期处理:
现象: 无法获取有效token
预期处理:
现象: 被测系统返回503错误
预期处理:
报告类型 | 生成工具 | 特点 | 适用场景 |
---|---|---|---|
HTML报告 | pytest-html | 简洁、快速 | 日常开发调试 |
Allure报告 | allure-pytest | 美观、交互 | 演示、分析 |
自定义报告 | 自研工具 | 定制、深度 | 管理汇报 |
JUnit报告 | pytest | 标准、兼容 | CI/CD集成 |
# 生成HTML报告
pytest --html=reports/report.html --self-contained-html
# 或使用执行脚本
python3 run_tests.py --report html
概览信息:
详细结果:
示例截图:
Test Results Summary
====================
21 tests ran in 45.67 seconds
Results:
✅ 20 passed
❌ 1 failed
⏭️ 0 skipped
Environment:
Python: 3.9.7
Platform: macOS-12.6-arm64
Packages: pytest-7.4.3, requests-2.31.0
# 生成Allure数据
pytest --alluredir=reports/allure-results
# 启动Allure服务
allure serve reports/allure-results
# 生成静态报告
allure generate reports/allure-results -o reports/allure-report --clean
Overview页面:
Suites页面:
Graphs页面:
Timeline页面:
测试步骤记录:
import allure
@allure.step("发送认证请求")
def send_auth_request(username, password):
# 测试步骤实现
pass
@allure.attach(body, name="API响应", attachment_type=allure.attachment_type.JSON)
def attach_response(response):
# 附件添加
pass
测试分类标记:
@allure.feature("用户认证")
@allure.story("登录功能")
@allure.severity(allure.severity_level.CRITICAL)
def test_login():
pass
测试概览:
<div class="summary">
<div class="summary-card">
<h3>21h3>
<p>总测试数p>
div>
<div class="summary-card passed">
<h3>20h3>
<p>通过p>
div>
<div class="summary-card failed">
<h3>1h3>
<p>失败p>
div>
div>
详细统计:
测试结果表格:
测试用例 | 状态 | 执行时间 | 错误信息 | 执行时间 |
---|---|---|---|---|
test_auth_with_valid_credentials | PASS | 2.156秒 | - | 2025-06-29 09:45:25 |
test_ping_health_check | PASS | 1.234秒 | - | 2025-06-29 09:45:26 |
# 生成自定义报告
from utils.report_generator import ReportGenerator
from utils.database_helper import DatabaseHelper
db_helper = DatabaseHelper(Config, logger)
generator = ReportGenerator(db_helper)
generator.generate_html_report('reports/custom_report.html')
JUnit XML格式是CI/CD系统的标准格式,支持:
# 生成JUnit XML报告
pytest --junitxml=reports/junit.xml
<testsuites>
<testsuite name="pytest" errors="0" failures="1" skipped="0" tests="21" time="45.67">
<testcase classname="testcases.test_auth.TestAuth"
name="test_auth_with_valid_credentials"
time="2.156"/>
<testcase classname="testcases.test_booking.TestBooking"
name="test_ping_health_check"
time="1.234"/>
<testcase classname="testcases.test_booking.TestBooking"
name="test_create_booking_with_invalid_data"
time="1.567">
<failure message="AssertionError: 期望状态码400,实际状态码200">
测试失败详细信息...
failure>
testcase>
testsuite>
testsuites>
功能特性 | HTML报告 | Allure报告 | 自定义报告 | JUnit报告 |
---|---|---|---|---|
生成速度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
美观程度 | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐ |
交互性 | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐ |
定制性 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐ |
CI集成 | ⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
日常开发: 使用HTML报告,快速查看测试结果
演示汇报: 使用Allure报告,美观的可视化展示
深度分析: 使用自定义报告,详细的数据分析
CI/CD集成: 使用JUnit报告,标准化集成
#!/bin/bash
# 自动生成所有类型报告
echo "开始生成测试报告..."
# 执行测试并生成报告
python3 run_tests.py --report both
# 生成自定义报告
python3 -c "
from utils.report_generator import ReportGenerator
from utils.database_helper import DatabaseHelper
from config.config import Config
from utils.logger import setup_logger
logger = setup_logger()
db = DatabaseHelper(Config, logger)
generator = ReportGenerator(db)
generator.generate_html_report()
print('自定义报告生成完成')
"
# 生成Allure静态报告
if command -v allure &> /dev/null; then
allure generate reports/allure-results -o reports/allure-report --clean
echo "Allure静态报告生成完成"
fi
echo "所有报告生成完成!"
echo "HTML报告: reports/report.html"
echo "Allure报告: reports/allure-report/index.html"
echo "自定义报告: reports/custom_report.html"
# 报告发布到Web服务器
import shutil
import os
def publish_reports():
"""发布报告到Web服务器"""
# 复制报告到Web目录
web_dir = "/var/www/html/test-reports"
if os.path.exists("reports/report.html"):
shutil.copy("reports/report.html", f"{web_dir}/latest.html")
if os.path.exists("reports/allure-report"):
shutil.copytree("reports/allure-report", f"{web_dir}/allure", dirs_exist_ok=True)
if os.path.exists("reports/custom_report.html"):
shutil.copy("reports/custom_report.html", f"{web_dir}/custom.html")
print("报告发布完成")
print(f"访问地址: http://your-server.com/test-reports/")
---
## ⚙️ 配置说明
### 环境变量配置
项目使用`.env`文件管理环境变量,支持灵活的配置管理。
#### 1. 主要配置项
```bash
# ================================
# API相关配置
# ================================
BASE_URL=https://restful-booker.herokuapp.com # 被测系统基础URL
REQUEST_TIMEOUT=30 # 请求超时时间(秒)
MAX_RETRIES=3 # 最大重试次数
REQUEST_INTERVAL=0.5 # 请求间隔时间(秒)
# ================================
# 认证相关配置
# ================================
AUTH_USERNAME=admin # 认证用户名
AUTH_PASSWORD=password123 # 认证密码
# ================================
# 数据库相关配置
# ================================
DATABASE_ENABLED=true # 是否启用数据库功能
DB_HOST=localhost # 数据库主机地址
DB_PORT=3306 # 数据库端口
DB_USER=root # 数据库用户名
DB_PASSWORD=chuankangkk # 数据库密码
DB_NAME=api_test # 数据库名称
DB_CHARSET=utf8mb4 # 数据库字符集
# ================================
# 日志相关配置
# ================================
LOG_LEVEL=INFO # 日志级别
LOG_FILE_PATH=logs/api_test.log # 日志文件路径
LOG_MAX_SIZE=10 # 日志文件最大大小(MB)
LOG_BACKUP_COUNT=5 # 日志文件保留数量
# ================================
# 测试报告相关配置
# ================================
HTML_REPORT_PATH=reports/report.html # HTML报告路径
ALLURE_RESULTS_PATH=reports/allure-results # Allure报告数据路径
# ================================
# 邮件通知相关配置(可选)
# ================================
EMAIL_ENABLED=false # 是否启用邮件通知
SMTP_SERVER=smtp.qq.com # SMTP服务器地址
SMTP_PORT=587 # SMTP端口
SMTP_USERNAME= # SMTP用户名
SMTP_PASSWORD= # SMTP密码
EMAIL_RECIPIENTS= # 收件人列表(逗号分隔)
# 配置加载示例
import os
from dotenv import load_dotenv
load_dotenv() # 加载.env文件
# 优先级:环境变量 > .env文件 > 默认值
BASE_URL = os.getenv("BASE_URL", "https://restful-booker.herokuapp.com")
# 开发环境配置
cp .env .env.dev
# 编辑.env.dev,设置开发环境参数
# 测试环境配置
cp .env .env.test
# 编辑.env.test,设置测试环境参数
# 生产环境配置
cp .env .env.prod
# 编辑.env.prod,设置生产环境参数
# 使用指定环境配置
export ENV=test
python3 run_tests.py # 会自动加载.env.test
[tool:pytest]
# 测试文件匹配模式
python_files = test_*.py
python_classes = Test*
python_functions = test_*
# 测试目录
testpaths = testcases
# 命令行选项
addopts =
-v # 详细输出
--tb=short # 简短的错误回溯
--strict-markers # 严格标记模式
--html=reports/report.html # HTML报告
--self-contained-html # 自包含HTML
--alluredir=reports/allure-results # Allure报告数据
# 标记定义
markers =
smoke: 冒烟测试用例
regression: 回归测试用例
auth: 认证相关测试
booking: 预订管理测试
slow: 执行时间较长的测试用例
# 日志配置
log_cli = true # 启用CLI日志
log_cli_level = INFO # CLI日志级别
log_cli_format = %(asctime)s [%(levelname)8s] %(name)s: %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S
# 过滤警告
filterwarnings =
ignore::UserWarning
ignore::DeprecationWarning
# 全局fixture配置
@pytest.fixture(scope="session")
def config():
"""会话级别的配置fixture"""
return Config()
@pytest.fixture(scope="session")
def api_client(config, logger):
"""会话级别的API客户端fixture"""
client = APIClient(config.BASE_URL, logger)
yield client
client.close_session()
@pytest.fixture(scope="function")
def auth_token(api_client, config):
"""函数级别的认证token fixture"""
auth_data = {
"username": config.AUTH_USERNAME,
"password": config.AUTH_PASSWORD
}
response = api_client.post("/auth", json=auth_data)
if response.status_code == 200:
return response.json().get("token")
return None
# 数据库连接参数
DB_CONFIG = {
'host': 'localhost',
'port': 3306,
'user': 'root',
'password': 'chuankangkk',
'database': 'api_test',
'charset': 'utf8mb4',
'autocommit': True,
'cursorclass': pymysql.cursors.DictCursor
}
# 连接池参数
POOL_CONFIG = {
'pool_size': 5, # 连接池大小
'max_overflow': 10, # 最大溢出连接数
'pool_timeout': 30, # 获取连接超时时间
'pool_recycle': 3600, # 连接回收时间
}
-- MySQL配置优化
SET GLOBAL max_connections = 200;
SET GLOBAL innodb_buffer_pool_size = 128M;
SET GLOBAL query_cache_size = 32M;
SET GLOBAL slow_query_log = 1;
SET GLOBAL long_query_time = 2;
级别 | 数值 | 说明 | 使用场景 |
---|---|---|---|
DEBUG | 10 | 调试信息 | 开发调试 |
INFO | 20 | 一般信息 | 正常运行 |
WARNING | 30 | 警告信息 | 潜在问题 |
ERROR | 40 | 错误信息 | 错误处理 |
CRITICAL | 50 | 严重错误 | 系统故障 |
# 控制台日志格式
CONSOLE_FORMAT = (
"{time:YYYY-MM-DD HH:mm:ss} | "
"{level: <8} | "
"{name} :{function} :{line} | "
"{message} "
)
# 文件日志格式
FILE_FORMAT = (
"{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | "
"{name}:{function}:{line} | {message}"
)
# 日志轮转参数
ROTATION_CONFIG = {
'rotation': '10 MB', # 文件大小轮转
'retention': 5, # 保留文件数量
'compression': 'zip', # 压缩格式
'encoding': 'utf-8', # 文件编码
}
{
"auth": {
"valid_credentials": {
"username": "admin",
"password": "password123"
},
"invalid_credentials": [
{
"username": "invalid_user",
"password": "invalid_password"
}
]
},
"booking": {
"valid_bookings": [
{
"firstname": "John",
"lastname": "Doe",
"totalprice": 100,
"depositpaid": true,
"bookingdates": {
"checkin": "2024-01-01",
"checkout": "2024-01-02"
},
"additionalneeds": "Breakfast"
}
]
}
}
# Faker配置
FAKER_CONFIG = {
'locales': ['zh_CN', 'en_US'], # 支持的语言
'seed': 12345, # 随机种子
}
# 数据生成规则
DATA_RULES = {
'firstname': 'fake.first_name()',
'lastname': 'fake.last_name()',
'totalprice': 'random.randint(50, 500)',
'checkin': 'fake.date_between(start_date="today", end_date="+30d")',
'checkout': 'checkin + timedelta(days=random.randint(1, 7))'
}
项目使用MySQL数据库存储测试结果、API调用日志和测试数据,支持完整的测试数据管理和分析。
CREATE TABLE test_results (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
test_name VARCHAR(255) NOT NULL COMMENT '测试用例名称',
test_class VARCHAR(255) NOT NULL COMMENT '测试类名',
test_method VARCHAR(255) NOT NULL COMMENT '测试方法名',
test_status ENUM('PASS', 'FAIL', 'SKIP', 'ERROR') NOT NULL COMMENT '测试状态',
test_duration DECIMAL(10, 3) DEFAULT 0.000 COMMENT '测试执行时长(秒)',
error_message TEXT COMMENT '错误信息',
test_data JSON COMMENT '测试数据',
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_test_name (test_name),
INDEX idx_test_status (test_status),
INDEX idx_created_time (created_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试结果表';
字段说明:
test_name
: 完整的测试用例名称,如 “test_auth_with_valid_credentials”test_class
: 测试类名,如 “TestAuth”test_method
: 测试方法名,如 “test_auth_with_valid_credentials”test_status
: 测试执行状态,支持通过、失败、跳过、错误四种状态test_duration
: 测试执行时长,精确到毫秒error_message
: 测试失败时的错误信息test_data
: 测试使用的数据,JSON格式存储CREATE TABLE api_logs (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
test_case VARCHAR(255) NOT NULL COMMENT '关联的测试用例',
request_method VARCHAR(10) NOT NULL COMMENT '请求方法',
request_url VARCHAR(500) NOT NULL COMMENT '请求URL',
request_headers JSON COMMENT '请求头',
request_body TEXT COMMENT '请求体',
response_status_code INT COMMENT '响应状态码',
response_headers JSON COMMENT '响应头',
response_body TEXT COMMENT '响应体',
response_time DECIMAL(10, 3) DEFAULT 0.000 COMMENT '响应时间(秒)',
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
INDEX idx_test_case (test_case),
INDEX idx_request_method (request_method),
INDEX idx_response_status_code (response_status_code),
INDEX idx_created_time (created_time)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='API调用日志表';
字段说明:
test_case
: 关联的测试用例名称,用于追踪API调用来源request_method
: HTTP请求方法,如GET、POST、PUT等request_url
: 完整的请求URLrequest_headers
: 请求头信息,JSON格式存储request_body
: 请求体内容response_status_code
: HTTP响应状态码response_headers
: 响应头信息,JSON格式存储response_body
: 响应体内容response_time
: API响应时间,精确到毫秒CREATE TABLE test_data (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
data_type VARCHAR(50) NOT NULL COMMENT '数据类型',
data_name VARCHAR(100) NOT NULL COMMENT '数据名称',
data_value JSON NOT NULL COMMENT '数据值',
description TEXT COMMENT '数据描述',
is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_data_type (data_type),
INDEX idx_data_name (data_name),
INDEX idx_is_active (is_active),
UNIQUE KEY uk_type_name (data_type, data_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试数据表';
字段说明:
data_type
: 数据类型分类,如 “auth”、"booking"等data_name
: 数据名称标识,如 “valid_credentials”data_value
: 具体的数据值,JSON格式存储description
: 数据描述信息is_active
: 是否启用该数据CREATE TABLE test_environments (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
env_name VARCHAR(50) NOT NULL UNIQUE COMMENT '环境名称',
base_url VARCHAR(255) NOT NULL COMMENT '基础URL',
auth_username VARCHAR(100) COMMENT '认证用户名',
auth_password VARCHAR(100) COMMENT '认证密码',
database_config JSON COMMENT '数据库配置',
other_config JSON COMMENT '其他配置',
is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
INDEX idx_env_name (env_name),
INDEX idx_is_active (is_active)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='测试环境配置表';
字段说明:
env_name
: 环境名称,如 “production”、“staging”base_url
: 该环境的基础URL地址auth_username
: 该环境的认证用户名auth_password
: 该环境的认证密码database_config
: 该环境的数据库配置,JSON格式other_config
: 其他配置信息,JSON格式# 保存测试结果
def save_test_result(db_helper, test_name, status, duration, error_msg=None):
"""保存测试结果到数据库"""
db_helper.save_test_result(
test_name=test_name,
test_class="TestAuth",
test_method="test_auth_with_valid_credentials",
status=status,
duration=duration,
error_message=error_msg,
test_data={"username": "admin", "password": "password123"}
)
# 查询测试结果
def get_test_results(db_helper, limit=10):
"""获取最近的测试结果"""
return db_helper.get_test_results(limit=limit)
# 统计测试结果
def get_test_statistics(db_helper):
"""获取测试统计信息"""
sql = """
SELECT
test_status,
COUNT(*) as count,
AVG(test_duration) as avg_duration,
MAX(test_duration) as max_duration,
MIN(test_duration) as min_duration
FROM test_results
WHERE created_time >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY test_status
"""
return db_helper.fetch_all(sql)
# 保存API调用日志
def save_api_log(db_helper, test_case, method, url, request_data, response_data):
"""保存API调用日志"""
db_helper.save_api_log(
test_case=test_case,
method=method,
url=url,
request_headers=request_data.get('headers'),
request_body=request_data.get('body'),
status_code=response_data.get('status_code'),
response_headers=response_data.get('headers'),
response_body=response_data.get('body'),
response_time=response_data.get('response_time')
)
# 查询API调用统计
def get_api_statistics(db_helper):
"""获取API调用统计"""
sql = """
SELECT
request_method,
response_status_code,
COUNT(*) as call_count,
AVG(response_time) as avg_response_time,
MAX(response_time) as max_response_time
FROM api_logs
WHERE created_time >= DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY request_method, response_status_code
ORDER BY call_count DESC
"""
return db_helper.fetch_all(sql)
# 获取测试数据
def get_test_data(db_helper, data_type, data_name=None):
"""获取指定类型的测试数据"""
return db_helper.get_test_data(data_type=data_type, data_name=data_name)
# 更新测试数据
def update_test_data(db_helper, data_type, data_name, new_value):
"""更新测试数据"""
sql = """
UPDATE test_data
SET data_value = %s, updated_time = CURRENT_TIMESTAMP
WHERE data_type = %s AND data_name = %s
"""
db_helper.execute_sql(sql, (json.dumps(new_value), data_type, data_name))
-- 清理30天前的测试结果
DELETE FROM test_results
WHERE created_time < DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 清理7天前的API日志
DELETE FROM api_logs
WHERE created_time < DATE_SUB(NOW(), INTERVAL 7 DAY);
-- 清理无效的测试数据
DELETE FROM test_data
WHERE is_active = FALSE AND updated_time < DATE_SUB(NOW(), INTERVAL 90 DAY);
#!/bin/bash
# 数据库备份脚本
BACKUP_DIR="/backup/api_test"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/api_test_$DATE.sql"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 执行备份
mysqldump -u root -p$DB_PASSWORD \
--single-transaction \
--routines \
--triggers \
api_test > $BACKUP_FILE
# 压缩备份文件
gzip $BACKUP_FILE
# 删除7天前的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
echo "数据库备份完成: $BACKUP_FILE.gz"
-- 添加索引优化查询性能
CREATE INDEX idx_test_results_composite ON test_results(test_status, created_time);
CREATE INDEX idx_api_logs_composite ON api_logs(test_case, created_time);
-- 分析表统计信息
ANALYZE TABLE test_results;
ANALYZE TABLE api_logs;
ANALYZE TABLE test_data;
ANALYZE TABLE test_environments;
-- 优化表结构
OPTIMIZE TABLE test_results;
OPTIMIZE TABLE api_logs;
项目提供完整的Jenkins流水线配置,支持自动化的测试执行、报告生成和结果通知。
pipeline {
agent any
parameters {
choice(
name: 'TEST_SUITE',
choices: ['all', 'smoke', 'regression', 'auth', 'booking'],
description: '选择要执行的测试套件'
)
choice(
name: 'ENVIRONMENT',
choices: ['production', 'staging'],
description: '选择测试环境'
)
choice(
name: 'PARALLEL_COUNT',
choices: ['1', '2', '4', 'auto'],
description: '并发执行进程数'
)
booleanParam(
name: 'SEND_EMAIL',
defaultValue: false,
description: '是否发送邮件通知'
)
booleanParam(
name: 'CLEAN_WORKSPACE',
defaultValue: true,
description: '是否清理工作空间'
)
}
}
environment {
PYTHON_VERSION = '3.8'
PROJECT_NAME = 'api-automation-test'
REPORT_DIR = 'reports'
ALLURE_RESULTS = 'reports/allure-results'
VENV_PATH = 'venv'
// 动态设置环境变量
BASE_URL = "${params.ENVIRONMENT == 'staging' ? 'https://restful-booker-staging.herokuapp.com' : 'https://restful-booker.herokuapp.com'}"
}
环境准备阶段:
stage('环境准备') {
steps {
script {
echo "开始环境准备..."
// 清理工作空间
if (params.CLEAN_WORKSPACE) {
cleanWs()
}
// 检出代码
checkout scm
// 显示构建信息
echo "构建参数:"
echo " 测试套件: ${params.TEST_SUITE}"
echo " 测试环境: ${params.ENVIRONMENT}"
echo " 并发数: ${params.PARALLEL_COUNT}"
echo " 邮件通知: ${params.SEND_EMAIL}"
}
}
}
依赖安装阶段:
stage('依赖安装') {
steps {
script {
echo "开始安装依赖..."
// 创建虚拟环境
sh """
python3 -m venv ${VENV_PATH}
source ${VENV_PATH}/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
"""
echo "依赖安装完成"
}
}
}
测试执行阶段:
stage('执行测试') {
steps {
script {
echo "开始执行测试..."
// 构建pytest命令
def pytestArgs = ""
switch(params.TEST_SUITE) {
case 'smoke':
pytestArgs = "-m smoke"
break
case 'regression':
pytestArgs = "-m regression"
break
case 'auth':
pytestArgs = "-m auth"
break
case 'booking':
pytestArgs = "-m booking"
break
default:
pytestArgs = ""
}
// 添加并发参数
if (params.PARALLEL_COUNT != '1') {
pytestArgs += " -n ${params.PARALLEL_COUNT}"
}
// 执行测试
sh """
source ${VENV_PATH}/bin/activate
mkdir -p ${REPORT_DIR}
pytest ${pytestArgs} \
--html=${REPORT_DIR}/report.html \
--self-contained-html \
--alluredir=${ALLURE_RESULTS} \
--junitxml=${REPORT_DIR}/junit.xml \
-v
"""
}
}
post {
always {
// 收集测试结果
junit "${REPORT_DIR}/junit.xml"
// 发布HTML报告
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: "${REPORT_DIR}",
reportFiles: 'report.html',
reportName: 'HTML测试报告'
])
// 发布Allure报告
allure([
includeProperties: false,
jdk: '',
properties: [],
reportBuildPolicy: 'ALWAYS',
results: [[path: "${ALLURE_RESULTS}"]]
])
}
}
}
组件 | 版本要求 | 说明 |
---|---|---|
Jenkins | 2.400+ | 支持Pipeline语法 |
Python | 3.8+ | 测试执行环境 |
Git | 2.0+ | 代码版本控制 |
Allure Plugin | 2.8+ | 报告生成插件 |
HTML Publisher | 1.25+ | HTML报告发布 |
# 通过Jenkins CLI安装插件
java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin \
pipeline-stage-view \
allure-jenkins-plugin \
htmlpublisher \
email-ext \
build-timeout \
timestamper \
ws-cleanup
Python配置:
管理Jenkins > 全局工具配置 > Python
名称: Python3
路径: /usr/bin/python3 (或实际Python路径)
Allure配置:
管理Jenkins > 全局工具配置 > Allure Commandline
名称: Allure
安装方式: 自动安装
版本: 2.20.1
创建Pipeline项目:
配置源码管理:
源码管理: Git
Repository URL: https://github.com/your-repo/api-automation-test.git
Credentials: 添加Git凭据
Branch: */main
配置构建触发器:
✅ GitHub hook trigger for GITScm polling
✅ Poll SCM: H/5 * * * * (每5分钟检查一次)
✅ Build periodically: H 2 * * * (每天凌晨2点执行)
Pipeline配置:
Definition: Pipeline script from SCM
SCM: Git
Repository URL: (同上)
Script Path: Jenkinsfile
// Jenkinsfile.multibranch
pipeline {
agent any
stages {
stage('分支检测') {
steps {
script {
def branchName = env.BRANCH_NAME
echo "当前分支: ${branchName}"
// 根据分支选择测试策略
if (branchName == 'main') {
env.TEST_SUITE = 'regression'
} else if (branchName.startsWith('feature/')) {
env.TEST_SUITE = 'smoke'
} else {
env.TEST_SUITE = 'smoke'
}
}
}
}
// 其他阶段...
}
}
pipeline {
agent none
stages {
stage('矩阵测试') {
matrix {
axes {
axis {
name 'ENVIRONMENT'
values 'production', 'staging'
}
axis {
name 'TEST_SUITE'
values 'smoke', 'regression'
}
}
stages {
stage('执行测试') {
agent any
steps {
script {
echo "执行 ${ENVIRONMENT} 环境的 ${TEST_SUITE} 测试"
sh """
source venv/bin/activate
python3 run_tests.py --env ${ENVIRONMENT} --suite ${TEST_SUITE}
"""
}
}
}
}
}
}
}
}
post {
always {
script {
if (params.SEND_EMAIL) {
def buildStatus = currentBuild.result ?: 'SUCCESS'
def subject = "${buildStatus}: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
def body = """
测试执行${buildStatus == 'SUCCESS' ? '成功' : '失败'}
项目 ${env.JOB_NAME}
构建号 ${env.BUILD_NUMBER}
测试套件 ${params.TEST_SUITE}
测试环境 ${params.ENVIRONMENT}
构建时间 ${new Date()}
执行时长 ${currentBuild.durationString}
快速链接
"""
emailext (
subject: subject,
body: body,
mimeType: 'text/html',
to: '${DEFAULT_RECIPIENTS}',
attachLog: buildStatus != 'SUCCESS'
)
}
}
}
}
// 设置构建超时
options {
timeout(time: 30, unit: 'MINUTES')
timestamps()
buildDiscarder(logRotator(numToKeepStr: '10'))
}
// 并行执行阶段
parallel {
stage('单元测试') {
steps {
sh 'python3 -m pytest tests/unit/'
}
}
stage('集成测试') {
steps {
sh 'python3 -m pytest tests/integration/'
}
}
}
// 缓存Python依赖
stage('缓存依赖') {
steps {
script {
def cacheKey = sh(
script: "md5sum requirements.txt | cut -d' ' -f1",
returnStdout: true
).trim()
if (fileExists("cache/venv-${cacheKey}")) {
echo "使用缓存的虚拟环境"
sh "cp -r cache/venv-${cacheKey} venv"
} else {
echo "创建新的虚拟环境"
sh """
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
mkdir -p cache
cp -r venv cache/venv-${cacheKey}
"""
}
}
}
}
// 资源限制
agent {
label 'test-agent'
customWorkspace '/opt/jenkins/workspace/api-test'
}
// 清理策略
post {
cleanup {
script {
// 清理大文件
sh 'find . -name "*.log" -size +10M -delete'
sh 'find . -name "*.tmp" -delete'
// 清理虚拟环境
sh 'rm -rf venv'
}
}
}
---
## ❓ 常见问题
### 安装和配置问题
#### Q1: Python版本兼容性问题
**问题**: 提示Python版本过低或不兼容
**解决方案**:
```bash
# 检查Python版本
python3 --version
# 如果版本低于3.8,需要升级Python
# macOS
brew install python@3.9
# Ubuntu
sudo apt update
sudo apt install python3.9
# Windows
# 从官网下载Python 3.9+安装包
问题: pip install失败或包冲突
解决方案:
# 升级pip
pip install --upgrade pip
# 使用虚拟环境
python3 -m venv venv
source venv/bin/activate # Linux/Mac
# 或
venv\Scripts\activate # Windows
# 清理缓存重新安装
pip cache purge
pip install -r requirements.txt
# 如果仍有问题,尝试指定源
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
问题: 无法连接到MySQL数据库
解决方案:
# 检查MySQL服务状态
# macOS
brew services list | grep mysql
# Linux
sudo systemctl status mysql
# Windows
net start mysql
# 检查连接参数
mysql -h localhost -u root -p
# 创建数据库
CREATE DATABASE api_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 检查用户权限
GRANT ALL PRIVILEGES ON api_test.* TO 'root'@'localhost';
FLUSH PRIVILEGES;
问题: 测试用例运行时出现各种错误
解决方案:
# 检查网络连接
curl -I https://restful-booker.herokuapp.com/ping
# 检查API可用性
python3 -c "
import requests
try:
response = requests.get('https://restful-booker.herokuapp.com/ping', timeout=10)
print(f'API状态: {response.status_code}')
except Exception as e:
print(f'API连接失败: {e}')
"
# 运行单个测试用例调试
pytest testcases/test_auth.py::TestAuth::test_auth_with_valid_credentials -v -s
# 查看详细日志
tail -f logs/api_test.log
问题: 并发执行时出现随机失败
解决方案:
# 减少并发数
python3 run_tests.py --parallel 2
# 增加请求间隔
# 在.env文件中设置
REQUEST_INTERVAL=1.0
# 增加超时时间
REQUEST_TIMEOUT=60
# 检查系统资源
top
free -h
问题: 无法获取有效的认证token
解决方案:
# 手动测试认证接口
curl -X POST https://restful-booker.herokuapp.com/auth \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "password123"}'
# 检查认证配置
python3 -c "
from config.config import Config
print(f'用户名: {Config.AUTH_USERNAME}')
print(f'密码: {Config.AUTH_PASSWORD}')
"
# 更新认证信息(如果API变更)
# 编辑.env文件
AUTH_USERNAME=new_username
AUTH_PASSWORD=new_password
问题: HTML或Allure报告无法生成
解决方案:
# 检查报告目录权限
ls -la reports/
chmod 755 reports/
# 手动生成HTML报告
pytest --html=reports/manual_report.html --self-contained-html
# 检查Allure安装
allure --version
# 安装Allure(如果未安装)
npm install -g allure-commandline
# 手动生成Allure报告
allure generate reports/allure-results -o reports/allure-report --clean
问题: 日志文件占用过多磁盘空间
解决方案:
# 检查日志文件大小
du -sh logs/
# 清理旧日志
find logs/ -name "*.log" -mtime +7 -delete
# 调整日志配置
# 在.env文件中设置
LOG_MAX_SIZE=5
LOG_BACKUP_COUNT=3
# 手动清理日志
> logs/api_test.log
> logs/api_test_error.log
问题: Jenkins流水线执行失败
解决方案:
# 检查Jenkins节点Python环境
which python3
python3 --version
# 检查工作空间权限
ls -la /var/jenkins_home/workspace/
# 在Jenkins中设置环境变量
# 管理Jenkins > 系统配置 > 全局属性 > 环境变量
PATH=/usr/local/bin:/usr/bin:/bin
# 检查插件安装
# 管理Jenkins > 插件管理
# 确保安装了Pipeline、HTML Publisher、Allure等插件
问题: Jenkins邮件通知发送失败
解决方案:
# 配置SMTP设置
# 管理Jenkins > 系统配置 > 邮件通知
SMTP服务器: smtp.qq.com
端口: 587
用户名: [email protected]
密码: your-app-password
# 测试邮件配置
# 在系统配置页面点击"通过发送测试邮件测试配置"
# 检查防火墙设置
telnet smtp.qq.com 587
问题: 测试执行时间过长
解决方案:
# 启用并发执行
python3 run_tests.py --parallel 4
# 只运行冒烟测试
python3 run_tests.py --suite smoke
# 优化网络配置
# 在.env文件中设置
REQUEST_TIMEOUT=10
MAX_RETRIES=1
# 禁用数据库功能(如果不需要)
python3 run_tests.py --no-db
问题: 测试执行时内存占用过多
解决方案:
# 监控内存使用
python3 -c "
import psutil
print(f'内存使用: {psutil.virtual_memory().percent}%')
"
# 减少并发数
python3 run_tests.py --parallel 2
# 清理测试数据
python3 -c "
from utils.database_helper import DatabaseHelper
from config.config import Config
from utils.logger import setup_logger
logger = setup_logger()
db = DatabaseHelper(Config, logger)
db.execute_sql('DELETE FROM api_logs WHERE created_time < DATE_SUB(NOW(), INTERVAL 1 DAY)')
print('清理完成')
"
install.py
自动化环境配置run_tests.py
简化测试执行init_database.py
、generate_test_data.py
test_example.py
快速验证安装# testcases/test_new_feature.py
import pytest
from utils.logger import test_logger
class TestNewFeature:
"""新功能测试类"""
@pytest.mark.smoke
@pytest.mark.new_feature
def test_new_api_endpoint(self, api_client):
"""测试新的API端点"""
test_logger.step("发送新API请求")
response = api_client.get("/new-endpoint")
test_logger.step("验证响应")
assert response.status_code == 200
test_logger.assertion_pass("状态码验证通过")
# pytest.ini
markers =
new_feature: 新功能测试用例
// data/test_data.json
{
"new_feature": {
"valid_data": {
"param1": "value1",
"param2": "value2"
}
}
}
# .env
BASE_URL=https://your-api-system.com
AUTH_USERNAME=your_username
AUTH_PASSWORD=your_password
# utils/api_client.py
class APIClient:
def __init__(self, base_url, logger=None):
# 添加新的认证方式
if "your-api-system" in base_url:
self.auth_type = "bearer"
else:
self.auth_type = "cookie"
# testcases/test_your_system.py
class TestYourSystem:
"""您的系统测试类"""
def test_your_api(self, api_client):
"""测试您的API"""
# 实现具体的测试逻辑
pass
# utils/custom_report_generator.py
class CustomReportGenerator:
"""自定义报告生成器"""
def generate_pdf_report(self, output_path):
"""生成PDF报告"""
# 实现PDF报告生成逻辑
pass
def generate_excel_report(self, output_path):
"""生成Excel报告"""
# 实现Excel报告生成逻辑
pass
# run_tests.py
parser.add_argument(
'--report-format',
choices=['html', 'allure', 'pdf', 'excel'],
default='html',
help='选择报告格式'
)
# .gitlab-ci.yml
stages:
- test
- report
api_test:
stage: test
script:
- python3 install.py
- python3 run_tests.py --suite regression
artifacts:
reports:
junit: reports/junit.xml
paths:
- reports/
# .github/workflows/api-test.yml
name: API自动化测试
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: 设置Python环境
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: 安装依赖
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: 运行测试
run: python3 run_tests.py --suite smoke
- name: 发布报告
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./reports
# testcases/test_performance.py
import time
import pytest
from concurrent.futures import ThreadPoolExecutor
class TestPerformance:
"""性能测试类"""
@pytest.mark.performance
def test_api_response_time(self, api_client):
"""测试API响应时间"""
start_time = time.time()
response = api_client.get("/booking")
end_time = time.time()
response_time = end_time - start_time
assert response_time < 2.0, f"响应时间过长: {response_time}秒"
@pytest.mark.performance
def test_concurrent_requests(self, api_client):
"""测试并发请求"""
def make_request():
return api_client.get("/booking")
with ThreadPoolExecutor(max_workers=10) as executor:
futures = [executor.submit(make_request) for _ in range(50)]
results = [future.result() for future in futures]
success_count = sum(1 for r in results if r.status_code == 200)
success_rate = success_count / len(results)
assert success_rate >= 0.95, f"成功率过低: {success_rate}"
# utils/performance_monitor.py
import psutil
import time
class PerformanceMonitor:
"""性能监控器"""
def __init__(self):
self.start_time = None
self.metrics = []
def start_monitoring(self):
"""开始监控"""
self.start_time = time.time()
self.metrics = []
def collect_metrics(self):
"""收集性能指标"""
cpu_percent = psutil.cpu_percent()
memory_percent = psutil.virtual_memory().percent
self.metrics.append({
'timestamp': time.time(),
'cpu_percent': cpu_percent,
'memory_percent': memory_percent
})
def generate_report(self):
"""生成性能报告"""
# 实现性能报告生成
pass
欢迎对项目进行贡献和改进:
本项目遵循MIT开源协议,允许自由使用、修改和分发。
Copyright © 2025 传康kk. All rights reserved.