测试套件TestSuite
,用于对测试用例的组织。测试用例组织好以后就可以使用运行器TestRunner
运行测试套件中包含的测试用例。
为了更方便演示,我们将之前的示例拆分到几个文件中:
+ test_demo 测试文件夹
- add.py 待测函数 add() 所在的文件
- test_a.py 测试类 TestAddOne 所在的文件,测试整数与字符串相加
- test_b.py 测试类 TestAddTwo 所在的文件,测试列表与元组相加
- run.py 测试套件
除了 run.py 以外其他文件内容如下:
add.py
# 待测函数
def add(a, b):
return a+b
test_a.py
import unittest
from add import add
class TestAddOne(unittest.TestCase):
def test_add_int(self):
'''测试int相加'''
result = add(5, 100)
print('整数相加结果:', result)
self.assertEqual(result, 105, '整数相加错误')
def test_add_str(self):
'''测试str相加'''
result = add('5', '6')
print('字符串相加结果:', result)
self.assertEqual(result, '56', '字符串相加错误')
test_b.py
import unittest
from add import add
class TestAddTwo(unittest.TestCase):
def test_add_list(self):
result = add(['1', '2'], ['a', 'b'])
print('列表相加结果:', result)
self.assertEqual(result, ['1','2','a','b'], '列表相加错误')
def test_add_tuple(self):
result = add((1,2), (3,4))
print('元组相加结果:', result)
self.assertEqual(result, (1,2,3,4), '元组相加错误')
这几个文件写好以后,我们可以来研究测试套件 TestSuite 了。
TestSuite 类用来组织测试用例,需要创建实例对象后使用。现在我们来把 test_a 和 test_b 文件中的所有用例都添加到套件:
import unittest
from test_a import TestAddOne # => 引入加入套件的测试类
from test_b import TestAddTwo
suite = unittest.TestSuite() # => 创建测试套件对象
suite.addTest(TestAddOne('test_add_int')) # => 将用例加入测试套件
suite.addTest(TestAddOne('test_add_str'))
suite.addTest(TestAddTwo('test_add_list'))
suite.addTest(TestAddTwo('test_add_tuple'))
runner = unittest.TextTestRunner() # => 创建运行器对象
runner.run(suite) # => 运行组织好的测试套件
上面的代码把四个测试方法都加入了测试套件 suite,装载的方式为:
- 引入需要装载的测试类
- 创建 TestSuite 对象
- 调用 addTest() 方法将测试用例加入套件,加入方式
测试类('测试用例')
。
这里把测试用例名作为字符串使用。
这种方式明显不够用,如果要加入测试套件的用例非常多,那么这种行为无异于自讨苦吃。
为了更方便的组织测试套件,需要使用加载器批量查找测试用例并加入测试套件。
加载器会自动将找到的用例加入测试套件。
加载器 TestLoader 提供了以下几个方法来查找用例并批量加入测试套件:
- loadTestsFromTestCase:根据传入的测试类查找用例
- loadTestsFromName:根据传入的名称查找用例
- loadTestsFromNames:根据传入的名称序列(批量)查找用例
- loadTestsFromModule:通过模块名添加该模块内所有的测试用例(不推荐,仅为向下兼容存在)
loadTestsFromTestCase
通过测试用例类的名称来加载用例,每次只能传入一个类名。我们修改 run.py 文件中的测试套件加载方式。
run.py
import unittest
from test_a import TestAddOne # => 引入加入套件的测试类
from test_b import TestAddTwo
loader = unittest.TestLoader() # => 创建加载器对象
tests = loader.loadTestsFromTestCase(TestAddOne) # => 通过测试类加载测试
print('测试套件:', tests) # => 打印一下已构造的测试套件
runner = unittest.TextTestRunner() # => 创建运行器对象
runner.run(tests) # => 运行组织好的测试套件
运行的结果:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
整数相加结果: 105
字符串相加结果: 56
测试套件: <unittest.suite.TestSuite tests=[<test_a.TestAddOne testMethod=test_add_int>, <test_a.TestAddOne testMethod=test_add_str>]>
从打印出来的测试套件可以看到,找到了两个用例test_add_int
和test_add_str
。
loadTestsFromName
通过名称查找用例,这个名称可以是模块名(文件名),测试类名,测试方法名(用例名),或者其他可调用对象中的测试用例,返回一个测试套件 TestSuite。
所有的查找都针对 run.py 所在的文件夹。
模块名:
tests = loader.loadTestsFromName('test_b') # => 以字符串的形式传入文件名
print(tests)
可以找到 test_b.py 文件中的test_add_list
和test_add_tuple
两个测试用例。
类名:
import test_a # => 需要引入模块
tests = loader.loadTestsFromName('TestAddOne', module=test_a) # => 需要指定模块
print(tests)
通过类名找的话, 需要指定模块(文件)才行,所以需要引入测试类所在的模块。
或者不引入:
tests = loader.loadTestsFromName('test_a.TestAddOne') # => 模块名.类名
print(tests)
在传入的字符串参数中指定模块名,模块名.类名
。
如果测试用例文件在子文件夹中(子文件夹中必须包含__init__.py
文件),还需要加上包名:
```python
tests = loader.loadTestsFromName(
'test_sub.test_a.TestAddOne' # => 包名.模块名.类名
)
print(tests)
测试用例名:
测试用例名需要通过 类名.用例名
来指定:
tests = loader.loadTestsFromName(
'test_a.TestAddOne.test_add_str'
)
print(tests)
只会找到一个用例test_add_str
。
loadTestsFromNames
如果同时需要查找多个地方的用例,通过带 s 的方法,传入一个序列来批量指定要查找的用例。
case = [
'test_a.TestAddOne.test_add_str', # => 指定了一个测试用例
'sub_test.test_b.TestAddTwo' # => 指定了一个测试类
]
tests = loader.loadTestsFromNames(case)
print(tests)
这里会查找到 3 个用例,test_add_str
和 TestAddTwo
中的两个用例。
网友评论