一、单元测试框架unittest简介:
- 单元测试:指的是在软件开发当中,对程序的最小单元(函数、方法)进行测试的过程;
- unittest不仅可以用于单元测试,还可以用于自动化测试用例的开发和执行。组织执行自动化测试用例。并且提供一些丰富的断言方法,判断用例是否通过,最终能够生成测试报告;
- unittest:更简单,容易上手;pytest:市场份额会更多;一般情况下:能用pytest尽量用pytest,如果团队 的编码能力欠缺的情况下可以选择unittest,web自动化选择unittest,接口自动化选择pytest。
- unittest是Python自带的一个单元测试框架,unittest又被称为PyUnit,是由Java的JUnit衍生而来,基本结构是类似的。对于单元测试,需要设置预先条件,对比预期结果和实际结果。
- 由于unittest是Python自带的标准模块,所以不需要单独再去安装。引入包
import unittest即可使用。
二、单元测试框架作用
1.测试发现:从多个py文件中收集并且加载测试用例;
2.测试执行:将测试用例按照一定的顺序和条件去执行并且生成结果
3.测试判断:通过断言去判断结果是否正确;
4.测试报告:统计测试进度,通过率,生成报告;
三、基本概念
1.核心概念
- TestCase测试用例:
- TestSuite测试套件:整理测试用例,形成一个集合
- TestFixtrue测试固件:
- TestLoader测试加载器:加载测试用例套件或者测试用例
- TestRunner测试运行器:运行测试用例
2.unittest.TestCase:TestCase类,所有测试用例类继承的基本类
class TestDemo(unittest.TestCase)3.setupclass():必须使用@classmethod装饰器,所有test运行前执行一次;
import unittest
class TestDemo(unittest.TestCase):
@classmethod
def setupClass(cls):
print("hello world")4.tearDownClass():必须使用@classmethod装饰器,所有test运行完后执行一次;
import unittest
class TestDemo(unittest.TestCase):
@classmethod
def tearDownClass(cls):
print("tearDownClass")5.setup():每个测试方法运行前执行;
import unittest
class TestDemo(unittest.TestCase):
def setUp(self):
print("setUp")6.teardown():每个测试方法运行完后执行;
import unittest
class TestDemo(unittest.TestCase):
def tearDown(self):
print("tearDown")7.每个测试方法均以test开头,否则是不被unittest识别的;
def test_case1(self):
print('test_case1')8、unittest.main():将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以test命名开头的测试方法,并自动执行他们。
执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。
9.unittest.TestSuite():创建测试套件。
- addTest()/addTests()方法是将测试用例添加到测试套件中。
例如:将test_Demo1模块下的TestDemo1类下的test_case1测试用例添加到测试套件中
suite = unittest.TestSuite()
suite.addTest(test_Demo1.TestDemo1('test_case1'))10.unittest.TestLoader():根据不同的条件加载测试用例,其中有几个方法:
unittest.TestLoader().loadTestsFromName()
unittest.TestLoader().loadTestsFromNames()
unittest.TestLoader().loadTestsFromTestCase()
unittest.TestLoader().loadTestsFromModule()
unittest.TestLoader().discover()加载一个目录下所有的测试用例:通过测试加载器:加载测试用例套件或者测试用例
import unittest
if __name__ == '__main__':
# discover发现
suite = unittest.defaultTestLoader.discover("./public", pattern='test_*.py') # 在punlic目录下寻找test_开头的py文件
unittest.main(defaultTest="suite")例如:将test_case包下的test_Demo1模块下的TestDemo1类下的test_case1测试用例添加到测试套件中:
suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromName('test_case.test_Demo1.TestDemo1.test_case1'))11.unittest.defaultTestLoader():通过该类下面的discover()方法可自动根据测试目录test_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件中。
discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')12.unittest.TextTextRunner():通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。
suite = unittest.TestSuite()
suite.addTest(TestDemo('test_case1'))
runner = unittest.TextTestRunner()
runner.run(suite)三、基本示例
- 1.创建TestDemo类,并继承unittest.TestCase;创建setUpClass、tearDownClass、setUp、tearDown;之后创建多个以test开头的测试方法,每个这样的方法在load的时候便会生成一个TestCase实例,如TestDemo类中有3个test_xxx方法,最后在load到suite中便有3个测试用例。
import unittest
# 定义测试类,父类为unittest.TestCase
class TestDemo(unittest.TestCase):
#必须使用@classmethod装饰器,所有test运行前执行一次
@classmethod
def setUpClass(cls) -> None:
print("setUpClass")
# 必须使用@classmethod装饰器,所有test运行完后执行一次
@classmethod
def tearDownClass(cls) -> None:
print("tearDownClass")
# 每个测试方法运行前执行
def setUp(self) -> None:
print("setUp")
# 每个测试方法运行后执行
def tearDown(self) -> None:
print("teardown")
# 所有的测试方法都要以test为开头
def test_01(self):
print("test01")
def test_02(self):
print("test02")
def test_03(self):
print("test03")
if __name__ == '__main__':
unittest.main()执行结果为

- 2、执行test_Demo.py文件,运行结果:
setUpClass()最先执行;
tearDownClass()最后执行;
setup()每个测试方法运行前执行;
teardown()每个测试方法运行完后执行;
3个测试方法(test_case1、test_case2、test_case3)。
最后打印出的3个点为3个测试方法执行结果标识:成功是 .失败是 F出错是 E跳过是 S - 3.在unittest.main()中加verbosity参数可以控制输出报告的详细程度,默认是1。
verbosity=0 是简单报告;
verbosity=1 是一般报告;
verbosity=2 是详细报告。
将test_Demo.py文件里的unittest.main()修改为unittest.main(verbosity=2),再次执行脚本。
运行结果:执行后输出的详细报告信息。
















