目录
Python 自动化测试框架 的完整搭建指南,涵盖 框架设计思路、核心模块、代码示例及最佳实践,适用于 Web/API/数据库 等测试场景:
一、准备工作
1 选择测试框架
-
pytest:
-
pytest 是一个功能强大、易于使用的 Python 测试框架。
-
它支持简单的单元测试和复杂的集成测试,具有丰富的插件和扩展。
-
pytest 具有自动发现测试用例,丰富的断言以及插件扩展等特点,被广泛应用。
-
-
unittest:
-
unittest 是 Python 标准库中的单元测试框架。
-
它提供了编写和组织测试用例的基本功能,适合简单的单元测试。
-
unittest是python自带的测试框架。
-
-
Robot Framework:
-
Robot Framework 是一个通用的自动化测试框架,支持关键字驱动测试。
-
它适用于各种自动化测试,包括 Web 测试、接口测试和移动应用测试。
-
robot framework 更加适合于,测试人员,或者,非开发人员。
-
2 安装必要的库
-
使用 pip 安装所选测试框架和相关库:
-
pip install pytest
-
pip install requests
(用于接口测试) -
pip install selenium
(用于 Web 测试)
-
3 编写测试用例
-
pytest:
-
创建以
test_
开头的文件或函数。 -
使用
assert
语句进行断言。 -
可以使用 fixture 来管理测试环境。
-
-
unittest:
-
创建继承自
unittest.TestCase
的测试类。 -
使用
self.assertXXX
方法进行断言。 -
可以使用
setUp
和tearDown
方法来设置和清理测试环境。
-
4 运行测试用例
-
pytest:
-
在命令行中运行
pytest
命令。 -
可以使用
-v
参数来显示详细的测试结果。 -
可以使用 -k 参数,来执行包含某个关键字的测试用例。
-
-
unittest:
-
在命令行中运行
python -m unittest
命令。 -
或者,在python代码中,使用 unittest.main() 来运行测试。
-
二、正式搭建
1. 框架设计原则
-
模块化:分离测试用例、工具方法、配置和数据。
-
可维护性:使用清晰的目录结构,降低耦合度。
-
可扩展性:支持插件机制(如
pytest
插件)。 -
多环境适配:灵活切换测试/生产环境配置。
-
报告与日志:生成可视化测试报告,记录执行过程。
2. 框架核心模块
模块划分
project_root/
├── config/ # 配置文件
│ ├── dev.yaml # 开发环境配置
│ └── prod.yaml # 生产环境配置
├── test_cases/ # 测试用例
│ ├── api/ # API 测试
│ └── web/ # Web UI 测试
├── utils/ # 工具类
│ ├── http_client.py # HTTP 请求封装
│ └── db_connector.py # 数据库操作封装
├── conftest.py # pytest 全局 Fixture
├── requirements.txt # 依赖库列表
└── reports/ # 测试报告
3. 核心代码实现
3.1 配置文件管理(使用 PyYAML
)
# config/dev.yaml
base_url: "https://dev.api.example.com"
database:
host: "localhost"
user: "test_user"
password: "secret"
# utils/config_loader.py
import yaml
from pathlib import Path
def load_config(env="dev"):
config_path = Path(__file__).parent.parent / "config" / f"{env}.yaml"
with open(config_path) as f:
return yaml.safe_load(f)
3.2 HTTP 请求封装(基于 requests
)
# utils/http_client.py
import requests
from utils.config_loader import load_config
class APIClient:
def __init__(self, env="dev"):
self.config = load_config(env)
self.base_url = self.config["base_url"]
self.session = requests.Session()
def request(self, method, endpoint, **kwargs):
url = f"{self.base_url}{endpoint}"
response = self.session.request(method, url, **kwargs)
response.raise_for_status() # 自动抛出 HTTP 错误
return response
3.3 数据库操作封装(使用 SQLAlchemy
)
# utils/db_connector.py
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from utils.config_loader import load_config
class Database:
def __init__(self, env="dev"):
config = load_config(env)["database"]
self.engine = create_engine(
f"postgresql://{config['user']}:{config['password']}@{config['host']}/test_db"
)
self.Session = sessionmaker(bind=self.engine)
def query(self, sql):
with self.Session() as session:
result = session.execute(sql)
return result.fetchall()
4. 测试用例编写(pytest
示例)
4.1 API 测试用例
# test_cases/api/test_user_api.py
def test_get_user(api_client):
response = api_client.request("GET", "/users/1")
assert response.status_code == 200
assert response.json()["id"] == 1
def test_create_user(api_client):
payload = {"name": "Alice", "email": "alice@example.com"}
response = api_client.request("POST", "/users", json=payload)
assert response.status_code == 201
assert "id" in response.json()
4.2 Web UI 测试用例(使用 Selenium
)
# test_cases/web/test_login.py
from selenium.webdriver.common.by import By
def test_login(web_driver):
web_driver.get("https://example.com/login")
web_driver.find_element(By.ID, "username").send_keys("admin")
web_driver.find_element(By.ID, "password").send_keys("secret")
web_driver.find_element(By.TAG_NAME, "form").submit()
assert web_driver.current_url == "https://example.com/dashboard"
5. Fixture 管理(conftest.py
)
# conftest.py
import pytest
from utils.http_client import APIClient
from selenium import webdriver
from utils.db_connector import Database
@pytest.fixture(scope="session")
def api_client():
return APIClient(env="dev")
@pytest.fixture(scope="function")
def web_driver():
driver = webdriver.Chrome()
yield driver
driver.quit()
@pytest.fixture(scope="module")
def db():
db = Database(env="dev")
yield db
db.engine.dispose() # 清理数据库连接
6. 测试报告与日志
6.1 生成 Allure 报告
pytest:
可以使用
pytest-html
插件生成 HTML 测试报告。可以使用
pytest-cov
插件生成代码覆盖率报告。unittest:
可以使用第三方的库,来生成unittest的html测试报告。
1.安装依赖:
pip install allure-pytest pytest-html
2.运行测试并生成报告:
pytest --alluredir=./reports/allure_results
allure serve ./reports/allure_results # 本地查看报告
6.2 日志记录
# utils/logger.py
import logging
import sys
def get_logger(name):
logger = logging.getLogger(name)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
# 在测试用例中使用
logger = get_logger(__name__)
logger.info("Test started")
7. 最佳实践
7.1 数据驱动测试
-
使用
@pytest.mark.parametrize
或外部文件(JSON/YAML/Excel)管理测试数据:
import pytest
test_data = [
("admin", "secret", True),
("guest", "wrong_pass", False)
]
@pytest.mark.parametrize("username, password, expected", test_data)
def test_login(web_driver, username, password, expected):
# 执行登录逻辑
assert (error_message is None) == expected
7.2 并行测试
-
使用
pytest-xdist
加速执行:
pytest -n 4 # 启动 4 个进程并行执行
7.3 环境隔离
-
通过命令行参数切换环境:
pytest --env=prod # 使用生产环境配置
-
在
conftest.py
中读取参数:
def pytest_addoption(parser):
parser.addoption("--env", action="store", default="dev")
8. 持续集成(CI/CD)
GitHub Actions 示例
# .github/workflows/python-test.yml
name: Python Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run tests
run: pytest --alluredir=./reports/allure_results
- name: Upload Allure report
uses: actions/upload-artifact@v3
with:
name: allure-report
path: ./reports/allure_results
9. 常见问题
9.1 依赖冲突
-
解决:使用虚拟环境(
venv
或poetry
)隔离项目依赖。
9.2 测试用例稳定性
-
解决:添加重试机制(
pytest-rerunfailures
):
pytest --reruns 3 --reruns-delay 2 # 失败后重试 3 次,间隔 2 秒
9.3 动态数据清理
-
解决:通过 Fixture 自动清理测试数据:
@pytest.fixture
def temp_user(api_client):
user = api_client.create_user(name="Temp")
yield user
api_client.delete_user(user["id"]) # 测试后删除
总结
通过以上步骤,、可以搭建一个 模块化、易扩展、支持多场景 的 Python 自动化测试框架。核心在于:
-
合理分层:分离配置、工具、测试用例。
-
灵活封装:统一管理 HTTP、数据库、日志等操作。
-
生态集成:利用
pytest
插件和主流工具(Allure、Selenium)增强能力。 -
持续优化:根据项目需求扩展 Mock 服务、性能测试等模块。
扩展阅读:
Python开发者必备:语法与高级特性精讲 | Python开发者必备:语法与高级特性精讲-CSDN博客 | Python的基本语法和高级属性 |
Python 入门核心概念:语法、运算符、函数及变量类型详解 | Python 入门核心概念:语法、运算符、函数及变量类型详解-CSDN博客 | Python基础知识梳理 |
Python开发环境搭建终极指南:从零配置到高频问题解决方案 | Python开发环境搭建终极指南:从零配置到高频问题解决方案-CSDN博客 | Python搭建教程及常见问题 |
Python自动化测试框架开发指南:从模块封装到持续交付的高效实践 | Python自动化测试框架开发指南:从模块封装到持续交付的高效实践-CSDN博客 | Python自动化测试框架的完整搭建指南 |