共计 1893 个字符,预计需要花费 5 分钟才能阅读完成。
在软件开发中,保证代码的正确性和稳定性是非常重要的。随着程序规模的增大,手动测试不仅耗时,而且容易遗漏。Python 提供了 unittest 模块,可以帮助我们编写自动化测试用例,对函数和类进行验证,从而提升代码质量。
- 什么是单元测试
单元测试是对软件中的最小可测试单元(如函数、方法或类)进行验证的过程。通过单元测试,可以确保每个单元在各种输入情况下都能返回预期的结果。
例如,我们写了一个计算阶乘的函数,就可以通过单元测试来验证它在输入 0、1、5、负数 等情况下是否能给出正确结果。
- 编写第一个测试用例
unittest是 Python 自带的单元测试框架,基本使用方法如下:
import unittest
# 被测试的函数
def add(a, b):
return a + b
# 定义测试类
class TestMathFunctions(unittest.TestCase):
def test_add_integers(self):
self.assertEqual(add(2, 3), 5)
def test_add_strings(self):
self.assertEqual(add("Hello ", "World"), "Hello World")
def test_add_lists(self):
self.assertEqual(add([1, 2], [3, 4]), [1, 2, 3, 4])
if __name__ == '__main__':
unittest.main()
运行后会显示测试结果,如果所有断言都通过,就会显示 OK,否则会显示错误信息。
- 常用的断言方法
unittest.TestCase提供了丰富的断言方法,用于验证代码的运行结果:
assertEqual(a, b):断言 a == bassertNotEqual(a, b):断言 a != bassertTrue(x):断言 x 为 TrueassertFalse(x):断言 x 为 FalseassertIs(a, b):断言 a is bassertIsNone(x):断言 x is NoneassertIn(a, b):断言 a 在 b 中assertRaises(Exception, func, *args):断言函数会抛出指定异常
例如:
def divide(a, b):
return a / b
class TestDivide(unittest.TestCase):
def test_divide_normal(self):
self.assertEqual(divide(10, 2), 5)
def test_divide_zero(self):
with self.assertRaises(ZeroDivisionError):
divide(10, 0)
这样可以确保我们的 divide() 函数在除数为 0 时能够抛出 ZeroDivisionError。
- 组织测试用例
随着项目复杂度增加,可以将测试代码放在单独的tests文件夹下,并使用以下结构:
project/
│── app.py
│── tests/
│── test_app.py
然后在 test_app.py 中导入 app 里的函数或类进行测试。
- 设置测试的前置与后置操作
有时在执行测试前需要准备数据,执行完后需要清理环境,这时可以用setUp()和tearDown():
class TestListOperations(unittest.TestCase):
def setUp(self):
self.mylist = [1, 2, 3]
def tearDown(self):
self.mylist = None
def test_append(self):
self.mylist.append(4)
self.assertEqual(self.mylist, [1, 2, 3, 4])
def test_remove(self):
self.mylist.remove(2)
self.assertEqual(self.mylist, [1, 3])
setUp() 在每个测试方法运行前执行,tearDown() 在每个测试方法运行后执行。
- 运行多个测试文件
如果测试文件较多,可以用以下命令批量运行:
python -m unittest discover -s tests
其中 -s tests 指定测试目录。
总结:
单元测试是保证代码质量的重要工具。通过 unittest,我们可以编写测试用例,验证函数或类的正确性,并在代码修改后快速检查是否引入了新的错误。
练习与思考:
- 为一个计算斐波那契数列的函数编写单元测试,验证前十个值是否正确。
- 使用
assertRaises测试输入非法参数时函数是否能抛出异常。 - 思考如何在项目中将单元测试与持续集成(CI)结合,自动运行测试用例。
正文完