pytest
是一个非常流行的 Python 测试框架,它具有强大的自动用例发现 功能。理解其用例发现规则和编写用例的要求,是高效使用 pytest
的基础。
一、用例发现规则 (Test Discovery Rules)
pytest
在命令行执行时(如 pytest
或 pytest tests/
),会递归地搜索指定目录(默认是当前目录)下的文件和函数,自动发现哪些是测试用例。其发现规则如下:
1. 搜索目录
pytest
会从你指定的路径(或当前目录)开始,递归地搜索所有子目录,除了venv虚拟环境目录和以'.'开头的目录(表示隐藏)。
2. 匹配文件名
pytest
会查找文件名 符合test_*.py
和*_test.py
的 .py
文件:
注意 :
conftest.py
文件是一个特例,它不会被当作测试文件执行,但其中可以定义fixture
等共享配置。
3. 匹配类名(可选)
在匹配的测试文件中,pytest
会查找类名 以 Test
开头的类- - 例如:TestClass
, TestUser
, TestAPI
不包括:
markdown
- `Test` 类本身不会被实例化测试。
- 以小写 `test` 开头的类(如 `test_user`)不会被发现。
- 包含 `__init__` 方法的类通常不会被发现(除非使用 `@pytest.mark.usefixtures` 等特殊方式)。
4. 匹配函数名和方法名
在测试文件或 Test
类中,pytest
会查找以 test_
开头的函数或方法-- 例如:test_login()
, test_user_creation()
不包括
markdown
- `test` 函数本身不会被发现。
- `_test()`(以下划线开头)不会被发现。
- `test()`(单个test)不会被发现。
二、编写测试用例的要求
为了让 pytest
正确发现并执行测试,需要遵循:
1. 文件命名要求
- 测试文件必须命名为
test_*.py
或*_test.py
。 - 推荐 :使用
test_
前缀,这是最常见和推荐的约定。
2. 函数/方法命名要求
- 独立的测试函数必须以
test_
开头。 - 类中的测试方法也必须以
test_
开头。 - 不要 在测试函数中使用
assert
以外的断言方式(如self.assertEqual
),虽然unittest
风格也支持,但pytest
推荐直接使用 Python 的assert
。
3. 测试类的要求
- 如果使用类来组织测试,类名必须以
Test
开头。 - 类中不要 定义
__init__
构造方法(除非你知道自己在做什么)。 - 每个测试方法都是独立的,
pytest
会为每个测试方法创建一个新的类实例。
4. 使用 assert
进行断言
-
pytest
对 Python 原生的assert
语句进行了增强,提供了详细的失败信息(如变量值、表达式分解)。 -
推荐写法:
java
def test_addition():
assert 1 + 1 == 2
assert [1, 2, 3] == [1, 2, 3]
assert "hello" in "hello world"
5. 避免 print
,使用 capsys
或日志
-
虽然可以在测试中使用
print()
,但pytest
会捕获输出。 -
如果需要测试
print
输出,可以使用capsys
fixture:
python
def test_print(capsys):
print("hello")
captured = capsys.readouterr()
assert "hello" in captured.out
6. 使用 pytest.raises
断言异常
- 测试函数是否抛出预期异常:
python
import pytest
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
1 / 0
7. 使用 @pytest.mark
标记用例(可选)
- 可以为用例添加标记,便于分类和选择性执行:
python
import pytest
@pytest.mark.smoke
def test_login():
...
@pytest.mark.skip(reason="Not implemented yet")
def test_logout():
...
总结
项目 | 要求 |
---|---|
文件名 | test_*.py 或 *_test.py |
类名 | 以 Test 开头(且无 __init__ ) |
函数/方法名 | 以 test_ 开头 |
断言 | 使用 assert 语句 |
异常断言 | 使用 with pytest.raises(...): |
遵循这些规则和要求,pytest
就能自动发现并运行你的测试用例。