第4章 结构化编码和测试
4.5 单元测试完整讲解(概述+详解+实操实例)
一、一句话概述
单元测试:是开发人员在编码阶段,对程序里最小的代码单元(函数、方法、小类),单独、隔离写测试代码,验证它逻辑是否正确的一种白盒测试。只测一小块代码,不依赖数据库、不依赖接口、不依赖页面,自己单独跑。
二、详细讲解
1. 什么是「单元」
程序拆分后的最小可独立测试模块:
- 最常见:一个函数、一个方法
- 其次:一个独立工具类、一个私有逻辑模块
- ❌ 不是整个项目、不是整个页面、不是整个接口
2. 单元测试核心本质
- 执行者:开发自己写,不是测试人员
- 执行时机:写完一个函数就立刻测,不是等项目开发完
- 测试方式:写代码测代码,自动运行,不用手动点页面
- 核心原则:隔离 测这个函数时,屏蔽掉它依赖的数据库、其他接口、外部服务,只单纯测自身逻辑。
3. 单元测试主要测什么
- 正常输入:给合法参数,看返回值对不对
- 边界值:最大值、最小值、0、空值
- 异常输入:非法参数、负数、空字符串
- 逻辑分支:if/else、for循环各分支是否都走得通
- 异常抛出:报错场景会不会正常抛异常
4. 单元测试 和 集成/系统测试 区别
| 测试类型 | 测试粒度 | 阶段 | 测什么 |
|---|---|---|---|
| 单元测试 | 最小:函数/方法 | 编码阶段 | 单个代码逻辑 |
| 集成测试 | 模块之间 | 模块写完后 | 模块和模块调用是否正常 |
| 系统测试 | 整个项目 | 全部开发完 | 整体功能、业务流程 |
5. 为什么要做单元测试
- 提前找Bug:写代码时就发现逻辑错误,后期改成本极低
- 改代码不翻车:后期重构代码,跑一遍单元测试,没问题就不会改坏老逻辑(回归测试)
- 调试简单:锁定就这一个函数错,不用全局排查
- 充当文档:测试用例本身就是函数的使用示例
三、实操实例(极简易懂,Python 自带单元测试框架)
场景
写一个计算两数相加、还要判断负数的工具函数,然后给它写单元测试。
步骤1:写业务功能代码
python
# 工具函数:两数相加,若有负数直接抛出异常
def add(a, b):
if a < 0 or b < 0:
raise ValueError("不能传入负数")
return a + b步骤2:写单元测试代码
用 Python 内置 unittest,不用装任何插件:
python
import unittest
# 测试类,固定写法继承 unittest.TestCase
class TestAddFunc(unittest.TestCase):
# 测试用例1:正常正数相加
def test_add_normal(self):
self.assertEqual(add(3, 5), 8)
# 测试用例2:边界值 0
def test_add_zero(self):
self.assertEqual(add(0, 6), 6)
# 测试用例3:传入负数,是否会正确抛异常
def test_add_negative(self):
with self.assertRaises(ValueError):
add(-2, 5)
# 运行测试
if __name__ == '__main__':
unittest.main()步骤3:运行结果
- 三个用例全部通过 → 说明函数逻辑完全正确
- 如果故意把
return a+b改成return a-b,再运行: 直接报错,立刻发现函数逻辑错误。
四、总结
单元测试 = 开发自测最小函数,隔离环境、代码测代码,提前抓Bug、改代码不翻车。 Java 里是 JUnit、Go 自带 testing、Vue前端 是 Jest,原理全都一模一样。