测试套件TestSuite
测试套件,把测试套件理解为容器,容器里面存放是一个个的测试用例,然后执行这个容器中的测试用例。
多个用例执行顺序:
- 收集用例
- 将用例添加到容器中
- 找个人去执行容器中的用例,这个人我们称为执行器
TestSuite容器有两种方式添加用例
-
suite.addTest(用例对象)
,每次往容器中添加一个 -
suite.addTests([用例对象1, 用例对象2, ......])
,一次添加多个用例 -
suite.countTestCases()
,输出当前容器中有多少用例
import unittest
class MyTestCase(unittest.TestCase):
def case_01(self):
self.assertTrue('FOO'.isupper()) # 'FOO'.isupper() --> True
def case_02(self):
self.assertTrue('Foo'.isupper())
def case_03(self):
self.assertTrue('bar'.islower())
if __name__ == '__main__':
# 1. 收集用例
case_01 = MyTestCase('case_01')
case_02 = MyTestCase('case_02')
case_03 = MyTestCase('case_03')
# 2. 创建一个容器,将第一步中的用例一一的 他添加到容器中
# 2.1 创建容器
suite = unittest.TestSuite()
# 2.2 j添加用例到容器中
suite.addTest(case_01)
suite.addTest(case_02)
suite.addTest(case_03)
print(suite.countTestCases())
# 3. 执行器执行容器中的用例
unittest.TextTestRunner().run(suite)
自动收集用例makeSuite
makeSuite执行顺序:
- 创建容器对象,并且同时将用例添加到容器中
- 找个
人
去执行容器中的用例,这个人
我们称为执行器
makeSuite容器有两种方式添加用例:
-
suite.addTest(用例对象)
,每次往容器中添加一个 -
suite.addTests([用例对象1, 用例对象2, ......])
,一次添加多个用例 -
suite.countTestCases()
,输出当前容器中有多少用例
import unittest
class MyTestCase(unittest.TestCase):
def case_01(self):
self.assertTrue('FOO'.isupper()) # 'FOO'.isupper() --> True
def case_02(self):
self.assertTrue('Foo'.isupper())
def case_03(self):
self.assertTrue('bar'.islower())
def test_case_01(self):
self.assertEqual(1, 1)
def test_case_02(self):
self.assertEqual(1, 0)
if __name__ == '__main__':
# # 创建容器并且同时将用例添加到容器中
# suite = unittest.makeSuite(testCaseClass=MyTestCase, prefix='case')
# print(,suite.countTestCases())
# # 执行器执行容器中的用例
# unittest.TextTestRunner().run(suite)
# # 创建容器并且同时将用例添加到容器中
# suite = unittest.makeSuite(testCaseClass=MyTestCase)
# print(suite.countTestCases())
# # 执行器执行容器中的用例
# unittest.TextTestRunner(verbosity=2).run(suite)
# 创建容器并且同时将用例添加到容器中
map_obj = map(MyTestCase, ['case_01', 'case_02', 'case_03'])
suite = unittest.makeSuite(testCaseClass=MyTestCase)
print(suite.countTestCases())
suite.addTests(map_obj)
print(suite.countTestCases())
# 执行器执行容器中的用例
unittest.TextTestRunner(verbosity=2).run(suite)
verbosity
verbosity有3种的错误信息状态提示报告
- 0,静默模式,对于测试结果给予简单提示。
- 1,默认模式,与静默模式类似,只是在每个成功的用例前面有个
.
每个失败的用例前面有个F
,跳过的用例有个S
。 - 2,详细模式,测试结果会显示每个用例的所有相关的信息。
只有0、1、2
三种状态,默认的是1。
import unittest
class MyTestCase(unittest.TestCase):
def case_01(self):
self.assertTrue('FOO'.isupper()) # 'FOO'.isupper() --> True
def case_02(self):
self.assertTrue('Foo'.isupper())
def case_03(self):
self.assertTrue('bar'.islower())
def test_case_01(self):
self.assertEqual(1, 1)
def test_case_02(self):
self.assertEqual(1, 0)
if __name__ == '__main__':
# 创建容器并且同时将用例添加到容器中
suite = unittest.makeSuite(testCaseClass=MyTestCase)
# 执行器执行容器中的用例
unittest.TextTestRunner(verbosity=0).run(suite)
类加载器TestLoader
TestLoader
类根据各种标准加载测试用例,并将它们返回给测试套件(suite)。
import os
import unittest
BASE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)))
discover_path = os.path.join(BASE_DIR, 'discover')
login_dir = os.path.join(discover_path, 'login')
register_dir = os.path.join(discover_path, 'register')
if __name__ == '__main__':
suite = unittest.TestLoader().discover(
start_dir=login_dir,
pattern='test*.py',
top_level_dir=discover_path,
)
print(suite.countTestCases())
unittest.TextTestRunner(verbosity=2).run(suite)
该discover
方法接收三个参数:
- start_dir:要测试的模块名或者测试用例的目录。
- pattern="test*.py":表示用例文件名的匹配原则,默认匹配以
test
开头的文件名,星号表示后续的多个字符。 - top_level_dir=None:测试模块的顶层目录,如果没有顶层目录,默认为None。
注意:
- discover对给定的目录是有要求的,它只识别Python的包,也就是目录内有init.py文件的才算是Python的包,只要是要读取的目录,都必须是包。
- 关于start_dir和top_level_dir的几种情况:
- start_dir目录可以单独指定,这个时候,让top_level_dir保持默认(None)即可。
- start_dir == top_level_dir, start_dir目录与top_level_dir目录一致,discover寻找start_dir指定目录内的符合规则的模块。
- start_dir < top_level_dir,start_dir目录是top_level_dir目录的子目录。discover寻找start_dir指定目录内的符合规则的模块。
- start_dir > top_level_dir,start_dir目录如果大于top_level_dir目录,等待你的是报错
AssertionError: Path must be within the project
。说你指定的路径(start_dir)必须位于项目内(top_level_dir)。
一般的,我们也可以不需要创建TestLoader类实例(想要用某个类的方法,通常都是通过个该类的实例化对象调用)。unittest已经帮我们实例化好了TestLoader对象—
defaultTestLoader
,我们可以直接使用defaultTestLoader.discover
。