1.基本术语
- 测试用例
- 测试套件
- 测试固件
- 测试运行器
2.使用unittest.TestCase
来创建测试
import unittest
class MyUnitTests(unittest.TestCase):
def setup(self): #TestCase 的实现方法
print("In setup..")
def tearDown(self): #TestCase 的实现方法
print("Tearing Down the test.")
def test_2(self): #以前缀test开始的方法会被测试运行器识别为测试用例
print("in test_2")
self.assertEqual(1 + 1, 2) #True
def test_1(self):
print("in test_1")
self.assertTrue(1+1 == 2) #True
def will_not_be_called(self): #默认情况下,这个方法不会被认定为一个测试方法
print("this method will not be called automatically")
if __name__ == "__main__":
unittest.main()
在这里setup
和tearDown
方法被称为固件,MyUnitTests.setup()
会在么个测试执行前被调用。它允许在测试被执行之前初始化一些常见变量。MyUnitTest.tearDown()
在每个测试执行之后会被调用。
当unittest。main()
程序别调用时,定义在MyUnitTests
中的测试会一个接着一个地执行。程序也可以接受一个测试运行器作为一个可选参数
3.控制测试执行
@unittest.skip("shipping test_2") #跳过不会被执行
def test_2(self):
print("in test_2")
self.assertEqual(1+1, 2)
@unittest.skip("shipping test_1") #跳过不会被执行
def test_1(self):
print("in test_1")
self.assertTrue(1+1 == 2)
@unittest.expectedFailure #失败的预期
def test_3(self):
...
4.使用unittest.TestSuite
import unittest
class MyUnitTestA(unittest.TestCase):
def test_a2(self):
print("MyUnitTestA.test_a2")
self.assertEqual(1 + 1, 3)
def test_a1(self):
print("MyUnitTestA.test_a1")
self.assertTrue(1 + 1 == 2)
def not_called_by_default(self):
print("MyUnitTestA:The method will not be called by default")
class MyUnitTestB(unittest.TestCase):
def test_b2(self):
print("MyUnitTestB.test_b2")
self.assertEqual(4*4 , 15)
def test_b1(self):
print("MyUnitTestB.test_b1")
self.assertTrue(4 + 4 == 8)
def not_called_by_default(self):
print("MyUnitTestB:The method will not be called by default")
#unitetest模块的'makeSuite'函数可以用来创建一个`TestSuite`类的实例:
#suite_a = unittest.makeSuite(MyUnitTestA)
def suite():
print("Inside suite()...")
suite_a = unittest.makeSuite(MyUnitTestA)
suite_b = unittest.makeSuite(MyUnitTestB)
suite_b.addTest(MyUnitTestB("not_called_by_default"))
return unittest.TestSuite((suite_a,suite_b))
#suite()函数创建了 TestSuite类的两个实例,即 suite_a和 suite_b.
#通过使用 addTest方法将 MyUnitTest.not_called_by_default 添加为测试套件中的一个实例
#函数返回了一个新的 TestSuite 对象。它使用一个Python元祖作为参数。在这个实例中,该元祖中包含了之前所创建的两个TestSuite的对象。
非测试方法(如not_called_by_default
方法)通常用于在不同的测试之间共享代码
unittest.TestCase
类包含方法 setUp()
,让我们只需创建这些对象一
次,并在每个测试方法中使用它们。如果你在 TestCase
类中包含了方法 setUp()
,Python
将先运行它,再运行各个以test_
打头的方法。这样,在你编写的每个测试方法中都可使用在方法 setUp()
中创建的对象了。
-m 是Python中内置的命令选项。它允许你将一个库模块作为一个脚本来运行
python -m unittest test.[filename]
python -m unittest test.[filename].[classname].[functionname]
批量执行单元测试
python -m unittest discover #这个命令可以批量测试文件
使用模拟库的单元测试
Mock是Python标准库中的unittest.mock
Mock库提供了一种灵活的方法来创建对象,这些对象可以用来替换正在测试的程序中的某些部分。
Mock库还以补丁装饰器的形式提供了另外一种非常重要的功能。补丁是这样一种机制:它允许你在测试中改变对象的行为。
Mock详情
其他单元测试工具
- Doctest
这是一个内置的模块,它支持一个类似于在解释器中编写的Python代码一样的文本。
#Doctest能够识别这样的代码,并运行它来检查是否做了它所描述的事件。
def add_nums(a,b):
"""Return sum of two numbers
Example usage:
.. doctest::
>>> add_nums(10, 20)
30
"""
return (a + b)
- Nose
- Pytest