Python 测试代码快速入门(10分钟)

以下教程将引导你快速学习 Python 测试,掌握基础工具和技术,以覆盖 80% 的常见场景。


1. 基础测试示例:简单函数

编写测试的目的是验证函数在各种输入情况下的正确性。

# 功能函数:实现两个数的加法
def add(x, y):
    """
    简单的加法函数
    :param x: 加数1
    :param y: 加数2
    :return: 两数相加的结果
    """
    return x + y

# 测试函数:验证 add 函数的正确性
def test_add():
    """
    测试 add 函数,覆盖常见场景
    """
    # 正常情况下
    assert add(2, 3) == 5  # 2+3 应该等于 5
    # 边界值情况
    assert add(-1, 1) == 0  # -1+1 应该等于 0
    # 特殊值情况
    assert add(0, 0) == 0  # 0+0 应该等于 0
运行测试

在命令行中运行:

pytest test_example.py

输出说明:

  • . 表示通过的测试
  • F 表示失败的测试

2. 参数化测试:减少重复代码

参数化测试可以一次性覆盖多个测试用例。

import pytest

# 功能函数:实现加法
def add(x, y):
    return x + y

# 测试函数:使用参数化装饰器简化多案例测试
@pytest.mark.parametrize("x, y, expected", [
    (2, 3, 5),   # 正常值
    (-1, 1, 0),  # 边界值
    (0, 0, 0),   # 特殊值
    (100, 200, 300),  # 较大值
])
def test_add(x, y, expected):
    """
    测试加法函数,覆盖多种输入情况
    """
    assert add(x, y) == expected

优点:

  • 避免重复编写 assert
  • 新增测试用例只需添加参数。

3. 测试异常:验证错误处理逻辑

异常测试用来确保代码在错误输入时能正确抛出错误。

# 功能函数:实现除法,并处理除零情况
def divide(x, y):
    """
    简单除法函数,处理除以零的特殊情况
    :param x: 被除数
    :param y: 除数
    :return: 商
    :raises ValueError: 如果 y 为 0
    """
    if y == 0:
        raise ValueError("Cannot divide by zero")  # 抛出异常
    return x / y

# 测试函数:验证 divide 的错误处理逻辑
def test_divide():
    """
    测试 divide 函数,确保异常正确抛出
    """
    # 正常情况
    assert divide(10, 2) == 5  # 10/2 应该等于 5
    # 测试异常:除以零
    with pytest.raises(ValueError, match="Cannot divide by zero"):
        divide(1, 0)  # 应该抛出 ValueError

关键点:

  • 使用 pytest.raises 检查异常是否抛出。
  • match 参数验证异常信息是否正确。

4. 测试类和方法

面向对象代码中,你需要测试类的初始化和方法行为。

# 功能类:实现简单的计算器
class Calculator:
    """
    一个简单的计算器类,用于累积计算
    """
    def __init__(self):
        self.result = 0  # 初始化结果为 0

    def add(self, value):
        """
        将 value 加到当前结果中
        :param value: 要添加的值
        """
        self.result += value

    def subtract(self, value):
        """
        从当前结果中减去 value
        :param value: 要减去的值
        """
        self.result -= value

# 测试类:验证 Calculator 的行为
def test_calculator():
    """
    测试 Calculator 类的功能
    """
    calc = Calculator()  # 初始化计算器
    calc.add(10)  # 加 10
    assert calc.result == 10  # 当前结果应该为 10
    calc.subtract(5)  # 减去 5
    assert calc.result == 5  # 当前结果应该为 5

5. 使用 Fixtures:复用测试准备代码

pytest 提供 fixture 来简化测试中重复的准备工作。

import pytest

# 功能函数:简单用户数据验证
def validate_user(user):
    """
    验证用户数据是否完整
    :param user: 字典类型,包含用户数据
    :return: 是否有效
    """
    return "name" in user and "email" in user

# Fixture:提供测试数据
@pytest.fixture
def user_data():
    """
    返回测试用的用户数据
    """
    return {"name": "Alice", "email": "alice@example.com"}

# 测试函数:使用 fixture 提供的数据
def test_validate_user(user_data):
    """
    测试 validate_user 函数
    """
    assert validate_user(user_data)  # 数据应通过验证
    # 修改数据,验证失败情况
    user_data.pop("email")
    assert not validate_user(user_data)  # 数据不应通过验证

优点:

  • 提供共享数据,减少重复代码。
  • 提高代码可读性和可维护性。

6. Mock 测试:模拟外部依赖

通过 unittest.mock 模块模拟外部依赖的行为。

from unittest.mock import MagicMock

# 功能函数:从 API 获取数据
def get_data_from_api(api_client):
    """
    从 API 客户端获取数据
    :param api_client: API 客户端对象
    :return: 获取的数据
    """
    return api_client.fetch_data()

# 测试函数:模拟 API 行为
def test_get_data_from_api():
    """
    测试 get_data_from_api 函数
    """
    # 模拟 API 客户端
    mock_client = MagicMock()
    mock_client.fetch_data.return_value = {"data": "mocked data"}  # 模拟返回值
    
    # 调用函数,验证返回结果
    result = get_data_from_api(mock_client)
    assert result == {"data": "mocked data"}  # 应该返回模拟数据
    # 验证 fetch_data 是否被正确调用
    mock_client.fetch_data.assert_called_once()

7. 覆盖报告

测试代码完成后,建议生成代码覆盖率报告:

  1. 安装工具:

    pip install pytest-cov
    
  2. 运行测试并生成覆盖率报告:

    pytest --cov=your_module test_example.py
    
  3. 生成 HTML 报告:

    pytest --cov=your_module --cov-report=html
    
  4. 查看 HTML 报告:

    打开生成的 htmlcov/index.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值