02.pytest中常用的参数

Pytest 中常用的参数详解

1. 前言

1.1 什么是 pytest 参数

Pytest 提供了丰富的命令行参数,这些参数可以控制测试的执行方式、输出格式、测试筛选等。通过使用这些参数,你可以更灵活地运行和管理测试用例。

1.2 为什么要学习参数

  • 提高效率:快速运行特定的测试用例
  • 调试方便:控制输出信息,便于定位问题
  • 灵活筛选:只运行需要的测试用例
  • 优化执行:控制测试的执行顺序和方式

1.3 如何查看所有参数

最简单的方法:运行 pytest -hpytest --help

# 查看所有可用的参数和选项
pytest -h

# 或者
pytest --help

输出示例

usage: pytest [options] [file_or_dir] [file_or_dir] [...]

positional arguments:
  file_or_dir

general:
  -v, --verbose         increase verbosity
  -q, --quiet           decrease verbosity
  -s, --capture=no      disable output capturing
  -x, --exitfirst       exit instantly on first error
  ...

2. 基础输出控制参数

2.1 -v / --verbose:增加详细程度

2.1.1 参数说明

-v 参数用于增加测试输出的详细程度,显示每个测试用例的名称和结果。

2.1.2 使用场景

  • 需要查看每个测试用例的执行情况
  • 调试时查看详细的测试信息
  • 需要区分哪些测试通过、哪些失败

2.1.3 基本用法

不使用 -v 参数(默认模式):

pytest test_example.py

输出示例

======================== test session starts ========================
platform win32 -- Python 3.9.0, pytest-7.0.0
collected 3 items

test_example.py ...                                          [100%]

======================== 3 passed in 0.05s ========================

使用 -v 参数

pytest -v test_example.py

输出示例

======================== test session starts ========================
platform win32 -- Python 3.9.0, pytest-7.0.0
collected 3 items

test_example.py::test_addition PASSED                          [ 33%]
test_example.py::test_subtraction PASSED                       [ 66%]
test_example.py::test_multiplication PASSED                    [100%]

======================== 3 passed in 0.05s ========================

2.1.4 详细示例

测试文件:test_math.py

def test_addition():
    """测试加法"""
    assert 1 + 1 == 2

def test_subtraction():
    """测试减法"""
    assert 5 - 3 == 2

def test_multiplication():
    """测试乘法"""
    assert 2 * 3 == 6

def test_division():
    """测试除法"""
    assert 10 / 2 == 5

运行命令对比

  1. 默认模式(不显示测试名称):

    pytest test_math.py

    输出:

    test_math.py ....                                          [100%]
    ======================== 4 passed in 0.02s ========================
  2. 详细模式(显示每个测试名称):

    pytest -v test_math.py

    输出:

    
    test_math.py::test_addition PASSED                          [ 25%]
    test_math.py::test_subtraction PASSED                        [ 50%]
    test_math.py::test_multiplication PASSED                     [ 75%]
    test_math.py::test_division PASSED                           [100%]

======================== 4 passed in 0.02s ========================


#### 2.1.5 更详细的模式:`-vv`

使用 `-vv` 可以获得更详细的输出:

```bash
pytest -vv test_math.py

输出示例

======================== test session starts ========================
platform win32 -- Python 3.9.0, pytest-7.0.0, pluggy-1.0.0
rootdir: C:UsersAdministratorDesktoppython自动化测试
collected 4 items

test_math.py::test_addition PASSED                          [ 25%]
test_math.py::test_subtraction PASSED                        [ 50%]
test_math.py::test_multiplication PASSED                     [ 75%]
test_math.py::test_division PASSED                           [100%]

======================== 4 passed in 0.02s ========================

2.1.6 实际应用场景

场景 1:查看哪些测试用例正在运行

# 运行所有测试,查看每个测试的名称
pytest -v

# 输出会显示:
# test_login.py::test_user_login PASSED
# test_login.py::test_admin_login PASSED
# test_user.py::test_create_user PASSED

场景 2:调试时查看详细信息

# 当测试失败时,使用 -v 可以看到是哪个测试失败了
pytest -v test_api.py

# 输出会明确显示:
# test_api.py::test_get_user FAILED
# test_api.py::test_create_user PASSED

2.2 -s / --capture=no:显示打印输出

2.2.1 参数说明

-s 参数用于禁用输出捕获,允许测试用例中的 print() 语句正常显示在控制台。

2.2.2 为什么需要这个参数

默认情况下,pytest 会捕获所有标准输出(stdout)和标准错误(stderr),只有在测试失败时才会显示。这意味着:

  • 测试中的 print() 语句不会显示
  • 调试信息无法看到
  • 无法实时查看程序运行状态

2.2.3 基本用法

不使用 -s 参数(默认捕获输出):

# test_example.py
def test_with_print():
    print("这是测试中的打印语句")
    print("这行不会显示在控制台")
    assert True

运行:

pytest test_example.py

输出:

test_example.py .                                          [100%]
======================== 1 passed in 0.01s ========================

注意print() 的内容没有显示!

使用 -s 参数

pytest -s test_example.py

输出:

======================== test session starts ========================
这是测试中的打印语句
这行不会显示在控制台
test_example.py .                                          [100%]

======================== 1 passed in 0.01s ========================

注意:现在 print() 的内容显示了!

2.2.4 详细示例

示例 1:调试信息输出

# test_debug.py
def test_user_login():
    username = "admin"
    password = "123456"

    print(f"尝试登录,用户名:{username}")
    print(f"密码:{password}")

    # 模拟登录逻辑
    if username == "admin" and password == "123456":
        print("登录成功!")
        assert True
    else:
        print("登录失败!")
        assert False

不使用 -s

pytest test_debug.py

输出:

test_debug.py .                                          [100%]
======================== 1 passed in 0.01s ========================

看不到任何调试信息!

使用 -s

pytest -s test_debug.py

输出:

======================== test session starts ========================
尝试登录,用户名:admin
密码:123456
登录成功!
test_debug.py .                                          [100%]

======================== 1 passed in 0.01s ========================

可以看到所有调试信息!

示例 2:API 测试中的请求信息

# test_api.py
import requests

def test_get_user():
    url = "https://api.example.com/users/1"
    print(f"发送 GET 请求到:{url}")

    response = requests.get(url)
    print(f"响应状态码:{response.status_code}")
    print(f"响应内容:{response.text}")

    assert response.status_code == 200

使用 -s 查看请求详情

pytest -s test_api.py

输出:

======================== test session starts ========================
发送 GET 请求到:https://api.example.com/users/1
响应状态码:200
响应内容:{"id": 1, "name": "John"}
test_api.py .                                          [100%]

======================== 1 passed in 0.15s ========================

示例 3:数据库操作调试

# test_database.py
def test_create_user():
    user_data = {"name": "张三", "age": 25}
    print(f"准备创建用户:{user_data}")

    # 模拟数据库操作
    user_id = create_user_in_db(user_data)
    print(f"用户创建成功,ID:{user_id}")

    assert user_id is not None

使用 -s 查看数据库操作过程

pytest -s test_database.py

2.2.5 组合使用:-sv

通常 -s-v 一起使用,既显示打印输出,又显示详细的测试信息:

pytest -sv test_example.py

输出示例

======================== test session starts ========================
这是测试中的打印语句
test_example.py::test_with_print PASSED                     [100%]

======================== 1 passed in 0.01s ========================

2.2.6 实际应用场景

场景 1:调试失败的测试

def test_complex_calculation():
    result = 0
    for i in range(10):
        result += i
        print(f"第 {i} 次循环,当前结果:{result}")

    assert result == 45

运行:

pytest -s test_complex_calculation.py

可以看到每次循环的结果,便于定位问题。

场景 2:查看 API 请求和响应

def test_api_call():
    print("=== 开始 API 调用 ===")
    response = api_client.get("/users")
    print(f"响应状态:{response.status_code}")
    print(f"响应数据:{response.json()}")
    print("=== API 调用结束 ===")
    assert response.status_code == 200

场景 3:查看文件操作过程

def test_file_operation():
    print("开始读取文件...")
    with open("data.txt", "r") as f:
        content = f.read()
        print(f"文件内容:{content}")
    print("文件读取完成")
    assert len(content) > 0

2.3 -q / --quiet:减少输出

2.3.1 参数说明

-q 参数用于减少测试输出的信息,只显示最简洁的结果。

2.3.2 使用场景

  • 测试用例很多,只需要看总体结果
  • CI/CD 环境中,减少日志输出
  • 快速查看测试是否通过

2.3.3 基本用法

默认输出

pytest test_example.py

输出:

======================== test session starts ========================
platform win32 -- Python 3.9.0, pytest-7.0.0
collected 3 items

test_example.py ...                                          [100%]

======================== 3 passed in 0.05s ========================

使用 -q 参数

pytest -q test_example.py

输出:

...                                                          [100%]
3 passed in 0.05s

2.3.4 详细示例

测试文件:test_multiple.py

def test_1(): assert True
def test_2(): assert True
def test_3(): assert True
def test_4(): assert True
def test_5(): assert True

对比输出

  1. 默认模式
    pytest test_multiple.py

    输出:

    
    ======================== test session starts ========================
    platform win32 -- Python 3.9.0, pytest-7.0.0
    collected 5 items

test_multiple.py ….. [100%]

======================== 5 passed in 0.02s ========================


2. **安静模式**:
```bash
pytest -q test_multiple.py

输出:

.....                                                         [100%]
5 passed in 0.02s

2.3.5 实际应用场景

场景 1:运行大量测试用例

# 运行整个项目的测试,只需要看总体结果
pytest -q

# 输出:
# ..........F...                                          [100%]
# 1 failed, 12 passed in 2.34s

场景 2:CI/CD 环境

# 在持续集成中,使用 -q 减少日志
pytest -q --tb=short

3. 测试执行控制参数

3.1 -x / --exitfirst:遇到失败立即退出

3.1.1 参数说明

-x 参数用于快速退出模式,当遇到第一个失败的测试用例时,立即停止执行后续测试。

3.1.2 使用场景

  • 快速定位第一个失败的测试
  • 开发时,修复一个错误后再继续
  • 不想等待所有测试执行完成
  • 节省时间,快速反馈

3.1.3 基本用法

不使用 -x 参数(默认会执行所有测试):

# test_example.py
def test_1():
    assert True  # 通过

def test_2():
    assert False  # 失败

def test_3():
    assert True  # 通过(但不会执行到这里)

运行:

pytest test_example.py

输出:

test_example.py F.                                          [ 66%]
======================== FAILURES ========================
test_2 FAILED
...
======================== 1 failed, 2 passed in 0.05s ========================

注意:即使 test_2 失败了,test_3 仍然会执行。

使用 -x 参数

pytest -x test_example.py

输出:

test_example.py F                                           [ 33%]
======================== FAILURES ========================
test_2 FAILED
...
======================== 1 failed, 1 passed in 0.02s ========================

注意test_2 失败后,立即停止,test_3 没有执行。

3.1.4 详细示例

示例 1:多个测试用例,第一个失败

# test_login.py
def test_login_with_valid_credentials():
    """测试有效凭据登录"""
    assert True  # 通过

def test_login_with_invalid_username():
    """测试无效用户名"""
    assert False  # 失败 ← 第一个失败

def test_login_with_invalid_password():
    """测试无效密码"""
    assert True  # 不会执行

def test_login_with_empty_fields():
    """测试空字段"""
    assert True  # 不会执行

不使用 -x

pytest -v test_login.py

输出:

test_login.py::test_login_with_valid_credentials PASSED    [ 25%]
test_login.py::test_login_with_invalid_username FAILED     [ 50%]
test_login.py::test_login_with_invalid_password PASSED     [ 75%]
test_login.py::test_login_with_empty_fields PASSED         [100%]

======================== 1 failed, 3 passed in 0.03s ========================

所有测试都执行了。

使用 -x

pytest -x -v test_login.py

输出:

test_login.py::test_login_with_valid_credentials PASSED    [ 25%]
test_login.py::test_login_with_invalid_username FAILED     [ 50%]

======================== 1 failed, 1 passed in 0.02s ========================

遇到第一个失败就停止了。

示例 2:修复错误的工作流程

# 第一步:运行测试,找到第一个错误
pytest -x test_login.py

# 输出显示 test_login_with_invalid_username 失败

# 第二步:修复代码
# ... 修改代码 ...

# 第三步:再次运行,找到下一个错误(如果有)
pytest -x test_login.py

# 重复直到所有测试通过

示例 3:多个文件中的测试

# test_file1.py
def test_1(): assert True
def test_2(): assert False  # 失败

# test_file2.py
def test_3(): assert True
def test_4(): assert True

不使用 -x

pytest -v

输出:

test_file1.py::test_1 PASSED                               [ 25%]
test_file1.py::test_2 FAILED                               [ 50%]
test_file2.py::test_3 PASSED                               [ 75%]
test_file2.py::test_4 PASSED                               [100%]

======================== 1 failed, 3 passed in 0.03s ========================

使用 -x

pytest -x -v

输出:

test_file1.py::test_1 PASSED                               [ 25%]
test_file1.py::test_2 FAILED                               [ 50%]

======================== 1 failed, 1 passed in 0.02s ========================

遇到第一个失败就停止,不会执行 test_file2.py 中的测试。

3.1.5 组合使用:-xv-xvs

# 快速退出 + 详细输出
pytest -xv test_example.py

# 快速退出 + 详细输出 + 显示打印
pytest -xvs test_example.py

3.1.6 实际应用场景

场景 1:TDD(测试驱动开发)工作流

# 1. 编写测试(会失败)
pytest -x test_new_feature.py

# 2. 编写代码使测试通过
# ... 编写代码 ...

# 3. 再次运行测试
pytest -x test_new_feature.py

# 4. 如果通过,继续下一个功能

场景 2:快速定位问题

# 当有大量测试时,使用 -x 快速找到第一个问题
pytest -x tests/

# 修复后,再次运行找到下一个问题
pytest -x tests/

场景 3:开发时的快速反馈

# 开发时,每次修改后快速运行,遇到错误立即停止
pytest -xvs test_current_feature.py

3.2 -m / --markers:用例筛选(标记)

3.2.1 参数说明

-m 参数用于根据标记(marker)筛选测试用例。标记是 pytest 中用于分类和组织测试用例的强大功能。

3.2.2 什么是标记(Marker)

标记是给测试用例打上的”标签”,用于:

  • 分类测试用例(如:冒烟测试、集成测试、慢速测试)
  • 选择性运行测试
  • 组织测试套件

3.2.3 基本用法

第一步:在测试用例上添加标记

# test_example.py
import pytest

@pytest.mark.smoke
def test_login():
    """冒烟测试:登录功能"""
    assert True

@pytest.mark.smoke
def test_logout():
    """冒烟测试:登出功能"""
    assert True

@pytest.mark.integration
def test_user_flow():
    """集成测试:用户流程"""
    assert True

@pytest.mark.slow
def test_performance():
    """慢速测试:性能测试"""
    assert True

第二步:运行特定标记的测试

# 只运行标记为 smoke 的测试
pytest -m smoke

# 只运行标记为 integration 的测试
pytest -m integration

# 只运行标记为 slow 的测试
pytest -m slow

3.2.4 详细示例

示例 1:基本标记使用

# test_api.py
import pytest

@pytest.mark.smoke
def test_api_health_check():
    """冒烟测试:API 健康检查"""
    assert True

@pytest.mark.smoke
def test_api_login():
    """冒烟测试:API 登录"""
    assert True

@pytest.mark.integration
def test_api_user_creation():
    """集成测试:创建用户"""
    assert True

@pytest.mark.integration
def test_api_user_deletion():
    """集成测试:删除用户"""
    assert True

@pytest.mark.slow
def test_api_bulk_operations():
    """慢速测试:批量操作"""
    assert True

运行不同标记的测试

  1. 运行所有冒烟测试
    pytest -m smoke -v

输出:

test_api.py::test_api_health_check PASSED                  [ 50%]
test_api.py::test_api_login PASSED                         [100%]

======================== 2 passed in 0.02s ========================
  1. 运行所有集成测试
    pytest -m integration -v

输出:

test_api.py::test_api_user_creation PASSED                  [ 50%]
test_api.py::test_api_user_deletion PASSED                  [100%]

======================== 2 passed in 0.02s ========================
  1. 运行所有慢速测试
    pytest -m slow -v

输出:

test_api.py::test_api_bulk_operations PASSED               [100%]

======================== 1 passed in 0.02s ========================

示例 2:多个标记组合

# test_advanced.py
import pytest

@pytest.mark.smoke
@pytest.mark.api
def test_api_login():
    """同时有 smoke 和 api 标记"""
    assert True

@pytest.mark.smoke
@pytest.mark.ui
def test_ui_login():
    """同时有 smoke 和 ui 标记"""
    assert True

@pytest.mark.integration
@pytest.mark.api
def test_api_user_flow():
    """同时有 integration 和 api 标记"""
    assert True

运行组合标记的测试

# 运行同时有 smoke 和 api 标记的测试
pytest -m "smoke and api" -v

# 运行有 smoke 或 api 标记的测试
pytest -m "smoke or api" -v

# 运行有 smoke 但没有 api 标记的测试
pytest -m "smoke and not api" -v

示例 3:在 pytest.ini 中注册标记

为了避免警告,需要在 pytest.ini 中注册标记:

# pytest.ini
[pytest]
markers =
    smoke: 冒烟测试,快速验证核心功能
    integration: 集成测试,测试多个模块的协作
    slow: 慢速测试,执行时间较长
    api: API 测试
    ui: UI 测试
    regression: 回归测试

完整的测试文件示例

# test_complete.py
import pytest

@pytest.mark.smoke
@pytest.mark.regression
def test_user_login():
    """冒烟测试 + 回归测试:用户登录"""
    assert True

@pytest.mark.integration
def test_user_registration_flow():
    """集成测试:用户注册流程"""
    assert True

@pytest.mark.slow
@pytest.mark.performance
def test_load_testing():
    """慢速测试 + 性能测试:负载测试"""
    assert True

@pytest.mark.api
def test_get_user_api():
    """API 测试:获取用户"""
    assert True

运行示例

# 运行所有冒烟测试
pytest -m smoke -v

# 运行所有回归测试
pytest -m regression -v

# 运行所有 API 测试
pytest -m api -v

# 运行慢速测试(通常跳过)
pytest -m "not slow" -v

3.2.5 标记表达式

pytest 支持复杂的标记表达式:

基本操作符

  • and:同时满足多个标记
  • or:满足任意一个标记
  • not:不满足标记

示例

# test_expressions.py
import pytest

@pytest.mark.smoke
@pytest.mark.api
def test_1(): pass

@pytest.mark.smoke
@pytest.mark.ui
def test_2(): pass

@pytest.mark.integration
def test_3(): pass

@pytest.mark.slow
def test_4(): pass

运行示例

# 运行同时有 smoke 和 api 的测试
pytest -m "smoke and api" -v

# 运行有 smoke 或 api 的测试
pytest -m "smoke or api" -v

# 运行有 smoke 但没有 api 的测试
pytest -m "smoke and not api" -v

# 运行不是 slow 的测试
pytest -m "not slow" -v

# 运行 (smoke 或 integration) 且不是 slow 的测试
pytest -m "(smoke or integration) and not slow" -v

3.2.6 实际应用场景

场景 1:CI/CD 中的测试分层

# 快速冒烟测试(每次提交都运行)
pytest -m smoke

# 完整测试套件(每天运行)
pytest -m "not slow"

# 完整测试(包括慢速测试,每周运行)
pytest

场景 2:开发时的快速测试

# 开发时只运行快速测试
pytest -m "not slow" -v

# 修复 bug 后运行相关测试
pytest -m regression -v

场景 3:按模块运行测试

# test_user.py
@pytest.mark.user
def test_create_user(): pass

# test_order.py
@pytest.mark.order
def test_create_order(): pass
# 只测试用户模块
pytest -m user -v

# 只测试订单模块
pytest -m order -v

4. 测试发现和筛选参数

4.1 -k:通过表达式筛选测试

4.1.1 参数说明

-k 参数用于通过测试名称的表达式来筛选测试用例,非常灵活和强大。

4.1.2 基本用法

# 运行名称包含 "login" 的测试
pytest -k login

# 运行名称包含 "user" 的测试
pytest -k user

# 运行名称包含 "api" 的测试
pytest -k api

4.1.3 详细示例

测试文件:test_example.py

def test_user_login(): pass
def test_user_logout(): pass
def test_admin_login(): pass
def test_admin_logout(): pass
def test_create_order(): pass
def test_delete_order(): pass

筛选示例

  1. 包含特定字符串
    # 运行所有包含 "login" 的测试
    pytest -k login -v

    输出:

    
    test_example.py::test_user_login PASSED                     [ 50%]
    test_example.py::test_admin_login PASSED                    [100%]

======================== 2 passed in 0.01s ========================


2. **使用逻辑运算符**:
```bash
# 运行包含 "user" 且包含 "login" 的测试
pytest -k "user and login" -v

输出:

test_example.py::test_user_login PASSED                     [100%]

======================== 1 passed in 0.01s ========================
  1. 排除特定测试
    # 运行不包含 "admin" 的测试
    pytest -k "not admin" -v

    输出:

    
    test_example.py::test_user_login PASSED                     [ 25%]
    test_example.py::test_user_logout PASSED                    [ 50%]
    test_example.py::test_create_order PASSED                   [ 75%]
    test_example.py::test_delete_order PASSED                   [100%]

======================== 4 passed in 0.01s ========================


4. **复杂表达式**:
```bash
# 运行包含 "user" 或 "order" 的测试
pytest -k "user or order" -v

# 运行包含 "login" 但不包含 "admin" 的测试
pytest -k "login and not admin" -v

4.1.4 实际应用场景

场景 1:快速运行相关测试

# 修改了登录功能,只运行登录相关测试
pytest -k login -v

# 修改了用户功能,只运行用户相关测试
pytest -k user -v

场景 2:排除特定测试

# 跳过已知有问题的测试
pytest -k "not broken" -v

4.2 --collect-only:只收集不执行

4.2.1 参数说明

--collect-only 参数用于只收集测试用例,不执行它们。用于查看 pytest 发现了哪些测试。

4.2.2 使用场景

  • 验证测试发现规则是否正确
  • 查看所有可用的测试用例
  • 调试测试发现问题

4.2.3 基本用法

# 只收集测试,不执行
pytest --collect-only

# 详细模式
pytest --collect-only -v

4.2.4 详细示例

测试文件结构

tests/
├── test_login.py
├── test_user.py
└── api/
    └── test_api.py

运行收集命令

pytest --collect-only -v

输出示例

======================== test session starts ========================
platform win32 -- Python 3.9.0, pytest-7.0.0
collected 5 items

<Module test_login.py>
  <Function test_user_login>
  <Function test_admin_login>
<Module test_user.py>
  <Function test_create_user>
  <Function test_delete_user>
<Module api/test_api.py>
  <Function test_get_user>

======================== 5 tests collected in 0.01s ========================

5. 输出格式控制参数

5.1 --tb:回溯信息格式

5.1.1 参数说明

--tb 参数用于控制测试失败时的回溯(traceback)信息显示格式。

5.1.2 可选值

  • --tb=short:简短的回溯信息
  • --tb=long:详细的长格式回溯信息(默认)
  • --tb=line:每个失败只显示一行
  • --tb=no:不显示回溯信息
  • --tb=auto:自动选择格式

5.1.3 详细示例

测试文件:test_example.py

def test_division():
    result = 10 / 0  # 会失败
    assert result > 0

不同格式对比

  1. --tb=long(默认,详细)
    pytest --tb=long test_example.py

    输出:

    
    ======================== FAILURES ========================
    test_division FAILED

test_example.py:2: in test_division result = 10 / 0 E ZeroDivisionError: division by zero


2. **`--tb=short`(简短)**:
```bash
pytest --tb=short test_example.py

输出:

test_example.py:2: ZeroDivisionError: division by zero
  1. --tb=line(一行)

    pytest --tb=line test_example.py

    输出:

    test_example.py:2: ZeroDivisionError
  2. --tb=no(不显示)

    pytest --tb=no test_example.py

    输出:

    test_example.py F                                          [100%]
    ======================== 1 failed in 0.01s ========================

5.1.4 实际应用场景

场景 1:CI/CD 环境

# 使用简短格式,减少日志
pytest --tb=short

场景 2:快速查看失败原因

# 只显示一行,快速浏览
pytest --tb=line

6. 参数组合使用

6.1 常用组合

在实际使用中,经常将多个参数组合使用:

# 详细输出 + 显示打印 + 快速退出
pytest -xvs

# 详细输出 + 显示打印 + 只运行冒烟测试
pytest -sv -m smoke

# 详细输出 + 显示打印 + 快速退出 + 简短回溯
pytest -xvs --tb=short

# 安静模式 + 快速退出
pytest -qx

6.2 实际工作流示例

开发时的常用命令

# 开发当前功能时
pytest -xvs test_current_feature.py

# 运行所有快速测试
pytest -sv -m "not slow"

# 修复 bug 后验证
pytest -xvs -k bug_fix

CI/CD 中的常用命令

# 快速冒烟测试
pytest -q -m smoke --tb=short

# 完整测试套件
pytest -v --tb=short -m "not slow"

7. 配置文件中的参数

7.1 在 pytest.ini 中设置默认参数

可以在 pytest.ini 中使用 addopts 设置默认参数:

# pytest.ini
[pytest]
addopts = -v --tb=short
markers =
    smoke: 冒烟测试
    integration: 集成测试
    slow: 慢速测试

这样每次运行 pytest 时,会自动应用这些参数。

7.2 覆盖配置文件中的参数

即使配置文件中设置了参数,命令行参数仍然可以覆盖:

# pytest.ini
[pytest]
addopts = -v
# 命令行参数会覆盖配置文件
pytest -q  # 使用 -q,忽略配置文件中的 -v

8. 总结

8.1 最常用的参数组合

  1. 开发调试pytest -xvs

    • -x:遇到失败立即退出
    • -v:详细输出
    • -s:显示打印
  2. 快速验证pytest -m smoke -v

    • 只运行冒烟测试
  3. 完整测试pytest -v --tb=short

    • 详细输出,简短回溯
  4. CI/CDpytest -q --tb=short

    • 安静模式,简短回溯

8.2 参数速查表

参数 全称 作用 常用场景
-v --verbose 增加详细程度 查看每个测试的执行情况
-s --capture=no 显示打印输出 调试时查看 print 语句
-x --exitfirst 遇到失败立即退出 快速定位第一个错误
-m --markers 用例筛选 运行特定标记的测试
-k 通过名称筛选 运行名称包含某字符串的测试
-q --quiet 减少输出 CI/CD 环境
--tb 回溯信息格式 控制错误信息显示
--collect-only 只收集不执行 查看发现的测试

8.3 学习建议

  1. 从基础开始:先掌握 -v-s-x 这三个最常用的参数
  2. 实践为主:多写测试用例,多尝试不同的参数组合
  3. 查看帮助:遇到不熟悉的参数,使用 pytest -h 查看帮助
  4. 配置文件:将常用的参数配置到 pytest.ini

9. 常见问题解答

9.1 如何查看所有可用参数?

pytest -h
# 或
pytest --help

9.2 参数可以组合使用吗?

可以!例如:

pytest -xvs test_example.py

9.3 如何只运行失败的测试?

# 第一次运行,记录失败的测试
pytest --lf  # --last-failed

# 只运行上次失败的测试
pytest --lf

9.4 如何跳过某些测试?

使用 @pytest.mark.skip 装饰器:

@pytest.mark.skip(reason="暂时跳过")
def test_example():
    assert True

9.5 参数在配置文件中如何设置?

pytest.ini 中使用 addopts

[pytest]
addopts = -v -s

发表评论