百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

unittest 单元测试框架(unittest框架缺点)

ccwgpt 2024-10-04 13:50 32 浏览 0 评论

unittest 单元测试框架

Unittest 单元测试框架简介

Unittest 是python内置的单元测试框架,具备编写用例、组织用例、执行用例、功能,可以结合selenium 进行UI自动化测试,也可以结合appium、requests 等模块做其它自动化测试。

使用unittest 前需要熟悉该框架的五个概念:

test case : 一个完整的测试单元,执行该测试单元可以完成对某一个问题的验证,完整提现在测试前环境准备(setUp),执行测试代码(run),一级测试后环境还原(tearDown)‘

test suit :多个测试用例的集合,测试套件或测试计划;

testLoader : 加载TestCase 到TestSuite 中的,其中loadTestsFrom__() 方法用于寻找TestCase,并创建它们的实例,然后添加到TestSuite中。

test runner : 执行多个测试用例,并将测试结果保存到TestTestResults 实例中,包括允许多少测试用例,成功了多少,失败了多少等信息;

test fixture : 一个测试用例的初始化准备环境及环境还原,主要是setUp() 和setDown() 方法

Unittest 基础框架

unittest 基础使用步骤:

  1. 用import 语句引入unittest 模块
  2. 让所执行的测试的类都基础于TestCase类,可以将TestCase看出是对特定类进程测试的方法的集合
  3. setUp() 方法中进行测试前的初始化工作, teardown() 方法中执行测试后的清理工作,它们都是TestCase 中的方法
  4. 编写测试的方法最好以test 开头(可以直接运行)

def test_add(self)、def test_sub(self)等,可以编写多个测试用例对被测对象进行测试

  1. 在编写测试方法过程中,使用TestCase class提供的方法测试功能点,比如:assertEqual等
  2. 调用 unittest.main() 方法运行所有以test开头的方法。

unittest 代码示例

import unittest
class test_cases(unittest.TestCase): # 继承TestCase类
def setUp(self): # 测试用例执行之前初始化
print('setUp')
def tearDown(self): # 测试用例执行之后还原、清理
print('tearDown')
def testcase01(self):
print('execute case01')
self.assertEqual(3,3) # 断言
if __name__ == '__main__':
unittest.main()

unittest 常用断言介绍:

断言即进行预期结果和实际结果对比。

assertEqual(a,b) a == b # a,b 是否相等

assertNotEqual(a,b) a != b # a,b 是否不相等

assertTrue(x) bool(x) is True # x 是否为True

assertFalse(x) bool(x) is False # x 是否为False

assertIn(a,b) a in b # a是否包含 b

assertGreater(a,b) a>b # a大于b

assertGreaterEqual(a,b) a>=b # a 大于等于b

assertLess(a,b) a<b # a 小于 b

assertLessEqual(a,b) a<=b # a 小于等于b

可以在断言最后一个参数中加入自定义的测试失败信息,如:

assertEqual(10,20,”10!=20 测试失败”) 当断言失败时,显示该信息。

unittest用例执行顺序:

当在一个测试类或多个测试模块下,用例数量较多时,unittest在执行用例(test_xxx)时,并不是从上到下的顺序执行,有特定的顺序。

unittest框架默认根据ACSII码的顺序加载测试用例,数字与字母的顺序为0~9,A~Z,a~z。

对于类来说,class TestAxx 会优先于class TestBxx被执行,对于方法来说,test_aaa()方法会优先于test_bbb()被执行。对于测试目录与测试文件来说,unittest同样时按照这个规则来加载测试用例的。

Unittest 用例执行顺序代码示例:

import unittest
class test_cases_01(unittest.TestCase):
def setUp(self) -> None:
print('setup')
def tearDown(self) -> None:
print('tearDown')
def test_ccc(self):
print('execute test_ccc')
self.assertEqual(3,3)
def test_aaa(self):
print('execute test_aaa')
self.assertEqual(3,3)
if __name__ == '__main__':
unittest.main()

Unittest 控制测试用例执行顺序:

如需要unittest自行控制测试方法的执行顺序,可以通过如下两种方法;

方法一:通过addTest()添加用例的顺序控制用例执行

if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(test_cases_01(
'test_ccc'))
suite.addTest(test_cases_01(
'test_aaa'))
unittest.main(
defaultTest='suite')

方法二:顺应unittest的默认执行顺序,通过设置测试类或者测试方法方法名字来实现。

Unittest 忽略用例:

在执行测试脚本的时候,可能会有某几条用例本次不想执行,但又不想删也不想注释,unittest通过忽略部分测试用例不执行的方式,分无条件忽略和有条件忽略,通过装饰器实现所描述的场景。提供的装饰器如下:

@unittest.skip(reason): 强制跳转。reason是跳转原因

@unittest.skipIf(condition,reason):condition为True的时候跳转

@unittest.skipUnless(condition,reason):condition为False的时候跳转

@unittest.expectedFailure:标记该测试预期为失败,如果该测试方法运行失败,则该测试不算做失败。

Unittest忽略用例示例代码:

import unittest
class test_cases_01(unittest.TestCase):
def setUp(self) -> None:
print('setup')
def tearDown(self) -> None:
print('tearDown')
@unittest.skip('无条件跳过')
def test_ccc(self):
print('execute test_ccc')
self.assertEqual(3, 3)
@unittest.skipIf(True, '条件为真时跳过')
def test_aaa(self):
print('execute test_aaa')
self.assertEqual(3, 3)
@unittest.skipUnless(False, '条件为假跳过')
def test_bbb(self):
print('execute test_bbb')
self.assertEqual(3, 3)
@unittest.expectedFailure # 预期结果为断言失败
def test_ddd(self):
print('execute test_ddd')
self.assertEqual(3, 3)
def test_fff(self):
print('execute test_fff')
self.assertEqual(3, 3)
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(test_cases_01(
'test_ccc'))
suite.addTest(test_cases_01(
'test_aaa'))
suite.addTest(test_cases_01(
'test_bbb'))
suite.addTest(test_cases_01(
'test_ddd'))
suite.addTest(test_cases_01(
'test_fff'))
unittest.main(
defaultTest='suite')

构建测试套件

在实际项目中,随着项目进度的开展,测试类会越来越多,可是直到现在我们还只会一个一个单独运行测试类,这在实际项目实践中肯定是不可行的,在unittest中可以通过测试套件来解决该问题。

测试套件(Test Suits)是由多个测试用例(Test Case)组成的,当然也可以由多个子套件组成。

在unittest中,把测试用例加载到测试套件的方法由如下方法:

方法一:

用unittest.TestSuite()实例化测试套件对象后,内部的addTest() 方法对测试类颞部的测试案例逐一添加:

if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTest(test_cases_01(
'test_ccc')) # 增加单个测试用例
suite.addTest(test_cases_01(
'test_aaa'))
unittest.main(
defaultTest='suite')

方式二:

Unitttest提供一个TestLoader类用于自动创建一个测试集并把单个测试放入到测试集中。TestLoader自动运行以test开头的测试方法。可以通过如下方法加载用例:

if __name__ == '__main__':
# 增加类下的所有用例
suite01 = unittest.TestLoader().loadTestsFromTestCase('TestCase02')
# 增加模块下所有用例
suite02 = unittest.TestLoader().loadTestsFromModule('test_case_02')
suite02.run()

在导入类及模块下的测试用例之前,如果用例实在其它模块,需要先进行import导入操作。

方式三:

用unittest.TestSuite()实例化测试套件对象后,内部的addTests()方法可以把多个子测试集合进行整合到一个大的测试集合中

if __name__ == '__main__':
allsuite = unittest.TestSuite()
# 增加单个测试用例
testsuite01 = unittest.TestSuite()
testsuite01.addTest(
'test_dddd')
testsuite01.addTest(
'test_eee')
testsuite02 = unittest.TestLoader().loadTestsFromModule(
'TestCases03') # 增加模块下的所有用例?
allsuite.addTests(testsuite01) # 把testsuite01集合的用例加载到allsuite测试集合
allsuite.addTests(testsuite02) # 把testsuite02 集合的用例加载到allsuite测试集合
unittest.main(defaultTest='allsuite')

方式四:

当测试用例存放在多个不同目录下,我们能用之气那把用例加载到测试集合中的方式是不太方便,需要不断去导入和添加用例模块,如此可以通过discover()方法实现,实现如下:

Discover(start_dir,pattern = ‘test*.py’,top_level_dir = None)

Start_dir : 要测试的模块名或测试用例目录;

Pattern=’test*.py’ :表示用例文件名的匹配原子,例子中匹配文件名以“test”开头的“.py”文件,星号“*”表示任意多个字符。

Top_level_dir=None :测试模块的顶层目录,如果没有顶层目录,默认是None。

该方法通过从指定的开始目录递归到子目录中查找所有测试模块,并返回包含它们的TestSuite对象,只要与模式匹配测试文件和可导入的模块名称才会被加载。

如果一个测试文件的名称符合pattern,会自动查找该文件中派生自TestCase的类包含的test开头的方法作为测试方法。

代码示例:


import unittest,os
case_path = os.path.join(os.path.dirname(__file__))
print(case_path)
def get_all_cases():
discover = unittest.defaultTestLoader.discover(case_path,
pattern='test*.py',top_level_dir=None) # 加载不同模块下的用例
suit = unittest.TestSuite()
suit.addTest(discover)
return suit
if __name__ == '__main__':
suite = unittest.TestSuite()
suite = get_all_cases()
unittest.main(
defaultTest='suite')

Unittest 生成测试报告

测试报告为测试结果的统计即展示,是自动化测试不可或缺的一部分,利用unittest生成测试报告方式如下:

方式一:

用unittest.main()执行测试集

if __name__ == '__main__':
suite = unittest.TestSuite()
unittest.main()
# 执行当前模块下所有类的测试用例
unittest.main(verbosity=2) # 执行当前模块下所有类的测试用例
unittest.main(defaultTest='suite') # 执行suite测试集合下所有的测试用例

这里的verbosity是一个选项,表示测试结果的信息复杂度,有三个值:

0 (静默模式) :你只能获得总的测试用例数和总的结果,比如100个,失败20个,成功80个

1 (默认模式) :非常类似静默模式,只是再每个成功的用力前面有个“.”,每个失败的用例前面有个“F”。

2 (详细模式) :测试结果会显示每个测试用例的所有相关的信息

方式二:

使用TextTestRunner 执行测试用例集,TextTestRunner有三个参数,它们都哦有静默参数:

  1. Verbosity 分别三个级别:0,1,2它们输出的测试报告详细程度不同,2 最详细
  2. Stream 关系着测试报告的位置,如果默认为None的话,测试报告会输出到控制台
  3. descriptions 测试报告的描述

mport unittest,os
case_path = os.path.join(os.path.dirname(__file__))
print(case_path)
def get_all_cases():
discover = unittest.defaultTestLoader.discover(case_path,
pattern='test*.py',top_level_dir=None) # 加载不同模块下的用例
suit = unittest.TestSuite()
suit.addTest(discover)
return suit
if __name__ == '__main__':
# 方式一:
# suite = unittest.TestSuite()
# suite = get_all_cases()
# unittest.main(defaultTest='suite')
# 方式二:
# suite = unittest.TestSuite()
# unittest.main() # 执行当前模块下所有类的测试用例
# unittest.main(verbosity=2) # 执行当前模块下所有类的测试用例
# unittest.main(defaultTest='suite') # 执行suite测试集合下所有的测试用例
# 方式三:
from sample.test_02.test_cases_01 import test_cases_01
suite = unittest.TestSuite()
suite = get_all_cases()
test_runner = unittest.TextTestRunner(
stream=None,descriptions=None,verbosity=2)
test_runner = unittest.TextTestRunner(
stream=None,descriptions=None,verbosity=0)
with open('test_result.txt','w',encoding='utf-8') as file:
runner = unittest.TextTestRunner(
stream=file, descriptions='执行用例的测试报告', verbosity=2)
runner.run(suite)

生成的txt报告:

方式三:

使用第三方HTMLRunner 执行用例集,它可以输出网页版本测试报告

HTMLTestRunner 是Python标准库的unittest模块的一个扩展,在使用该模块之前要下载HTMLTestRunner.py文件,并将该文件保存在python安装路径下的lib文件夹或者是项目的子包中,在python代码中通过import HTMLTestRunner导入,即可使用。

import unittest,os
case_path = os.path.join(os.path.dirname(__file__))
print(case_path)
def get_all_cases():
discover = unittest.defaultTestLoader.discover(case_path,
pattern='test*.py',top_level_dir=None) # 加载不同模块下的用例
suit = unittest.TestSuite()
suit.addTest(discover)
return suit

if __name__ == '__main__':
import HTMLTestRunner
suite = unittest.TestSuite()
suite = get_all_cases()
html_obj =
open('result.html','w+',encoding='utf-8') # 创建
runner = HTMLTestRunner.HTMLTestRunner(stream=html_obj,
title='测试报告',
description='测试报告')
runner.run(suite)

HTMLTestRunner常用参数:

stream : 配置测试报告要保存的文件路径

title : 测试报告标题

description : 测试报告的描述信息

生成的简易的html报告:

测试用例信息在报告中显示:

一:在测试用例中加上注释西悉尼,即可在html报告中体现,能更好的展示每个用例的信息。

import unittest,os
class TestCases03(unittest.TestCase):
'''测试类的详细信息'''
def setUp(self) -> None:
print('setUp')
def tearDown(self) -> None:
print('tearDown')
def test_aaa(self):
'''测试用例test_aaa的详细信息'''
print('execute test_aaa')
self.assertEqual(3,3)
def test_ccc(self):
'''测试用例test_ccc的详细信息'''
print('execute test_ccc')
self.assertEqual(3,3)
def test_dddd(self):
'''测试用例test_dddd的详细信息'''
print('execute test_ccc')
self.assertEqual(3,3)
def test_eee(self):
'''测试用例test_eee的详细信息'''
print('execute test_eee')
self.assertEqual(3, 3)

测试用例信息在报告中显示:

二:在测试方法中通过:

self._testMethodName = ‘设置测试用例的名称’

self._testMethodDoc = ‘设置测试用例详情’

def test_aaa(self):
'''测试用例test_aaa的详细信息'''
self._testMethodName = 'test_aaa'
self._testMethodDoc = '测试用例test_aaa详细信息'
print('execute test_aaa')
self.assertEqual(3,3)

生成的报告如下图:

方式四:

使用第三方HTMLTest ReportCN 执行测试用例集,它可以输出网页版测试报告。

在使用该模块之前下载HTMLReportCN.py文件,并将该文件保存在python安装路径下的lib文件夹或项目的子包中,在python代码中通过

import HTMLTestReportCN 导入,即可使用。


from sample.test_02.comm import HTMLTestReportCN
suite = unittest.TestSuite()
suite = get_all_cases()
report_dir =
'./html_report/' # 测试报告路径,必须以 / 结尾
report_path_obj = HTMLTestReportCN.ReportDirectory(report_dir) # 创建测试报告路径对象
report_path_obj.create_dir('UI 自动化测试_') # 创建测试报告存放目录
html_path = HTMLTestReportCN.GlobalMsg.get_value('report_path') # 获取测试报告文件对象
html_file = open(html_path,'wb') # 创建html测试报告
html_runner = HTMLTestReportCN.HTMLTestRunner(stream=html_file,
title='UI 测试报告',
tester='YangShiYu',
description='20221013')
html_runner.run(suite)

生成的测试报告展示如下:

相关推荐

火电厂智能管控新基建:全场景人员定位系统架构解析

在能源生产领域,火电厂以庞大的厂区规模、复杂的作业环境和密集的人机交互著称。从高温高压的锅炉房到精密复杂的电气设备间,从露天煤场到灰渣处理区,传统管理模式下的人员定位盲区,正成为制约安全生产与高效运营...

安全仪表系统(SIS)全生命周期管理:从设计到运维的深度解析

以下是一篇关于安全仪表系统(SIS)的技术解析与实践方法,涵盖系统架构、设计标准、实施流程及行业应用。安全仪表系统(SIS)是工业过程安全的最后一道防线,通过独立于基础控制系统的硬件和逻辑,在工艺失控...

数字化转型架构下的数据安全治理方案

这份PPT文件内容围绕数字化转型架构下的数据安全治理方案展开,主要探讨了数据质量治理、安全治理、全生命周期治理以及治理考核等方面的内容。更多参考及文档获取详见公众号:优享智库数据治理概述定义与目标:数...

安全完整性等级(SIL)分析报告编制与认证实践方法

以下是一篇关于安全完整性等级(SIL)分析报告的文章,涵盖SIL定级方法、验证流程、计算模型及工程实践。安全完整性等级(SIL)是量化安全仪表系统(SIS)性能的核心指标,由IEC61508/615...

项目管理体系框架(项目的管理体系)

Pokemon go下载教程 口袋妖怪Go下载解锁方法

#p#安卓下载#e#Pokemongo怎么下载?口袋妖怪go下载教程讲解。虽然锁区了但是大家还是有办法的,首先是口袋妖怪Go下载问题,很多口袋妖怪go的安卓玩家不知道怎么下载游戏,小编给大家详细解答...

抛弃Windows吧!谷歌推免费Chrome系统,一个U盘就搞定

在目前的个人电脑上,最主流的系统当然是Windows,不过除了Windows之外,我们也可以选择购买苹果的电脑,使用苹果的MacOS系统。不过除了苹果和微软的系统之外,实际上谷歌也有自己用于个人电脑...

谷歌误发ARM版Chrome安装包,致英特尔 /AMD用户无法安装

IT之家3月26日消息,科技媒体WindowsLatest昨日(3月25日)发布博文,报道称由于谷歌误发适用于ARM架构的安装包,导致用户从谷歌官网下载的ChromeSetu...

【Google Gemini极简教程】使用Flask和Gemini API构建一个AI BaaS

BaaS(BackendasaService,后端即服务)BaaS是一种云服务模型,它为开发者提供了一种便捷的方式来构建和管理应用程序的后端服务。BaaS提供了一系列的后端功能,如数据库管理...

第一资讯Windows 10 Mobile已成功安装谷歌Play Store

虽然微软并未正式推出WP可安装APK的功能,但近期有不少玩机爱好者已经在Windows10Mobile平台上用上了Android应用,而且随后还在需要谷歌服务框架(GoogleServices)...

宝可梦TCG Pocket谷歌账号登录,给你提供指南

《宝可梦TCGPocket》作为一款备受欢迎的卡牌对战游戏,为了给玩家提供更加便捷和安全的登录方式,支持使用谷歌账号进行登录。通过谷歌账号登录,您不仅可以快速进入游戏,还能享受账号数据同步、跨设备游...

秒变万能家庭服务器!斐讯N1 armbian安装指南

一直以来,我都想配置一台小型服务器放在家里玩一玩,但是x86架构的主机体积大功耗高,价格也不低。而树莓派的话,价格便宜一点,性能对于轻度使用也基本够用。可是树莓派仍然要两三百块钱,感觉还是有点贵。于是...

如何自己开发一个Google浏览器插件?

相信很多人都好奇,谷歌浏览器那么多的插件是如何开发的,我们如何开发一个自定义的Google浏览器插件,下面我们就来详细的给出一个开发Google浏览器插件的流程。准备环境首先需要有一个文本编辑器工具如...

我的世界手机版谷歌商店安装教程(我的世界谷歌下载)

在我的世界手机版升级到0.11.0版本后,很多玩家发现正式版需要有谷歌商店的验证也就是必须安装Googleplay才能玩。这次搞趣网小编就为大家带来我的世界手机版谷歌商店安装教程。有些手机自带Goo...

部落冲突安卓版谷歌怎么绑定 有无root都可以

部落冲突安卓版谷歌怎么绑定?下面小编为大家带来部落冲突安卓版谷歌绑定攻略详解,希望这篇攻略详解能够对大家有所帮助。首先准备这些东西(必须在网上自己下载,不要相信google应用)还需要下载"谷歌服务框...

取消回复欢迎 发表评论: