参数化测试

基础 @pytest.mark.parametrize

import pytest # 单个参数 @pytest.mark.parametrize("n,expected", [ (1, 1), (5, 120), (10, 3628800), ]) def test_factorial(n, expected): assert factorial(n) == expected # 多个参数 — 元组形式 @pytest.mark.parametrize("input_str,expected", [ ("hello", "HELLO"), ("World", "WORLD"), ("", ""), ]) def test_to_upper(input_str, expected): assert input_str.upper() == expected

ids — 自定义测试名称

import pytest # 显式字符串 IDs @pytest.mark.parametrize("value,expected", [ (0, True), (1, False), (-1, False), ], ids=["零", "正数", "负数"]) def test_is_zero(value, expected): assert (value == 0) == expected # pytest.param 携带元数据 @pytest.mark.parametrize("config", [ pytest.param({"debug": True}, id="调试模式"), pytest.param({"debug": False}, id="生产模式"), ])

indirect — 通过 Fixtures 传参

import pytest @pytest.fixture def user_factory(request): role = request.param return create_user(role=role, name=f"{role}_用户") @pytest.mark.parametrize("user_factory", ["admin", "editor", "viewer"], indirect=True) def test_user_dashboard(user_factory): user = user_factory response = client.get("/dashboard", user=user) assert response.status_code == 200

矩阵测试 — 叠加 parametrize

import pytest # 叠加产生笛卡尔积(2x3 = 6 个测试用例) @pytest.mark.parametrize("browser", ["chrome", "firefox"]) @pytest.mark.parametrize("resolution", ["1920x1080", "1366x768", "375x812"]) def test_layout(browser, resolution): driver = setup_driver(browser, resolution) assert driver.page_renders_correctly()

parametrize 与 Fixtures 结合

import pytest @pytest.fixture def api_client(app): return app.test_client() @pytest.mark.parametrize("endpoint,expected_status", [ ("/health", 200), ("/api/v1/users", 200), ("/nonexistent", 404), ]) def test_endpoints(api_client, auth_headers, endpoint, expected_status): response = api_client.get(endpoint, headers=auth_headers) assert response.status_code == expected_status

parametrize 与标记组合

标记用法效果
marks=pytest.mark.skip跳过特定用例无条件跳过
pytest.mark.skipif条件跳过根据条件决定是否跳过
marks=pytest.mark.xfail预期失败失败视为通过
pytest.mark.slow自定义标记用 -m slow 选择执行