云计算百科
云计算领域专业知识百科平台

pytest冒烟测试用例过滤执行实例

如何在庞大的全量测试集中,精准定位并执行核心链路,而无需重构整个测试生态。

实战方案设计

核心思路:方案一提供物理隔离的目录结构,适合稳定版本快速验证;方案二提供动态优先级过滤,支持按需灵活调度。两者结合,可以覆盖大多数业务场景。

实例结构:

test_project/
├── conftest.py # pytest钩子配置
├── pytest.ini # pytest配置文件
├── requirements.txt # 依赖包
├── test_smoke/ # 方案一:冒烟用例独立目录
│ ├── test_login.py
│ └── test_checkout.py
├── test_full/ # 方案一:全量用例目录
│ ├── test_login.py
│ ├── test_checkout.py
│ ├── test_profile.py
│ └── test_orders.py
├── test_cases/ # 方案二:YAML用例集中管理
│ ├── login.yaml
│ ├── checkout.yaml
│ └── profile.yaml
└── run_tests.py # 方案二:自定义命令行参数处理

核心代码实现

1. pytest.ini(pytest基础配置)

[pytest]
testpaths = .
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -v –tb=short
markers =
smoke: 冒烟测试标记
blocker: 高优先级阻塞问题
critical: 关键优先级问题
normal: 普通优先级问题

2. conftest.py(pytest钩子与自定义参数)

import pytest
from typing import List, Dict
import yaml
import os

def pytest_addoption(parser):
"""自定义命令行参数"""
parser.addoption("–level", action="store", default=None,
help="指定用例优先级: blocker,critical,normal")
parser.addoption("–cases", action="store", default=None,
help="指定用例目录路径")
parser.addoption("–type", action="store", default=None,
help="指定用例类型: yaml, python")

def pytest_configure(config):
"""动态注册marker"""
config.addinivalue_line("markers", "smoke: 冒烟测试")
config.addinivalue_line("markers", "blocker: 阻塞级别")
config.addinivalue_line("markers", "critical: 关键级别")
config.addinivalue_line("markers", "normal: 普通级别")

def pytest_collection_modifyitems(config, items):
"""动态过滤用例(方案二实现)"""
level = config.getoption("–level")
if not level:
return

levels = level.split(",")
selected_items = []

for item in item:
# 获取用例的所有marker
markers = {mark.name for mark in item.iter_markers()}

# 检查是否匹配指定优先级
if any(lvl in markers for lvl in levels):
selected_items.append(item)

items[:] = selected_items
if selected_items:
config.hook.pytest_deselected(items=items)

3. run_tests.py(方案二的YAML解析器)

import pytest
import yaml
import os
from typing import List, Dict

def case_parser(case_type: str, case_dir: str, level: str = None) -> Dict:
"""
YAML用例解析器(方案二核心逻辑)

Args:
case_type: 用例类型,如 'yaml'
case_dir: 用例目录路径
level: 优先级过滤条件

Returns:
包含过滤后用例信息的字典
"""
case_infos = []

if case_type != "yaml":
return {"case_infos": case_infos}

# 遍历目录获取所有YAML文件
yaml_files = []
for root, _, files in os.walk(case_dir):
for file in files:
if file.endswith(('.yaml', '.yml')):
yaml_files.append(os.path.join(root, file))

# 解析YAML用例
yaml_case_infos = []
for yaml_file in yaml_files:
with open(yaml_file, 'r', encoding='utf-8') as f:
data = yaml.safe_load(f)
if isinstance(data, list):
yaml_case_infos.extend(data)
else:
yaml_case_infos.append(data)

# 根据优先级过滤(方案二关键逻辑)
if level:
levels = level.split(",")
for case_info in yaml_case_infos:
if case_info.get("rank") in levels:
case_infos.append(case_info)
else:
case_infos = yaml_case_infos

return {"case_infos": case_infos}

def pytest_generate_tests(metafunc):
"""动态生成测试用例(YAML用例注入)"""
if "case_info" in metafunc.fixturenames:
case_dir = metafunc.config.getoption("–cases")
case_type = metafunc.config.getoption("–type")
level = metafunc.config.getoption("–level")

if case_dir and case_type:
result = case_parser(case_type, case_dir, level)
metafunc.parametrize("case_info", result["case_infos"])

4. 方案一:目录分离的测试用例

test_smoke/test_login.py

import pytest

@pytest.mark.smoke
def test_login_success():
"""冒烟测试:登录成功"""
print("执行冒烟测试:登录成功")
assert True

@pytest.mark.smoke
def test_login_with_valid_credentials():
"""冒烟测试:有效凭证登录"""
print("执行冒烟测试:有效凭证登录")
assert True

test_smoke/test_checkout.py

import pytest

@pytest.mark.smoke
@pytest.mark.blocker
def test_checkout_basic_flow():
"""冒烟测试:基础购物流程"""
print("执行冒烟测试:基础购物流程")
assert True

test_full/test_login.py(包含更多边界场景)

import pytest

@pytest.mark.smoke
def test_login_success():
"""全量测试:登录成功"""
assert True

@pytest.mark.normal
def test_login_with_invalid_password():
"""全量测试:错误密码登录"""
assert True

@pytest.mark.normal
def test_login_with_empty_fields():
"""全量测试:空字段登录"""
assert True

@pytest.mark.critical
def test_login_with_locked_account():
"""全量测试:锁定账号登录"""
assert True

5. 方案二:YAML用例文件

test_cases/login.yaml

– desc: 登录用例-正常登录
rank: blocker
steps:
– step: 打开登录页面
expected: 页面加载成功
– step: 输入用户名密码
expected: 输入成功
– step: 点击登录按钮
expected: 登录成功跳转

– desc: 登录用例-错误密码
rank: normal
steps:
– step: 打开登录页面
expected: 页面加载成功
– step: 输入用户名和错误密码
expected: 输入成功
– step: 点击登录按钮
expected: 提示密码错误

– desc: 登录用例-锁定账号
rank: critical
steps:
– step: 打开登录页面
expected: 页面加载成功
– step: 输入锁定账号
expected: 输入成功
– step: 点击登录按钮
expected: 提示账号已锁定

test_cases/checkout.yaml

– desc: 购物流程-基础流程
rank: blocker
steps:
– step: 选择商品
expected: 商品选中
– step: 加入购物车
expected: 购物车数量增加
– step: 提交订单
expected: 订单提交成功

– desc: 购物流程-库存不足
rank: critical
steps:
– step: 选择库存不足商品
expected: 商品选中
– step: 加入购物车
expected: 提示库存不足

6. YAML用例驱动测试(方案二执行器)

test_yaml_runner.py

import pytest

def test_yaml_case(case_info):
"""
YAML用例通用执行器
通过conftest.py中的pytest_generate_tests动态注入用例
"""
print(f"\\n执行用例:{case_info['desc']}")
print(f"优先级:{case_info.get('rank', '无')}")

for idx, step in enumerate(case_info['steps'], 1):
print(f"步骤{idx}: {step['step']}")
print(f"预期: {step['expected']}")
# 这里可以添加实际的测试逻辑
# 例如调用API、操作页面等

assert True # 简化示例,实际应根据步骤执行结果断言

7. requirements.txt

pytest>=7.0.0
pyyaml>=6.0
pytest-html>=3.0.0

执行示例与命令

方案一:目录分离模式执行

# 只执行冒烟测试(指定smoke目录)
pytest test_smoke/ -v

# 执行全量测试(指定full目录)
pytest test_full/ -v

# 使用自定义参数执行冒烟测试
pytest –cases=./test_smoke –type=python -v

方案二:优先级过滤模式执行

# 只执行blocker和critical级别用例(冒烟测试)
pytest –level=blocker,critical -v

# 执行指定级别用例
pytest –level=normal -v

# 结合YAML用例执行
pytest test_yaml_runner.py –cases=./test_cases –type=yaml –level=blocker,critical -v

组合场景执行

# 执行冒烟目录 + blocker级别用例
pytest test_smoke/ –level=blocker -v

# 并行执行多个测试集合
pytest test_smoke/ test_full/ –level=blocker,critical -v

实例亮点与最佳实践体现

  • 方案一体现:

    • test_smoke/ 和 test_full/ 物理分离,结构清晰
    • 通过 pytest 命令直接指定目录执行,简单高效
    • 适合项目稳定后,冒烟用例不常变化的场景
  • 方案二体现:

    • YAML 用例统一管理,便于维护和版本控制
    • 通过 –level 参数动态过滤,支持灵活调度
    • 适合用例频繁调整、需要按优先级分批执行的场景
  • 两者结合:

    • 目录分离处理核心稳定链路(如登录、支付)
    • YAML + 优先级处理需要动态调整的业务场景(如营销活动)
    • 通过同一个配置体系(pytest.ini + conftest.py)统一管理
  • 工程化细节:

    • pytest 钩子实现动态过滤,无需修改测试代码
    • Marker 体系标准化用例分类
    • YAML 解析器支持优先级字段过滤,完全复现你提供的逻辑
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » pytest冒烟测试用例过滤执行实例
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!