1. unittest介绍
Python unittest是Python官方标准库中的一个模块,提供了自动化测试的功能和测试相关的工具。通过使用Python unittest可以方便地编写、运行和管理自动化测试用例。Python unittest最初由Java语言的JUnit框架衍生而来,因此在某些方面与JUnit有些类似。
unittest模块的基本要素有:Test Fixture、Test Case、Test Suite、 Test Runner等。
1.1 Test Fixture
Test Fixture是指测试夹具,它是测试执行的前、后环境的搭建和还原。
在unittest中,Test Fixture通常是通过setUp()和tearDown()方法来实现的。
1.2 Test Case
Test Case是指测试用例,它是指一系列相关的测试步骤、输入、操作和预期输出的集合。
在unittest中,Test Case通常是通过编写继承unittest.TestCase类中的一个或多个测试方法来实现的。每个测试方法中一般包含assert语句,用于对测试结果进行验证。
1.3 Test Suite
Test Suite是指测试套件,它是指一组相关的测试用例的集合。Test Suite可以包含多个Test Case。
在unittest中,Test Suite通常是通过编写继承unittest.TestSuite类的测试套件来实现的。Test Suite中可以添加多个Test Case。
1.4 Test Runner
Test Runner是指测试运行器,它是指协调和执行测试的引擎。
在unittest中,Test Runner通常是通过Python unittest自带的命令行测试运行工具或第三方测试运行工具来实现的。
2. unittest用例执行顺序的问题
在unittest中,默认情况下,它会按照用例的名称的字母顺序来执行所有测试用例。但是,在某些情况下,我们可能需要自定义用例的执行顺序,比如测试用例之间具有依赖关系,或者需要按照某种逻辑顺序来执行用例。这时,我们可以通过unittest中提供的装饰器来控制用例的执行顺序。
2.1 按照方法名称顺序
unittest框架默认是按照测试方法名称字典序(alphabetically)来执行测试用例的。可以使用sortTestMethodsUsing()方法自定义用例的排序。此方法需要传入一个函数,用于比较两个测试方法的顺序。
import unittest
class TestSequenceFunctions(unittest.TestCase):
def test_shuffle(self):
# 测试shuffle方法
pass
def test_choice(self):
# 测试choice方法
pass
def test_sample(self):
# 测试sample方法
pass
if __name__ == '__main__':
# 按照测试方法名称升序执行
# 在这里使用默认方式
unittest.main()
2.2 按照TestSuite添加的顺序执行
如果需要按照添加Test Case的顺序执行用例,可以使用TestSuite。在创建TestSuite时,添加的测试用例就是按照添加的顺序来执行的。
import unittest
from test_case_1 import TestSequenceFunctions1
from test_case_2 import TestSequenceFunctions2
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(TestSequenceFunctions1('test_shuffle'))
suite.addTest(TestSequenceFunctions2('test_choice'))
suite.addTest(TestSequenceFunctions1('test_sample'))
# 按照添加的顺序执行
runner = unittest.TextTestRunner()
runner.run(suite)
2.3 使用装饰器控制用例的执行顺序
unittest提供了两个装饰器,@unittest.skip(reason)和@unittest.skipIf(condition, reason),可以用于控制测试用例的执行和跳过某些测试用例。当然,还有另外一个装饰器@unittest.expectedFailure,用于标记某些预期失败的测试用例。
@unittest.skip()装饰器用于跳过测试用例,将其标记为不执行。它可以接受一个可选的reason参数,用于说明为什么要跳过这个测试用例。例如:
import unittest
class TestSequenceFunctions(unittest.TestCase):
@unittest.skip("暂时不执行这个测试用例")
def test_shuffle(self):
# 测试shuffle方法
pass
@unittest.skipIf(temperature > 0.5, "温度太高,不执行此测试用例")
def test_choice(self):
# 测试choice方法
pass
@unittest.expectedFailure
def test_sample(self):
# 测试sample方法
pass
if __name__ == '__main__':
unittest.main()
2.4 使用TestLoader的sortTestMethodsUsing()方法
TestLoader是TestCase、TestSuite或者TestModule对象进行加载的工具,这些工具都可以生成一个TestSuite来包含它加载的测试用例。
sortTestMethodsUsing()方法接收一个可调用对象,用于完全控制测试方法的顺序。默认情况下,其值为None。在这种情况下,unittest会自动将测试用例按字母表顺序排序,并在按顺序运行它们。
下面演示一个自定义一个方法名排序函数的例子,其中按照test_x_XX格式排序,其中x_XX表示每个类中的文件名,如果文件名相同,并且方法名第二部分相同,则第三部分按照字典序排列。
import unittest
class TestSuite(unittest.TestCase):
# pass
def test_suite_method_1(self):
self.assertEqual(1, 1)
def test_suite_method_2(self):
self.assertEqual(1, 1)
def test_suite_method_b(self):
self.assertEqual(1, 1)
def test_suite_method_a(self):
self.assertEqual(1, 1)
if __name__ == "__main__":
# 自定义排序函数
def custom_sort_method(test_name):
"""a custom sort function"""
class_name, method_name = test_name.split('.')
filename = class_name.split('_')[1]
return filename, int(method_name.split('_')[2]), method_name.split('_')[3]
suite = unittest.TestLoader().loadTestsFromTestCase(TestSuite)
suite.sortTestMethodsUsing(custom_sort_method)
unittest.TextTestRunner(verbosity=2).run(suite)
3. 总结
Python unittest是Python官方标准库中的一个模块,提供了一系列自动化测试的功能和测试相关的工具。通过使用Python unittest可以方便地编写、运行和管理自动化测试用例。
默认情况下,unittest会按照测试方法名称字典序(alphabetically)来执行测试用例。可以使用sortTestMethodsUsing()方法自定义用例的排序。此方法需要传入一个函数,用于比较两个测试方法的顺序。
如果需要按照添加Test Case的顺序执行用例,可以使用TestSuite。在创建TestSuite时,添加的测试用例就是按照添加的顺序来执行的。
如果需要控制测试用例的执行状态,可以使用@unittest.skip()装饰器。它可以接受一个可选的reason参数,用于说明为什么要跳过这个测试用例。还可以使用@unittest.expectedFailure装饰器,用于标记某些预期失败的测试用例。