作为一名长期从事自动化测试的工程师,我深知一个稳定可靠的测试环境是高效工作的基础。下面我将分享在Windows系统下搭建Python接口自动化测试环境的完整流程,包含你可能遇到的各种细节问题。
首先打开PyCharm,选择"New Project",这里有几个关键设置点需要注意:
创建完成后,我习惯先做两件事:
src和tests两个文件夹,分别存放源代码和测试代码.gitignore文件,排除不必要的文件版本控制在开始安装依赖前,我们需要确认Python环境是否正确配置:
bash复制where python
这个命令会显示当前生效的Python解释器路径。特别注意:
常见问题:当系统存在多个Python版本时,可能出现pip安装的包和实际使用的Python版本不匹配的情况。可以通过
python -m pip代替直接使用pip命令来避免这个问题。
PyCharm默认使用cmd终端,但PowerShell提供了更强大的功能:
powershell.exePowerShell的优势在于:
我还会推荐安装Windows Terminal作为替代方案,它提供了标签页、分屏等实用功能,大幅提升工作效率。
创建一个requirements.txt文件是Python项目的标准做法,我通常会按功能分组注释:
text复制# 测试框架
pytest==8.3.2
allure-pytest==2.13.5
# HTTP客户端
requests==2.31.0
# 数据验证
jsonschema==4.23.0
# 配置管理
PyYAML==6.0.1
安装时使用以下命令:
bash复制pip install -r requirements.txt
几个实用技巧:
--upgrade参数可以更新已安装的包pip freeze > requirements.txt可以生成当前环境的所有依赖-i参数指定私有源安装完成后,建议运行:
bash复制pip list
检查各包版本是否匹配。特别要注意:
如果出现依赖冲突,可以尝试:
pip install --force-reinstall强制重装作为HTTP客户端库,requests是接口测试的核心工具。以下是我总结的高级用法:
会话保持
python复制import requests
s = requests.Session() # 创建会话对象
s.headers.update({'X-Test': 'true'}) # 公共请求头
# 所有请求都会自动携带X-Test头
response = s.get('https://api.example.com/users')
超时设置
python复制# 同时设置连接超时和读取超时
response = requests.get(url, timeout=(3.05, 10))
重试机制
python复制from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
http = requests.Session()
http.mount("https://", adapter)
http.mount("http://", adapter)
代理设置
python复制proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
requests.get('http://example.org', proxies=proxies)
pytest的强大之处在于其丰富的插件系统和灵活的fixture机制。
fixture共享
python复制# conftest.py
import pytest
@pytest.fixture(scope="module")
def api_client():
client = ApiClient()
yield client
client.cleanup()
参数化测试
python复制@pytest.mark.parametrize("user,password,expected", [
("admin", "123456", 200),
("test", "wrong", 401),
("", "", 400),
])
def test_login(user, password, expected):
response = login(user, password)
assert response.status_code == expected
标记和过滤
python复制@pytest.mark.slow
def test_large_file_upload():
...
# 只运行标记为slow的测试
pytest -m slow
插件推荐
Allure报告可以通过多种方式增强可读性:
添加附件
python复制import allure
def test_with_attachment():
allure.attach.file('./data/test.csv', name='Test Data')
allure.attach('<html>Test</html>', name='HTML附件', attachment_type=allure.attachment_type.HTML)
动态标题
python复制@allure.title("登录测试-{username}")
def test_login(username):
...
步骤嵌套
python复制@allure.step("准备测试数据")
def prepare_data():
with allure.step("生成用户"):
...
with allure.step("初始化数据库"):
...
jsonschema在接口测试中用于确保返回数据结构符合预期:
复杂schema示例
python复制schema = {
"type": "object",
"required": ["success", "code", "data"],
"properties": {
"success": {"type": "boolean"},
"code": {"type": "integer", "enum": [200, 400, 500]},
"message": {"type": "string"},
"data": {
"type": "object",
"properties": {
"user": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {"type": "integer", "minimum": 1},
"name": {"type": "string", "minLength": 2},
"email": {"type": "string", "format": "email"}
}
}
}
}
}
}
自定义验证器
python复制from jsonschema import validators
def is_phone_number(validator, value, instance, schema):
if not re.match(r'^1[3-9]\d{9}$', instance):
yield ValidationError(f"{instance}不是有效的手机号")
validators.Draft7Validator.VALIDATORS["phone"] = is_phone_number
YAML非常适合存储测试数据和配置:
多文档YAML处理
yaml复制---
# 测试用例1
name: 正常登录
request:
method: POST
url: /login
data:
username: admin
password: 123456
expect:
status_code: 200
---
# 测试用例2
name: 错误密码
request:
method: POST
url: /login
data:
username: admin
password: wrong
expect:
status_code: 401
Python读取示例
python复制import yaml
def load_test_cases(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return list(yaml.safe_load_all(f))
YAML与JSON转换
python复制import json
import yaml
def yaml_to_json(yaml_str):
data = yaml.safe_load(yaml_str)
return json.dumps(data, indent=2)
Allure的安装有几个关键步骤:
验证安装:
bash复制allure --version
常见问题:如果PyCharm终端无法识别allure命令,但cmd可以,这是因为PyCharm没有继承系统PATH。需要在PyCharm的Settings -> Tools -> Terminal中勾选"Activate virtualenv"和"Add environment variables from system"。
生成报告的两种方式:
临时查看
bash复制pytest --alluredir=./allure-results
allure serve ./allure-results
生成静态报告
bash复制pytest --alluredir=./allure-results
allure generate ./allure-results -o ./allure-report --clean
我通常会添加以下参数增强报告:
--clean-alluredir:清除历史结果--allure-severities critical,normal:按严重级别过滤--allure-epics:按epic过滤环境信息配置
在allure-results目录下创建environment.properties文件:
properties复制python.version=3.8.10
os=Windows 10
pytest.version=6.2.5
allure.version=2.13.5
分类标记
python复制@allure.epic("用户管理")
@allure.feature("登录功能")
@allure.story("普通用户登录")
@allure.severity(allure.severity_level.CRITICAL)
def test_login():
...
自定义样式
可以在allure-report目录下添加自定义CSS来修改报告样式:
css复制/* allure-报告样式覆盖.css */
.graph-container {
background-color: #f5f5f5;
}
SSL证书错误
bash复制pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org package_name
版本冲突
bash复制pipdeptree # 查看依赖树
pip check # 检查冲突
测试发现失败
test_*.py或*_test.pytest_开头pytest.ini配置夹具作用域问题
autouse=True自动应用夹具报告为空
--alluredir参数正确样式丢失
allure open代替直接打开index.html--clean参数跨域问题
python复制headers = {
'Origin': 'http://localhost',
'Access-Control-Request-Method': 'POST'
}
Cookie处理
python复制session = requests.Session()
response = session.post(login_url, data=credentials)
assert 'sessionid' in session.cookies
文件上传
python复制files = {'file': ('report.xlsx', open('report.xlsx', 'rb'), 'application/vnd.ms-excel')}
response = requests.post(url, files=files)
在实际项目中,我建议建立一个基础测试类来封装这些通用操作,使测试用例更加简洁:
python复制class APITestBase:
@pytest.fixture(autouse=True)
def setup(self):
self.session = requests.Session()
self.base_url = "https://api.example.com"
yield
self.session.close()
def request(self, method, endpoint, **kwargs):
url = f"{self.base_url}{endpoint}"
return self.session.request(method, url, **kwargs)