写过Python代码的小伙伴们都知道,测试代码是保证代码质量的重要手段。pytest作为Python世界最受欢迎的测试框架,它简单易用又功能强大,确实香得不得了。
安装和基本使用
安装pytest超级简单,一行命令就搞定:
pip install pytest
写个最基础的测试用例试试水:
# test_sample.py
def add(a, b):
return a + b
def test_add():
assert add(1, 2) == 3
assert add(-1, 1) == 0
运行测试只需要在命令行输入pytest,它会自动找到所有以test_开头的文件和函数。贼方便!
小贴士:
测试文件名要以test_开头
测试函数也要以test_开头
assert语句失败时,pytest会显示详细的错误信息
测试夹具(fixture)
fixture是pytest的杀手锏,可以帮我们准备测试数据、处理资源清理等琐事:
import pytest
@pytest.fixture
def db_connection():
print(“连接数据库”)
# 这里假设建立了数据库连接
db = {“connected”:True}
yield db
print(“关闭数据库连接”)
# 这里做清理工作
def test_database(db_connection):
assert db_connection[“connected”] == True
瞧,用yield把前置和后置操作分开,代码结构多清晰。fixture还能设定作用域,比如session级别只执行一次,function级别每个测试函数都执行。
参数化测试
测试不同的输入输出太麻烦?参数化测试来帮忙:
import pytest
def is_palindrome(s):
return s == s[::-1]
(“level”, True),
(“python”, False),
(“”, True),
(“88”, True)
])
def test_is_palindrome(test_input, expected):
assert is_palindrome(test_input) == expected
一个测试函数搞定多组测试用例,代码量立马少了一大截。
小贴士:
参数名要和装饰器里的参数对应
可以测试边界情况和特殊输入
数据量大的话可以放到外部文件里
mock和打桩
真实环境调用外部API费时费力?mock来模拟:
from unittest.mock import patch
def get_user_data(user_id):
# 假设这是个调用外部API的函数
pass
def test_get_user():
with patch('__main__.get_user_data') as mock_get:
mock_get.return_value = {“name”:“猫哥”, “age”:18}
result = get_user_data(1)
assert result[“name”] == “猫哥”
mock_get.assert_called_once_with(1)
mock对象可以设置返回值、记录调用次数、检查调用参数,爽得很!
小贴士:
记得import正确的mock路径
别忘了验证mock是否被正确调用
模拟异常可以用side_effect
测试报告和覆盖率
想看看测试覆盖了多少代码?装个pytest-cov插件:
pip install pytest-cov
pytest --cov=myproject tests/
还能生成漂亮的HTML报告:
pytest --cov=myproject --cov-report=html tests/
代码覆盖率高不代表测试质量好,但低覆盖率一定说明测试不够充分。我建议核心业务代码的覆盖率要保持在80%以上。
写测试代码也是一门学问,pytest的这些功能用好了,能让测试代码变得优雅又好维护。手里有一套靠谱的测试,写代码的时候底气也足了不少。
领取专属 10元无门槛券
私享最新 技术干货