Unittest是基于Python的单元测试框架,当然现在经常与其他框架集成,用来做自动化测试的框架。比如跟Selinum一起做Web UI的自动化测试框架,与Requests一起做接口的自动化测试框架,与Twisted一起做VoIP系统的自动化测试框架等等。
1 Unittest的几大组件介绍
2 测试用例的编写
(1)TestCase组件介绍
当我们写测试用例的时候,是需要自己实现一个类,该类需要集成unittest框架自带的TestCase类。我们具体每一个case的体现就是一个以test打头的实例方法,具体的测试用例代码都是写在以test打头的实力方法里面。
另外,父类TestCase给我们提供了几个方法【实例方法:setUP()、tearDown()、addCleanup(),类方法:setUpClass()、tearDownClass()、addClassCleanup()】,用来充当TestFixture。帮我们实现测试用例执行前环境的创建、执行后环境的清理工作。
当然,类TestCase给我们提供了大量的断言方法【assert*()】,用例判断测试用例的结果是否符合预期,这些断言方法,我们可以在以test打头的实例方法里调用。
最后TestCase给我们提供了运行case的实例方法【run()】,不过呢该方法我们不会直接调用,而是通过调用后文讲的【Testrunner】的方法【run()】,再调用它。
(2)TestCase有关方法执行顺序
(3)编写一个测试用例文件
如下:
## test_case_demo.py
import unittest
class TestStringMethods(unittest.TestCase):
@classmethod
def setUpClass(cls):
print('Before all test cases')
def setUp(self):
print('Before some test case')
def tearDown(self):
print('After some test case')
@classmethod
def tearDownClass(cls):
print('After all test cases')
def test_upper(self):
print(__name__ + '.' + 'test_uppern')
self.assertEqual('foo'.upper(), 'FOO')
def test_isupper(self):
print(__name__ + '.' + 'test_isuppern')
self.assertTrue('FOO'.isupper())
self.assertFalse('Foo'.isupper())
def test_split(self):
print(__name__ + '.' + 'test_splitn')
s = 'hello world'
self.assertEqual(s.split(), ['hello', 'world'])
# check that s.split fails when the separator is not a string
with self.assertRaises(TypeError):
s.split(2)
3 测试用例的执行
(1)TestSuite组件介绍
站坑
(2)TestLoader组件介绍
站坑
(3)TestResult组件介绍
(4)TestRunner组件介绍
顾名思义,TestRunner是用来运行我们的TestCase的,最终会产生一个结果,形成一个测试报告。
一般根据TestResult,我们的TestRunner会有几种,比如基于文本的TextTestRunner,基于HTML的HtmlTestRunner()。
我们已unittest框架自带的运行器TexTestRunner()为例,该class的构造方法,接受几个参数,如下:
TexTestRunner(stream=None, descriptions=True, verbosity=1, failfast=False,
buffer=False, resultclass=None, warnings=None, *, tb_locals=False)
最后我们可以调用该class的run()方法,运行testcase,当然testcase作为该方法的入参,如下:
run(test)
(5) 执行测试用例
从上面不难知晓,Testcase是Unittest框架的核心,整个框架都是围绕Testcase展开的,这一节重点阐述运行Testcase的几种方法。
(5.1)采用unittest框架自带的入口文件完成
采用unittest框架自带的入口文件,有两种处理方式。
第一种方式,在testcase文件里面,最后几行加入以下代码:
if __name__ == '__main__':
unittest.main()
然后执行以下命令即可。
python3 test_case_demo.py
这种方式的缺点是,一次只能执行一个testcase文件里面的case。
第二种方式,在testcase文件里面,无需额外的代码。不过呢,在运行的时候,需要调用unittest框架自带的入口文件。命令如下:
python3 -m unittest test_case_demo.py
采用该方式,可以通过添加【-v】对运行时的输出信息详细程度等做控制,当然还有其他参数,具体的可以查看源码【unittest/__main__.py】。
(5.2)自己编写入口文件
除了testcase文件以外,我们需要额外编写一个入口文件,用来运行我们的testcase。上面一种方式的入口文件,其实是由unittest框架自身实现的。
入口文件样例如下:
## entry_point.py
import unittest
from test_case import TestStringMethods
# step 1: create test suite
suite = unittest.TestSuite()
# # step 2-1: add test case to suite
# suite.addTest(TestStringMethods('test_upper'))
# suite.addTest(TestStringMethods('test_isupper'))
# suite.addTest(TestStringMethods('test_split'))
# # step 2-2: add test cases to suite
# cases = [TestStringMethods('test_upper'), TestStringMethods('test_isupper')]
# suite.addTests(cases)
# # step 2-3:
# suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestStringMethods))
# test 2-4:
suite.addTests(unittest.TestLoader().loadTestsFromName('test_case.TestStringMethods'))
# steo 2-5:
discover = unittest.defaultTestLoader.discover(
start_dir='./', pattern='test_case.py'
)
# step 3: create test runner
runner = unittest.TextTestRunner()
# step 4-1: start runner
runner.run(suite)
# step 4-2: start runner
# runner.run(discover)
最后执行以下命令,运行testcase。
python3 entry_point.py