优点
python内嵌的测试框架,无需安装即可使用- 执行多个
case时,互不干扰,即使有一个case失败了,也不影响其余的case执行。
组成部分
TestCase:测试用例类,编写的用例类需要继承该类。TestSuite:测试集,可以添加多个case,然后以添加的顺序执行用例。TestLoader:测试加载器,可以加载一类case,然后添加到TestSuite中。TextTestRunner:用例执行器,生成简单文本显示执行结果,一般以TestSuite为单位来执行用例。TestResult:测试结果。
实例:
1.
新建一个文件叫:case.py
import unittest
class study(unittest.TestCase):
def setUp(self):
print('测试开始前的准备函数')
def test_01(self):
print('测试用例01')
def test_02(self):
print('测试用例02')
def tearDown(self):
print('测试结束后的善后函数')
if __name__ == '__main__':
unittest.main()
然后执行python case.py就可得到:
测试开始前的准备函数
测试用例01
测试结束后的善后函数
.测试开始前的准备函数
测试用例02
测试结束后的善后函数
.
----------------------------------------------------------------------
Ran 2 tests in 0.005s
OK
setUp() 和 tearDown() 函数在每一个用例执行前都执行一遍。如果只需要在类层面执行一次这两种函数,可以使用 setUpClass() 和 tearDownClass 函数,不过在使用时需要用@classmethod修饰。
例如:
import unittest
class study(unittest.TestCase):
@classmethod
def setUpClass(self):
print('测试开始前的准备函数,类层面')
def test_01(self):
print('测试用例01')
def test_02(self):
print(‘测试用例02')
@classmethod
def tearDownClass(self):
print('测试结束后的善后函数,类层面')
if __name__ == '__main__':
unittest.main()
执行结果:
测试开始前的准备函数,类层面
测试用例01
.测试用例02
.测试结束后的善后函数,类层面
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
2.
将刚才case.py中的两个测试用例添加到另一个文件的TestSuite中并执行:
在case.py文件所在目录下新建一个文件run.py,内容为:
import unittest
from case import study
# 实例化
suite = unittest.TestSuite()
# 列表形式组合用例
case = [study('test_02'), study('test_01')]
suite.addTests(case)
# 实例化
runner = unittest.TextTestRunner()
runner.run(suite)
执行python run.py,结果为:
测试开始前的准备函数,类层面
测试用例02
.测试用例01
.测试结束后的善后函数,类层面
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
可以看到,用例的执行顺序也改变了。
suite添加用例还可以以下列方式进行:
suite.addTest(study('test_02'))
suite.addTest(study('test_01'))
不过这种方式比较繁琐。
3.
可以发现,上述的添加case的方法只适合与用例较少的情况,在用例非常多的情况下,为了方便添加,就需要使用TestLoader,即用例加载器。
接下来就对run.py进行改造:
import unittest
from case import study
suite = unittest.TestSuite()
loader = unittest.TestLoader().loadTestsFromTestCase(study)
suite.addTests(loader)
runner = unittest.TextTestRunner()
runner.run(suite)
执行结果:
测试开始前的准备函数,类层面
测试用例01
.测试用例02
.测试结束后的善后函数,类层面
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
loader查找case的方式还有如下几种:
import case
loader = unittest.TestLoader().loadTestsFromModule(case)
# 感觉也是每次添加一个用例,不推荐
loader = unittest.TestLoader().loadTestsFromName('case.study.test_01')
# 如果有多个case文件,case, case1……,可以使用discover
loader = unittest.defaultTestLoader.discover(start_dir='path', pattern='case*.py')
# path即指这些case文件所在的绝对路径
4.
TextTestRunner在上面的例子中有所体现,基本上就是:
runner = unittest.TextTestRunner()
runner.run(suite)
这样的用法。
断言
测试用例执行需要用断言来判断是否成功
新建一个example01,内容:
import unittest
a, b = 1, 2
class study01(unittest.TestCase):
def setUp(self):
print('----start----')
def test_01(self):
self.assertEqual(a, b, 'a < b')
def tearDown(self):
print('-----end-----')
if __name__ == '__main__':
unittest.main()
执行结果:
----start----
-----end-----
F
======================================================================
FAIL: test_01 (__main__.study01)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\weilong\Pworkspace\Test_study\Unitest_simple\example01.py", line 8, in test_01
self.assertEqual(a, b, 'a < b')
AssertionError: 1 != 2 : a < b
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (failures=1)
可以看到,如果断言失败,会显示预留的信息。
断言的类型:
assertEqual(a,b) a==b 值是否相等
aassertNotEqual(a,b) a!=b 值是否不相等
aasserIs(a,b) a is b 值是否相同
aassertIsNot(a,b) a is not b 值是否不同
assertIn(a,b) a in b a是否包含b
assertNotIn(a,b) a not in b a是否不包含b
ssertTrue(a) bool(a) is true 是否为真
assertFalse(a) bool(a)is false 是否为假
assertIsNone(a) a is None 是否为空
assertIsNotNone(a) a is None 是否不为空
assertIsInstance(a,b) Instance(a,b) a与b的数据类型一样
assertNotIsInstance(a) not Instance(a,b) a与b的数据类型不一样
跳过
有时候,因为环境或者需要等因素,一些用例需要进行跳过处理,这时候就需要用到@unittest.skip()来修饰用例。
改写example01:
import unittest
a, b = 1, 2
class study01(unittest.TestCase):
def setUp(self):
print('----start----')
@unittest.skip('a != b')
def test_01(self):
self.assertEqual(a, b, 'a < b')
def test_02(self):
self.assertNotEqual(a, b, 'a = b')
def tearDown(self):
print('-----end-----')
if __name__ == '__main__':
unittest.main()
执行结果:
s----start----
-----end-----
.
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK (skipped=1)
可以看懂跳过了一个测试用例。然后,skip()括号内的是reason,虽然执行结果没有显示,但其实是一个必要的参数,如果没填入会报错。
skip还有一种方式:
@unittest.skipIf(option, reason)
数据驱动
大量不同的数据进行相同的逻辑函数测试,可以用ddt模块,安装
pip install ddt
使用:
import unittest
from ddt import ddt, data
@ddt
class study02(unittest.TestCase):
@data('a', 'b', 'c')
# 即将a, b, c轮流与a比较,不相同的断言失败
def test_01(self, text):
self.assertEqual('a', text)
if __name__ == '__main__':
unittest.main()
此外,还有以文件形式存储的数据驱动
import unittest
from ddt import ddt, file_data
@ddt
class study03(unittest.TestCase):
@file_data('filepath')
# **指字典形式。 *指列表形式
def test_01(self, **text):
print(text)
if __name__ == '__main__':
unittest.main()
文件格式为json或yaml
对于excel、csv、txt文件,需要先进行数据的读取。
unpack修饰会将列表数据拆分到参数中,不然多个参数时会将数据只传到第一个参数中。
测试报告
利用html-testRunner插件生成html测试报告,安装:
pip install html-testRunner
使用:
import unittest
from case import study
from HtmlTestRunner import HTMLTestRunner
suite = unittest.TestSuite()
loader = unittest.TestLoader().loadTestsFromTestCase(study)
suite.addTests(loader)
# 在该文件目录下创建report目录,将报告存入其中
runner = HTMLTestRunner(output='report')
runner.run(suite)
带中文的测试信息会产生乱码,所以要对该插件的result.py进行修改,
将def generate_file(self, testRunner, report_name, report):方法下的with open(path_file, 'w') as report_file:改成with open(path_file, 'w',encoding='utf-8') as report_file:,这样就可以得到带中文的测试报告了。
328

被折叠的 条评论
为什么被折叠?



