现在位置: 首页 > Pycharm 教程 > 正文

PyCharm 单元测试

单元测试是保证代码质量的基础手段,它验证程序中最小可测试单元的行为是否符合预期。

在 PyCharm 中编写和运行单元测试非常便捷,IDE 提供了从测试创建到执行再到结果分析的完整工作流。

PyCharm 内置支持三种主流 Python 测试框架:unittestpytestnose


编写测试示例

下面通过一个完整的示例演示如何在 PyCharm 中编写单元测试。

我们首先创建一个简单的 Car 类,然后为其编写测试用例。

被测代码:car.py

实例

# car.py - 一个简单的 Car 类,用于演示单元测试的编写
class Car:
    """模拟汽车类,提供加速和刹车功能"""

    def __init__(self, make="runoob", model="RUNOOB-X1"):
        # 初始化汽车品牌和型号
        self.make = make
        self.model = model
        # 初始速度为 0
        self.speed = 0

    def accelerate(self, increment):
        """加速方法
        参数:
            increment: 速度增量,必须为正整数
        返回:
            加速后的当前速度
        异常:
            ValueError: 当 increment 为负数或零时抛出
        """

        if increment <= 0:
            raise ValueError("加速增量必须为正数")
        self.speed += increment
        return self.speed

    def brake(self, decrement):
        """刹车方法
        参数:
            decrement: 减速量,必须为正整数
        返回:
            刹车后的当前速度,最低为 0
        异常:
            ValueError: 当 decrement 为负数或零时抛出
        """

        if decrement <= 0:
            raise ValueError("减速量必须为正数")
        self.speed = max(0, self.speed - decrement)
        return self.speed

测试代码:test_car.py

实例

# test_car.py - Car 类的单元测试
# 使用 unittest 框架编写测试用例
import unittest
from car import Car


class TestCar(unittest.TestCase):
    """Car 类的测试套件"""

    def setUp(self):
        """每个测试方法执行前都会调用 setUp,创建全新的 Car 实例"""
        self.car = Car()

    def test_initial_speed(self):
        """测试初始速度是否为 0"""
        self.assertEqual(self.car.speed, 0,
                         "新车初始速度应该为 0")

    def test_accelerate_normal(self):
        """测试正常加速场景"""
        # 加速 50
        result = self.car.accelerate(50)
        # 验证返回值
        self.assertEqual(result, 50,
                         "加速后速度应该为 50")
        # 验证对象状态
        self.assertEqual(self.car.speed, 50,
                         "car.speed 属性应该更新为 50")

    def test_accelerate_multiple_times(self):
        """测试多次加速的累计效果"""
        # 第一次加速 30
        self.car.accelerate(30)
        # 第二次加速 20
        result = self.car.accelerate(20)
        # 总速度应为 50
        self.assertEqual(result, 50,
                         "两次加速后速度应该为 50")

    def test_accelerate_with_zero(self):
        """测试加速增量为 0 时应抛出异常"""
        with self.assertRaises(ValueError,
                               msg="加速增量为 0 应抛出 ValueError"):
            self.car.accelerate(0)

    def test_accelerate_negative(self):
        """测试加速增量为负数时应抛出异常"""
        with self.assertRaises(ValueError,
                               msg="加速增量为负数应抛出 ValueError"):
            self.car.accelerate(-10)

    def test_brake_normal(self):
        """测试正常刹车场景"""
        # 先加速到 80
        self.car.accelerate(80)
        # 刹车 30
        result = self.car.brake(30)
        # 验证速度
        self.assertEqual(result, 50,
                         "刹车后速度应该为 50")

    def test_brake_below_zero(self):
        """测试刹车不会让速度低于 0"""
        # 先加速到 20
        self.car.accelerate(20)
        # 刹车 50,速度应该被限制在 0
        result = self.car.brake(50)
        self.assertEqual(result, 0,
                         "速度不应低于 0")

    def test_brake_with_zero(self):
        """测试减速量为 0 时应抛出异常"""
        with self.assertRaises(ValueError,
                               msg="减速量为 0 应抛出 ValueError"):
            self.car.brake(0)


# 当脚本直接运行时执行测试
if __name__ == "__main__":
    unittest.main()

PyCharm 可以自动识别测试类和测试方法,测试类名以 Test 开头,测试方法名以 test_ 开头是 Python 测试的命名约定。


运行测试

编写好测试代码后,有多种方式可以运行测试。

方式一:点击绿色运行图标

PyCharm 会在测试类和每个测试方法的左侧 Gutter 区域显示绿色运行图标

点击类名旁的绿色图标可以运行该类的所有测试,点击方法旁的图标只运行单个测试。

也可以右键点击测试文件,在菜单中选择 Run 'test_car'

方式二:使用快捷键

将光标放在测试类或测试方法内部,按下 Ctrl + Shift + F10 即可运行当前测试。

查看测试结果

测试运行完成后,PyCharm 会在底部的 Run 工具窗口中树状显示测试结果。

通过的测试以绿色对勾标记,失败的测试以红色叉号标记,并附带详细的错误信息和堆栈跟踪。

点击失败的测试项,PyCharm 会直接跳转到出错的代码行,方便快速定位问题。


切换测试框架

PyCharm 默认使用 unittest 作为测试运行器,但你可以轻松切换到其他框架。

配置步骤

  1. 打开 设置(快捷键 Ctrl + Alt + S,macOS 为 Command + ,)。
  2. 导航到 Python
  3. 集成工具 区域找到 测试 下拉菜单。
  4. UnittestspytestNosetests 中选择你需要的框架。
  5. 点击 确认 保存设置。

如果选择 pytest 作为测试运行器,请确保已通过 pip install pytest 安装了 pytest 包。


测试驱动开发建议

单元测试不仅仅用于验证已有代码,更是测试驱动开发(TDD)的核心实践。

推荐的开发流程是先编写测试用例,再编写实现代码,最后通过测试验证。

养成编写测试的习惯,你的代码质量将得到显著提升。