本文共 6028 字,大约阅读时间需要 20 分钟。
测试夹具(Fixture)是为了设置和清理测试环境而设计的。它可以在测试前准备必要的资源,并在测试后清理这些资源。unittest框架提供了多种夹具方法,包括类级和模块级的setUp和tearDown方法。
setUp()方法:在每个测试方法运行之前执行,用于初始化测试环境。可以为每个测试方法准备必要的资源。
tearDown()方法:在每个测试方法运行之后执行,用于清理测试环境。无论测试方法是否成功运行,这个方法都会被调用。
例如:
import unittestclass StudyTestCase(unittest.TestCase): def setUp(self): print("setUp : 准备完成,可以测试...") def tearDown(self): print("tearDown : 测试完成 ...") def test_case1(self): print("run : test_case1") def test_case2(self): print("run : test_case2") setUpClass()方法:在类中的所有测试方法运行之前执行,用于初始化类级资源。
tearDownClass()方法:在类中的所有测试方法运行之后执行,用于清理类级资源。
例如:
import unittestclass Test(unittest.TestCase): @classmethod def setUpClass(cls): print("类夹具 setUpClass : study_testfixture.py") @classmethod def tearDownClass(cls): print("类夹具 tearDownClass : study_testfixture.py") def setUp(self): print("setUp ... study_testfixture.py") def tearDown(self): print("tearDown ... study_testfixture.py") def test_case(self): print("run : Test_case") setUpModule()方法:在模块中的所有测试方法运行之前执行,用于初始化模块级资源。
tearDownModule()方法:在模块中的所有测试方法运行之后执行,用于清理模块级资源。
例如:
import unittestdef setUpModule(): print("模块级夹具 setUpModule : study_testfixture.py") def tearDownModule(): print("模块级夹具 tearDownModule : study_testfixture.py")class Test(unittest.TestCase): @classmethod def setUpClass(cls): print("类夹具 setUpClass : study_testfixture.py") @classmethod def tearDownClass(cls): print("类夹具 tearDownClass : study_testfixture.py") def setUp(self): print("setUp ... study_testfixture.py") def tearDown(self): print("tearDown ... study_testfixture.py") def test_case(self): print("run : Test_case") 为了简化测试代码,可以将测试夹具封装到一个独立的模块中。例如:
# myunite.pyimport unittestclass MyUnite(unittest.TestCase): @classmethod def setUpClass(cls): print("类夹具 setUpClass : study_testfixture.py") @classmethod def tearDownClass(cls): print("类夹具 tearDownClass : study_testfixture.py") def setUp(self): print("setUp ... study_testfixture.py") def tearDown(self): print("tearDown ... study_testfixture.py") 然后在需要测试的模块中继承MyUnite类:
# study_testfixture.pyfrom 测试.fixture.myunite import MyUniteclass StudyTestCase(MyUnite): def test_case1(self): print("run : test_case1 : study_testfixture.py") def test_case2(self): print("run : test_case2 : study_testfixture.py") unittest框架提供了多种断言方法,用于验证测试结果。常用的断言方法包括:
assertEqual(a, b):检查a和b是否相等。assertNotEqual(a, b):检查a和b是否不相等。assertTrue(x):检查x是否为True。assertFalse(x):检查x是否为False。assertIs(a, b):检查a和b是否是同一个对象。assertIsNot(a, b):检查a和b是否不是同一个对象。assertRaises(exception, callable):检查callable是否在执行时抛出指定的异常。assertIn(a, b):检查a是否在b中。assertLength(a, b):检查a和b的长度是否相等。例如:
import unittestclass MyMathTest(unittest.TestCase): def test_fib(self): print("测试斐波那契数列") a, b = 0, 1 for i in range(0, 50): self.assertEqual(my_math.fib(i), a, "斐波那契数列第{}项错误..".format(i)) a, b = b, a + b def test_NarcissisticNumber(self): print("测试水仙花数") expected = [153, 370, 371, 407] actual = my_math.NarcissisticNumber(100, 999) self.assertEqual(expected, actual, "水仙花数验证失败..") TextTestRunner是默认的测试运行器,生成文本报告。可以通过参数指定测试套件:
import unittestsuite = unittest.TestSuite()test_cases = unittest.defaultTestLoader.discover(os.getcwd(), pattern='*.py')suite.addTests(test_cases)unittest.main(defaultTest='suite')
HTMLTestRunner需要先安装,然后修改其在Python3中的兼容性。安装方法:
pip install htmltestrunner
修改HTMLTestRunner.py:
# 确保使用Python3兼容的版本import ioclass HTMLTestRunner(unittest.TextTestRunner): def __init__(self, *args, **kwargs): super(HTMLTestRunner, self).__init__(*args, **kwargs) self.outputBuffer = io.StringIO() def run(self, test): self.outputBuffer = io.StringIO() super(HTMLTestRunner, self).run(test) result = self.outputBuffer.getvalue() # 生成HTML报告 ...
使用HTMLTestRunner运行测试:
import osfrom unittest import TestSuite, defaultTestLoaderimport HTMLTestRunnerdef run_tests(): suite = TestSuite() test_cases = defaultTestLoader.discover(os.getcwd(), pattern='*.py') suite.addTests(test_cases) runner = HTMLTestRunner( stream=open(os.path.join(os.getcwd(), 'test_report.html'), 'wb'), title='Python自动化测试报告', description='报告详情如下:' ) runner.run(suite)if __name__ == '__main__': run_tests()
以my_math.py为例:
# my_math.pydef fib(n=0): """斐波那契数列""" a, b = 0, 1 for i in range(n): a, b = b, a + b return adef NarcissisticNumber(left=100, right=999): """水仙花数""" assert(left >= 0 and right <= 999) lst = [] for i in range(left, right + 1): s = str(i) one = int(s[-1]) ten = int(s[-2]) hun = int(s[-3]) if i == one**3 + ten**3 + hun**3: lst.append(i) return lstif __name__ == '__main__': print("斐波那契数列第10项是:", fib(10)) print("10 - 1000 的水仙花数有:\n", NarcissisticNumber(100, 999)) 编写测试用例:
import unittestfrom my_math import fib, NarcissisticNumberclass MyMathTest(unittest.TestCase): def test_fib(self): print("测试斐波那契数列") a, b = 0, 1 for i in range(0, 50): self.assertEqual(fib(i), a, "斐波那契数列第{}项错误..".format(i)) a, b = b, a + b def test_NarcissisticNumber(self): print("测试水仙花数") expected = [153, 370, 371, 407] actual = NarcissisticNumber(100, 999) self.assertEqual(expected, actual, "水仙花数验证失败..") 运行测试:
if __name__ == '__main__': unittest.main(verbosity=2)
通过以上方法,可以有效地使用unittest框架进行测试,确保代码的稳定性和功能性。
转载地址:http://kwso.baihongyu.com/