unittest用法


unittest 是python的单元测试框架,类似 java的 junit ,TestNG ,用法简单,可用做单元测试。

1. unittest 的简单用法

unittest提供了test cases、test suites、test fixtures、test runner相关的类,让测试更加明确、方便、可控。使用unittest编写用例,必须遵守以下规则:

1.测试文件必须先import unittest

2.测试类必须继承unittest.TestCase

3.测试方法必须以“test_”开头,python的文件名也最好以test开头

4.测试类必须要有unittest.main()方法

下面简述下unittest的用法:


运行后可以看到运行结果,通过和失败的用例。

unittest也支持命令行的方式运行,

python -m unittest test_module1 test_module2

python -m unittest test_module.TestClass

python -m unittest test_module.TestClass.test_method

cd 到该文件目录下,然后输入 >python -m unittest test_Demo01

以下简要说明下unittest命令行的 常用参数,更多的可查看官方文档 https://docs.python.org/zh-cn/3/library/unittest.html#command-line-interface

-f, --failfast         #当出现第一个错误或者失败时,停止运行测试。

-v, --verbose      #更详细地输出结果。

-p, --pattern pattern      #用于匹配测试文件的模式(默认为 test*.py ),这种格式的文件找出来执行

-t, --top-level-directory directory    #指定项目的最上层目录(通常为开始时所在目录)


2. setUp ,tearDown 和执行顺序

unittest自带hook方法,setUp 和tearDwon ,setUpClass 和 tearDwonClass,可以理解成java 的构建函数和析构函数。setUpClass和tearDownClass 方法必须加 @classmethod 装饰器 。

运行结果如下,输出结果可以看出unittest的执行顺序,测试用例会按照字符顺序执行,如test_01 ,先于test_02:

但值得注意的是 unittest 有一个bug ,比如上面的例子,不做任何修改,多跑几次,随机会出现下面的通过(概率较低)

3. 断言

1. unittest的断言常用的有 assertEqual ,assertNotEqual  ,assertTrue,assertFalse  ,assertIn , ,assertNotIn ,assertIsNone ,assertIsNotNone等

2. 自定义断言信息 。以assertEqual 为例 , 默认为assertEqual(self, first, second, msg=None) ,可以自定义在两个数不相等的时候输出的信息assertEqual(self, first, second, msg="Not Equal")

4.跳过测试用例的方法

在执行用例的时候,并不需要每次都全部跑一次,unittest提供了跳过某些用例不执行的方法

@unittest.skip("don't run this case!"): 跳过执行

@unittest.skipIf(3<2,"don't run this case!"):跳过此用例如果

@unittest.skipUnless(3>2,"don't run this case!"): 跳过此用例,除非,例如

5. 用例加载和执行

unittest.main():使用她可以方便的将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以“test”命名开头的测试方法,并自动执行他们。执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。

unittest.TestSuite():unittest框架的TestSuite()类是用来创建测试套件的。

unittest.TextTextRunner():unittest框架的TextTextRunner()类,通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。

unittest.defaultTestLoader(): defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover。用法如下:

discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')




如果一个项目有很多的测试方法,多个文件目录


如何执行上面的用例 ?

1. 可以按照上面的方法,把各个文件的测试类加入到 unittest.TestSuite中,然后运行

(注意:一个py文件中可能有多个测试类,不同类有多个test方法)

2. discover 方法

1.discover 方法里面有三个参数:

--case_dir:这个是待执行用例的目录。

--pattern:这个是匹配脚本名称的规则,test*.py 意思是匹配 test 开头的所有脚本。

--top_level_dir:这个是顶层目录的名称,一般默认等于 None 就行了。

2.discover 加载到的用例是一个 list 集合,需要重新写入到一个 list 对象 testcase 里,

这样就可以用 unittest 里面的 TextTestRunner 这里类的 run 方法去执行。

上图中的 "." 是 case_dir  pattern="*.py" 指后缀为py的文件都执行,通常用 "test*.py"  ,top_level_dir=None默认为None

6.数据驱动ddt,参数化

下面是每个组件的简单介绍:

ddt.ddt:装饰类,用于unittest.TestCase子类的类装饰器。

ddt.data:添加到unittest.TestCase测试用例上的方法装饰器。

ddt.file_data(value):添加到unittest.TestCase测试用例上的方法装饰器。value应该是文件目录的路径。文件应该包含JSON编码的数据,可以是列表,也可以是dict。

如果文件中是列表,每个列表的值会作为测试用例参数,同时作为测试用例方法名后缀显示。

如果文件中是字典,字典的key会作为测试用例方法的后缀显示,字典的值会作为测试用例参数。

ddt.unpack:

传递的是复杂的数据结构时使用。比如使用元组或者列表,添加unpack之后,ddt会自动把元组或者列表对应到多个参数上。


参数化数据放在yml 或json 文件中,与代码分离。如在当前目录下新建一个ddt_file.json ,里面输入数据


如图,这里新建了2条用例,均有用例名称 每个json的值里面是参数化的数据

代码修改如下:

再跑一次,此时可以看到跑的用例数和参数化的数据一致


另外一种参数化方法 (参考网上例子的)


7. 测试报告

批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成 HTML 格式的。

unittest 里面是不能生成 html 格式报告的,需要导入一个第三方的模块:HTMLTestRunner

1. 这 个 模 块 下 载 不 能 通 过 pip 安装了,只能下载后手动导入,下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

下载后解压到项目下,如果放入到项目目录下import 时候找不到 ,可以在 python安装目录\lib  下面放一份,如在F:\python3.5.2\Lib\HTMLTestRunner_PY3

在run_all_case.py 

HTMLTestRunner的参数说明如下:

--stream:测试报告写入文件的存储区域

--title:测试报告的主题

--description:测试报告的描述

查看报告详情

生成的report.html 用浏览器打开查看


失败的用例点击【失败】可以查看失败的详情


2.为了生成带中文描述的测试用例,可以在 case 中添加注释,如在脚本添加如下注释:


重新跑一次测试用例,即可看到中文注释

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,548评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,497评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,990评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,618评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,618评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,246评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,819评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,725评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,268评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,356评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,488评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,181评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,862评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,331评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,445评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,897评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,500评论 2 359

推荐阅读更多精彩内容