本文目录导读:

对于Python单元测试,强烈推荐使用pytest,除非有特殊限制(如公司强制使用unittest),以下是详细对比:
核心对比
| 特性 | unittest | pytest |
|---|---|---|
| 复杂度 | 需要类和方法,模板化代码多 | 函数式,简洁直观 |
| 断言 | self.assertEqual() 等 |
原生 assert |
| Fixture | setUp/tearDown,继承 | 模块级、函数级,灵活作用域 |
| 参数化 | 需要subTest或第三方库 | 内置 @pytest.mark.parametrize |
| 插件生态 | 有限 | 丰富(覆盖、mock、并发等) |
| 自动发现 | 需特定命名规则 | 更智能的自动发现 |
| 报告输出 | 基础 | 更详细、美观,含失败原因 |
代码对比
unittest 示例
import unittest
class TestCalculator(unittest.TestCase):
def setUp(self):
self.calc = Calculator()
def test_add(self):
result = self.calc.add(2, 3)
self.assertEqual(result, 5)
def test_divide_by_zero(self):
with self.assertRaises(ValueError):
self.calc.divide(1, 0)
pytest 示例
import pytest
class TestCalculator:
def setup_method(self):
self.calc = Calculator()
def test_add(self):
result = self.calc.add(2, 3)
assert result == 5 # 直接使用assert
def test_divide_by_zero(self):
with pytest.raises(ValueError):
self.calc.divide(1, 0)
# 参数化测试
@pytest.mark.parametrize("a,b,expected", [
(1, 2, 3),
(0, 0, 0),
(-1, 1, 0)
])
def test_add_param(self, a, b, expected):
assert self.calc.add(a, b) == expected
选择建议
选择 pytest 的情况:
- ✅ 新项目启动
- ✅ 需要简洁代码
- ✅ 需要参数化测试
- ✅ 需要并发测试 (pytest-xdist)
- ✅ 需要详细HTML报告
- ✅ 需要mock复杂场景
选择 unittest 的情况:
- ✅ 公司/项目标准强制要求
- ✅ 需要兼容Python 2.x(极少)
- ✅ 不想添加第三方依赖
- ✅ 团队习惯保持统一
最佳实践
建议使用pytest + 插件组合:
pip install pytest pytest-cov pytest-mock pytest-xdist pytest-html
示例配置(pytest.ini):
[pytest] testpaths = tests python_files = test_*.py python_classes = Test* python_functions = test_* addopts = -v --cov=src --html=report.html
实际案例
# 使用pytest的fixture管理资源
@pytest.fixture
def database():
db = Database()
db.connect()
yield db
db.close()
def test_query(database):
result = database.query("SELECT * FROM users")
assert len(result) > 0
# 使用mock
def test_api_call(mocker):
mock_response = {"status": "success"}
mocker.patch('requests.get', return_value=MockResponse(mock_response))
assert call_api() == mock_response
pytest是更现代、更强大的选择,能让测试代码更简洁,维护成本更低,除非有特殊约束,否则直接使用pytest。