Python进阶教程:单元测试与代码质量

目录

Python进阶教程:单元测试与代码质量

本文是 Python 入门教程系列 的第 14 篇(扩展篇)。上一篇讲解了装饰器与生成器,本篇介绍如何用单元测试保障代码质量。

一、为什么需要测试

随着代码规模增长,手动验证越来越不可靠。自动化测试能:

  • 快速回归:改动代码后立即发现是否破坏原有功能
  • 驱动设计:写测试时倒逼代码结构清晰
  • 保障重构:放心地优化代码而不怕改坏

二、unittest 基础

unittest 是 Python 内置测试框架:

python 复制代码
import unittest

def add(a, b):
    return a + b

def divide(a, b):
    if b == 0:
        raise ValueError("除数不能为零")
    return a / b

class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(1, 2), 3)
        self.assertEqual(add(-1, 1), 0)

    def test_divide(self):
        self.assertEqual(divide(10, 2), 5)
        with self.assertRaises(ValueError):
            divide(10, 0)

if __name__ == "__main__":
    unittest.main()

运行:python -m unittest test_math.py

三、setUp 与 tearDown

python 复制代码
import unittest

class TestDatabase(unittest.TestCase):
    def setUp(self):
        """每个测试前执行"""
        self.data = {"name": "Alice", "age": 20}

    def tearDown(self):
        """每个测试后执行"""
        self.data.clear()

    def test_data(self):
        self.assertEqual(self.data["name"], "Alice")

    @classmethod
    def setUpClass(cls):
        """整个测试类执行前运行一次"""
        print("开始测试")

    @classmethod
    def tearDownClass(cls):
        """整个测试类执行后运行一次"""
        print("测试结束")

四、pytest:更简洁的框架

pytest 语法更简洁,是社区主流(pip install pytest):

python 复制代码
# test_calculator.py
import pytest

def add(a, b):
    return a + b

def test_add_positive():
    assert add(1, 2) == 3

def test_add_negative():
    assert add(-1, -2) == -3

# 参数化测试
@pytest.mark.parametrize("a,b,expected", [
    (1, 2, 3),
    (0, 0, 0),
    (-5, 5, 0),
])
def test_add_param(a, b, expected):
    assert add(a, b) == expected

# 异常断言
def test_add_raises():
    with pytest.raises(TypeError):
        add("1", 2)

运行:pytest test_calculator.py -v

五、Mock:模拟外部依赖

测试中经常需要模拟网络、数据库等外部依赖:

python 复制代码
from unittest.mock import Mock, patch

def get_user_data(api):
    """从 API 获取用户数据(依赖外部服务)"""
    resp = api.get("/users/1")
    return resp.json()["name"]

def test_get_user_data():
    # 创建一个 Mock API
    mock_api = Mock()
    mock_api.get.return_value.json.return_value = {"name": "Alice"}

    result = get_user_data(mock_api)
    assert result == "Alice"
    mock_api.get.assert_called_with("/users/1")

六、代码质量工具

6.1 代码风格检查

bash 复制代码
# 安装
pip install flake8 black mypy

# 检查代码风格
flake8 my_module.py

# 自动格式化
black my_module.py

# 类型检查
mypy my_module.py

6.2 覆盖率统计

bash 复制代码
# 安装
pip install coverage

# 统计测试覆盖率
coverage run -m pytest
coverage report  # 查看报告
coverage html    # 生成 HTML 报告

七、实战:为工具类编写测试

python 复制代码
# calculator.py
class Calculator:
    def add(self, a, b):
        return a + b

    def subtract(self, a, b):
        return a - b

    def multiply(self, a, b):
        return a * b

    def divide(self, a, b):
        if b == 0:
            raise ValueError("不能除以零")
        return a / b
python 复制代码
# test_calculator.py
import pytest
from calculator import Calculator

@pytest.fixture
def calc():
    """测试夹具:为每个测试提供实例"""
    return Calculator()

def test_add(calc):
    assert calc.add(2, 3) == 5

def test_subtract(calc):
    assert calc.subtract(10, 4) == 6

def test_divide(calc):
    assert calc.divide(8, 2) == 4

def test_divide_by_zero(calc):
    with pytest.raises(ValueError):
        calc.divide(1, 0)

总结

本篇介绍了 unittest 与 pytest 两大测试框架、Mock 模拟外部依赖、以及 flake8/black/mypy/coverage 等代码质量工具,并为计算器类编写了完整测试。养成写测试的习惯,是成为专业开发者的重要一步。

相关推荐
§ꦿCFོ༉5 小时前
嵌入式八股文—C语言入门学习(四)
c语言·开发语言·学习
投图匠5 小时前
十种不同风格的 CTP接口 框架
开发语言·python
2601_967980117 小时前
深入理解词向量算法及其在Python中的实践
python·word2vec·glove·fasttext·词向量
129Lab7 小时前
电池循环测试数据自动化分析:用Python+AI工具构建一键式寿命评估流水线
python·数据分析·电池测试·数据自动化·寿命评估
treasure1407 小时前
【复古】浅尝Django前后端不分离
前端·css·python·django·bootstrap·html·web
Dmz丶8 小时前
前端转 AI 100 天 Day 44:前端集成实战——用 React 给 Agent 做个正式界面
python
jay神8 小时前
基于 YOLOv8 的手势识别系统(Web 版)
前端·人工智能·python·深度学习·yolo·计算机视觉·计算机毕业设计
DeepVisionary8 小时前
阿里云上线旗舰多模态新模型,不公布跑分且限时14天退役
python·自动化
东莞市云毅网络有限公司8 小时前
FAQ 覆盖度打分:TF-IDF 与向量嵌入双路召回的 Python 实现
python·数据清洗·rag·企业知识库·文档解析
爱笑的k119 小时前
nano-vllm 源码剖析:千行 Python 手写离线推理引擎的调度、显存与并行时序
开发语言·python·vllm