使用unittest进行单元测试需继承TestCase类,编写以test_开头的方法,并用assertEqual、assertTrue等断言验证结果,setUp和tearDown用于初始化和清理测试环境,测试文件应以test_命名并置于tests目录下,通过unittest.main()或命令行发现并运行测试。

Python进行单元测试,最直接、也是官方推荐的方式就是使用其内置的
unittest
要使用
unittest
unittest
unittest.TestCase
test_
unittest
unittest.TestCase
assertEqual
assertTrue
unittest.main()
我们来举一个简单的例子。假设我们有一个简单的数学函数,用于计算两个数的和:
# my_math.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b现在,我们为它编写一个测试文件:
立即学习“Python免费学习笔记(深入)”;
# test_my_math.py
import unittest
from my_math import add, subtract
class TestMyMathFunctions(unittest.TestCase):
def test_add_positive_numbers(self):
"""测试正数相加"""
result = add(5, 3)
self.assertEqual(result, 8) # 断言结果是否为8
def test_add_negative_numbers(self):
"""测试负数相加"""
result = add(-5, -3)
self.assertEqual(result, -8)
def test_add_mixed_numbers(self):
"""测试正负数混合相加"""
result = add(5, -3)
self.assertEqual(result, 2)
def test_subtract_positive_numbers(self):
"""测试正数相减"""
result = subtract(10, 4)
self.assertEqual(result, 6)
def test_subtract_zero(self):
"""测试与零相减"""
result = subtract(7, 0)
self.assertEqual(result, 7)
if __name__ == '__main__':
unittest.main()运行这个测试文件(
python test_my_math.py
在
unittest
TestCase
说实话,刚开始接触时,可能会觉得方法有点多,但它们的设计都非常直观,一旦用起来就会发现它们各自的用途。以下是一些最常用、也最实用的断言方法:
assertEqual(a, b, msg=None)
a
b
self.assertEqual(add(1, 2), 3)
assertNotEqual(a, b, msg=None)
assertEqual
a
b
assertTrue(x, msg=None)
x
True
self.assertTrue(user.is_active)
assertFalse(x, msg=None)
x
False
assertIs(a, b, msg=None)
a
b
a is b
assertEqual
assertIsNot(a, b, msg=None)
a
b
assertIsNone(x, msg=None)
x
None
assertIsNotNone(x, msg=None)
x
None
assertIn(member, container, msg=None)
member
container
self.assertIn('apple', ['banana', 'apple', 'orange'])assertNotIn(member, container, msg=None)
member
container
assertIsInstance(obj, cls, msg=None)
obj
cls
assertNotIsInstance(obj, cls, msg=None)
obj
cls
callable
exception
def test_divide_by_zero(self):
with self.assertRaises(ValueError):
# 假设有一个divide函数,当除数为0时抛出ValueError
divide(10, 0)assertGreater(a, b, msg=None)
a
b
assertLess(a, b, msg=None)
a
b
实际项目中,你会发现自己最常用到的还是
assertEqual
assertTrue
assertRaises
unittest
setUp
tearDown
在单元测试中,我们经常需要为每个测试用例准备一个干净、独立的环境,并在测试结束后清理这个环境,以确保测试之间互不影响。这就是
setUp
tearDown
unittest.TestCase
setUp()
test_
举个例子,假设你的测试需要操作一个用户对象,每次测试都需要一个全新的用户实例:
import unittest
class User:
def __init__(self, name):
self.name = name
self.is_active = True
def deactivate(self):
self.is_active = False
class TestUserOperations(unittest.TestCase):
def setUp(self):
"""在每个测试方法运行前创建一个新的用户实例"""
print("\nSetting up a new user...")
self.user = User("Alice")
def test_user_is_active_by_default(self):
self.assertTrue(self.user.is_active)
self.assertEqual(self.user.name, "Alice")
def test_deactivate_user(self):
self.user.deactivate()
self.assertFalse(self.user.is_active)
# 这里即使上一个测试改变了user的状态,因为setUp会重新创建,所以这个测试依然是独立的你会发现,
setUp
test_user_is_active_by_default
test_deactivate_user
Alice
tearDown()
setUp
tearDown
继续上面的例子,如果
User
tearDown
# ... (User类定义不变)
class TestUserOperations(unittest.TestCase):
def setUp(self):
print("\nSetting up a new user...")
self.user = User("Alice")
# 假设这里模拟打开一个文件句柄或数据库连接
# self.file_handle = open("temp_log.txt", "w")
def tearDown(self):
"""在每个测试方法运行后清理资源"""
print("Tearing down user and resources...")
del self.user # 显式删除对象,虽然Python垃圾回收机制通常会处理
# self.file_handle.close() # 关闭文件句柄
# os.remove("temp_log.txt") # 删除临时文件
def test_user_is_active_by_default(self):
self.assertTrue(self.user.is_active)
def test_deactivate_user(self):
self.user.deactivate()
self.assertFalse(self.user.is_active)除了
setUp
tearDown
unittest
setUpClass(cls)
tearDownClass(cls)
setUpClass
tearDownClass
@classmethod
随着项目规模的扩大,测试文件会越来越多,如何有效地组织这些测试,并确保它们都能被正确地发现和运行,就成了一个需要考虑的问题。一个良好的测试组织结构不仅能提升开发效率,还能让团队成员更容易理解和维护测试代码。
统一的命名约定: 这是最基本也是最重要的一点。通常,测试文件会以
test_
test_module_name.py
Test
TestModuleName
test_
unittest
test_add_positive_numbers
与被测试代码保持一致的目录结构: 一个常见的做法是将测试文件放在与被测试代码平行的
tests/
my_project/
├── my_module/
│ ├── __init__.py
│ └── core.py
└── tests/
├── __init__.py
└── test_core.py这种结构使得测试代码易于查找,也方便管理。
使用unittest.main()
unittest.TestSuite
if __name__ == '__main__': unittest.main()
unittest
python -m unittest tests/test_core.py
python -m unittest discover -s tests -p 'test_*.py'
-s tests
-p 'test_*.py'
tests
善用__init__.py
tests
__init__.py
unittest discover
为复杂的测试场景创建独立的测试套件(TestSuite
unittest.TestSuite
TestSuite
import unittest
from tests.test_core import TestCoreFunctions
from tests.test_utils import TestUtilityFunctions
def suite():
test_suite = unittest.TestSuite()
test_suite.addTest(unittest.makeSuite(TestCoreFunctions))
test_suite.addTest(unittest.makeSuite(TestUtilityFunctions))
# 也可以添加单个测试方法
# test_suite.addTest(TestCoreFunctions('test_specific_function'))
return test_suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())这种方式虽然稍微复杂一些,但它提供了极高的灵活性,可以根据需求定制测试运行的范围。
通过这些实践,你的测试代码将变得有条不紊,无论是新增功能还是修复bug,都能快速定位到相关的测试,并确保代码的质量。良好的组织结构,本身就是一种效率的提升。
以上就是Python怎么进行单元测试_unittest框架单元测试入门指南的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号