unittest基本知识
【一】unittest组件:
testcases
test suites
test fixtrues
test runner
unittest.TestCase
测试类必须继承自unittest.TestCase
一个TestCase的实例就是一个测试用例。测试用例就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代 码(run),以及测试后环境的还原(tearDown)。单元测试(unittest)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
unittest.TestSuite
一个功能的验证往往需要多个测试用例,可以把多个测试用例集合在一起执行的,就是TestSuite,TestSuit用来组装单个测试用例,可以通过addTest加载到TestCase到TestSuit中,从而返回一个TestSuit实例;而且TestSuite也可以嵌套TestSuite。
unittest.TestLoader
(TestLoader是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例)
unittest.TextTestRunner
测试的执行也是单元测试中非常重要的一个概念,一般单元测试框架中都会提供非常丰富的执行策略和执行结果;在unittest中,通过TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。TestRunner可以使用图形界面、文本界面,或者返回一个特殊的值的方式来表示测试执行结果。
(这样整个流程就清楚了,首先是要写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由 TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,整个过程集成在unittest.main模 块中)
Test Fixture
对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖TestCase的setUp()和tearDown()方法 来实现。这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUp()中建立数据库连接以及进行一些初始化,在tearDown() 中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的TestCase留下一个干净的环境。关于fixture,还 有一个专门的库函数叫做fixtures,功能更加强大,详细介绍可以查阅相应的函数库资料。
以上这段参考自:https://www.cnblogs.com/101718qiong/p/7488861.html
【二】数据驱动
概念:数据驱动即数据的改变驱动自动化测试的执行,最终引起测试结果的改变。简单来说就是参数化的应用。数据量大的时候可以借助于json和yaml存放数据。
实现方式:在unittest中通过ddt来实现,ddt(data driver test),可以直接读取yaml文件
- 数据驱动简单case
import unittest
from ddt import ddt,data,unpack,file_data
@ddt
class UnitForTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("------类------前置条件")
@classmethod
def tearDownClass(cls):
print("------类------后置条件")
def setUp(self):
print("------方法------前置条件")
def tearDown(self):
print("------方法------前置条件")
# 测试用例默认以A-Z,a-z,0-9的顺序执行,与写的case顺序无关
# def test_01(self):
# print("测试case")
# print('dfdfdfdf')
# # print(a)
#
@file_data('test1.yaml')
def test_2(self, **user):
name = user.get('name')
pwd = user.get('pwd')
print(name,'***','\n',pwd)
if __name__ == '__main__':
unittest.main()
- yaml文件操作
import yaml
# yaml文件操作
# 读取yaml文件的方法,第二个参数必须写,要不然会有警告
file = open('test1.yaml',encoding='utf-8')
res = yaml.load(file,Loader=yaml.FullLoader)
# print(res)
for l in res:
print(l)
【三】unittest的断言应用
断言:自动化测试过程中,预期结果与实际结果的对比
常用的unittest的断言:
- self.assertTrue()
方法参考:assertTrue(self, expr, msg=None) - self.assertEqual()
assertEqual(self, first, second, msg=None) - self.assertIn()
assertIn(self, member, container, msg=None) - self.assertAlmostEqual()
assertAlmostEqual(self, first, second, places=None, msg=None,
delta=None)
其他断言如图参考:
image.png
断言如果失败,断言后的代码就不会被执行
如果想忽略掉断言失败的case,需要加装饰器
@unittest.expectedFailure
def test_05(self):
print('555')
【四】unittest.skip用法
作用:挑选合适的场景,执行对应的用例
具体的方法,大家可以加一个装饰器然后进源码查看,根据老师讲的视频,我列举下:
@unittest.skip('无条件跳过,msg')
def test_01(self):
print("测试case")
print('dfdfdfdf')
# print(a)
@unittest.skipUnless(1>2,'条件False,跳过case,否则执行case')
def test_03(self):
print('sdfdsfsfdsf')
@unittest.skipIf(condition='1<2', reason='条件True,跳过case,否则执行case')
def test_04(self):
print('44444')
【五】unittest套件及Runner应用
必须新建一个类运行套件,如果在同文件中,会自动调用unittest.main(),达不到要的效果
import unittest
from unit_demo.unit_fortest import UnitForTest
# 创建测试套件,记得TestSuite后面加括号
suite = unittest.TestSuite()
# 添加测试用例到套件中,通过测试用例名称来添加
# 单个添加
# suite.addTest(UnitForTest('test_a'))
# 多个添加
cases = [UnitForTest('test_a'),UnitForTest('test_b'),UnitForTest('test_c')]
suite.addTests(cases)
# 批量添加,指定路径下所有符合要求的case都会被运行
test_dir = './'
discover = unittest.defaultTestLoader.discover(start_dir=test_dir,pattern='unit_*.py')
# 基于类去执行case
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(UnitForTest))
# 基于名称去添加执行case
suite.addTests(unittest.TestLoader().loadTestsFromName('unit_fortest.UnitForTest'))
# 基于Runner来运行测试套件
# 创建运行器,记得加括号啊盆友们
runner = unittest.TextTestRunner()
# 运行套件
runner.run(suite)
# 运行discover
runner.run(discover)
【六】unittest+HTMLRunner自动化实现
代码如下,供参考
from HTMLTestRunner import HTMLTestRunner
import time
import os
import unittest
from unit_demo.unit_fortest import UnitForTest
# 创建测试套件,记得TestSuite后面加括号
suite = unittest.TestSuite()
t = time.strftime('%Y_%m_%d',time.localtime())
# print(t)
# 测试报告名称
report_name = t + '测试报告'
# 测试报告标题
report_title = '第一版测试报告'
# 测试报告描述
report_desc = '第一版测试XXX流程的报告'
# 报告路径
report_path = './report/'
# 报告文件
report_file = report_path + t + '测试报告.html'
if not os.path.exists(report_file):
os.mkdir(report_path)
with open(report_file,'wb') as report:
# 多个添加
cases = [UnitForTest('test_a'), UnitForTest('test_b'), UnitForTest('test_c')]
suite.addTests(cases)
runner = HTMLTestRunner(stream=report,title=report_title,description=report_desc)
runner.run(suite)
【七】unittest用例的四种执行方式
- 方法一
unittest.main() 可以执行当前文件所有的unittest模块中的测试用例
if __name__ == '__main__':
unittest.main()
- 方法二
加入容器中运行 testsuite,结合testrunner批量执行想要执行的内容(执行指定的测试用例),见上面 - 方法三
执行某个或者多个测试类,使用testloader,见上面 - 方法四
匹配每个目录下所有test开头的py文件,使用testloader.discover,见上面
网友评论