后端

pytest基础使用教程:安装、用例编写与运行实战

TRAE AI 编程助手

pytest基础使用教程:安装、用例编写与运行实战

引言

pytest 是 Python 生态中最流行的测试框架之一,以其简洁的语法、强大的断言机制和丰富的插件生态而闻名。相比 Python 标准库中的 unittest,pytest 提供了更加灵活和高效的测试体验,成为了很多 Python 项目的首选测试工具。

本文将详细介绍 pytest 的基础使用方法,包括安装配置、测试用例编写和运行实战,帮助你快速上手 pytest 测试框架。

一、pytest 安装与验证

1.1 安装方式

使用 pip 安装(推荐)

# 安装最新稳定版
pip install pytest
 
# 安装指定版本
pip install pytest==7.4.3
 
# 安装开发版
pip install -U git+https://github.com/pytest-dev/pytest.git

使用 conda 安装

conda install -c conda-forge pytest

安装完成后验证

pytest --version

如果安装成功,将输出类似以下信息:

pytest 7.4.3

二、pytest 测试用例编写规则

pytest 采用了约定优于配置的设计理念,只要遵循以下简单规则,测试用例就能被自动发现:

  1. 测试文件:以 test_ 开头或 _test.py 结尾(如 test_calculator.pycalculator_test.py
  2. 测试类:以 Test 开头,并且不能包含 __init__ 方法
  3. 测试函数/方法:以 test_ 开头

2.1 基本测试用例示例

示例 1:测试简单函数

# test_calculator.py
 
def add(x, y):
    return x + y
 
def test_add():
    assert add(1, 2) == 3
    assert add(0, 0) == 0
    assert add(-1, 1) == 0

示例 2:测试类和方法

# test_user.py
 
class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age
 
    def is_adult(self):
        return self.age >= 18
 
class TestUser:
    def test_is_adult(self):
        adult_user = User("Alice", 20)
        assert adult_user.is_adult() == True
 
        minor_user = User("Bob", 17)
        assert minor_user.is_adult() == False

2.2 断言使用技巧

pytest 支持 Python 标准的 assert 语句,并会在断言失败时提供详细的错误信息。

断言相等/不相等

assert 1 + 2 == 3
assert "hello" != "world"

断言包含/不包含

assert "a" in "apple"
assert "x" not in "apple"

断言类型

assert isinstance(123, int)
assert isinstance("hello", str)

断言异常

def divide(x, y):
    if y == 0:
        raise ZeroDivisionError("除数不能为0")
    return x / y
 
def test_divide_zero():
    # 断言会抛出 ZeroDivisionError 异常
    with pytest.raises(ZeroDivisionError) as excinfo:
        divide(1, 0)
    # 可以进一步断言异常信息
    assert "除数不能为0" in str(excinfo.value)

三、pytest 测试用例运行

3.1 基本运行方式

运行当前目录下的所有测试

pytest

运行指定测试文件

pytest test_calculator.py

运行指定测试函数

pytest test_calculator.py::test_add

运行指定测试类中的方法

pytest test_user.py::TestUser::test_is_adult

3.2 常用命令行参数

参数说明
-v详细输出测试结果
-x遇到第一个错误或失败就停止运行
-k按关键词筛选测试用例
-m运行标记了特定标记的测试用例
--tb=short简化错误信息输出
-q安静模式,只输出汇总信息

示例:使用 -v 详细输出

pytest -v test_calculator.py

示例:使用 -k 筛选测试用例

# 运行包含 "add" 或 "multiply" 的测试用例
pytest -k "add or multiply" test_calculator.py

示例:使用 -m 运行标记测试

# 标记测试用例
import pytest
 
@pytest.mark.slow
def test_long_running():
    # 长时间运行的测试
    pass
 
@pytest.mark.fast
def test_short_running():
    # 短时间运行的测试
    pass
# 只运行标记为 fast 的测试
pytest -m fast

四、实战:完整测试项目

4.1 项目结构

my_project/
├── src/
│   └── calculator.py
└── tests/
    └── test_calculator.py

4.2 实现代码

# src/calculator.py
 
class Calculator:
    def add(self, x, y):
        """加法运算"""
        return x + y
 
    def subtract(self, x, y):
        """减法运算"""
        return x - y
 
    def multiply(self, x, y):
        """乘法运算"""
        return x * y
 
    def divide(self, x, y):
        """除法运算"""
        if y == 0:
            raise ValueError("除数不能为0")
        return x / y

4.3 测试用例

# tests/test_calculator.py
 
import pytest
from src.calculator import Calculator
 
class TestCalculator:
    def setup_method(self):
        """每个测试方法执行前都会调用"""
        self.calc = Calculator()
        print("\nsetup_method: 创建 Calculator 实例")
 
    def teardown_method(self):
        """每个测试方法执行后都会调用"""
        print("teardown_method: 清理资源")
 
    def test_add(self):
        """测试加法运算"""
        assert self.calc.add(1, 2) == 3
        assert self.calc.add(-1, 1) == 0
        assert self.calc.add(0, 0) == 0
 
    def test_subtract(self):
        """测试减法运算"""
        assert self.calc.subtract(5, 3) == 2
        assert self.calc.subtract(3, 5) == -2
        assert self.calc.subtract(0, 0) == 0
 
    def test_multiply(self):
        """测试乘法运算"""
        assert self.calc.multiply(2, 3) == 6
        assert self.calc.multiply(-2, 3) == -6
        assert self.calc.multiply(0, 100) == 0
 
    def test_divide(self):
        """测试除法运算"""
        assert self.calc.divide(6, 3) == 2
        assert self.calc.divide(5, 2) == 2.5
 
    def test_divide_by_zero(self):
        """测试除以零的异常情况"""
        with pytest.raises(ValueError) as excinfo:
            self.calc.divide(10, 0)
        assert "除数不能为0" in str(excinfo.value)

4.4 运行测试

# 在项目根目录下运行
pytest -v tests/

五、总结

本文介绍了 pytest 的基础使用方法,包括安装配置、测试用例编写规则、运行测试用例的各种方式以及一个完整的实战项目。pytest 以其简洁的语法和强大的功能,成为 Python 测试领域的事实标准。

要深入学习 pytest,可以探索其丰富的插件生态,比如:

  • pytest-cov:代码覆盖率统计
  • pytest-xdist:并行执行测试
  • pytest-html:生成 HTML 测试报告
  • pytest-mock:模拟测试

通过不断实践和探索,你将能够充分发挥 pytest 的优势,编写出高效、可靠的测试用例,提高项目的代码质量。

(此内容由 AI 辅助生成,仅供参考)