Python脚本单元测试Unittest还是Pytest

wen 实用脚本 1

本文目录导读:

Python脚本单元测试Unittest还是Pytest

  1. 核心对比
  2. 代码对比
  3. 选择建议
  4. 最佳实践
  5. 实际案例

对于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。

抱歉,评论功能暂时关闭!