单元测试模块unittest使用学习
unittest中最核心的四个概念是:test case, test suite, test runner, test fixture。 一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),
执行测试代码(run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。 而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。 TestLoader是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。 TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。 而对一个测试用例环境的搭建和销毁,是一个fixture。
三个模块:
1、程序或基础类:
def add(a, b):
return a+b def minus(a, b):
return a-b def multi(a, b):
return a*b def divide(a, b):
return a/b
2、测试用例
class TestMathFunc(unittest.TestCase):# 一个class继承了unittest.TestCase,便是一个测试用例,但如果其中有多个以 test 开头的方法,那么每有一个这样的方法,在load的时候便会生成一个TestCase实例 def test_add(self): # 每个测试方法都需要以test开头,否则是不会被unittest识别到
"""Test method add(a, b)"""
self.assertEqual(3, add(1, 2)) # 判断相等
self.assertNotEqual(3, add(2, 2)) # 判断不相等
def test_minus(self):
"""Test method minus(a, b)"""
self.assertEqual(1, minus(3, 2)) def test_multi(self):
"""Test method multi(a, b)"""
self.assertEqual(6, multi(2, 3)) def test_divide(self):
"""Test method divide(a, b)"""
self.assertEqual(2, divide(6, 3))
self.assertEqual(2.5, divide(5, 2)) if __name__ == '__main__':
unittest.main() #main传参控制报告详细程度 verbosity = ,默认是1,不输出每一条测试用例的结果是0,输出详细的测试用例执行结果是2
3、执行测试
import unittest
from test_mathfunc import TestMathFunc #传入测试用例, if __name__=='__main__':
suite = unittest.TestSuite() #按指定顺序执行
tests = [TestMathFunc("test_add"),TestMathFunc("test_minus"),TestMathFunc('test_divide')]
suite.addTests(tests) # 直接用addTest方法添加单个TestCase
# suite.addTest(TestMathFunc("test_multi")) # 用addTests + TestLoader
# loadTestsFromName(),传入'模块名.TestCase名'
# suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfunc.TestMathFunc'))
# suite.addTests(unittest.TestLoader().loadTestsFromNames(['test_mathfunc.TestMathFunc'])) # loadTestsFromNames(),类似,传入列表 # loadTestsFromTestCase(),传入类TestCase
# suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc)) runner = unittest.TextTestRunner(verbosity=2) #测试结果展示内容
runner.run(suite) #执行测试
测试用例的保存:
修改执行测试文件: import unittest
from test_mathfunc import TestMathFunc if __name__=='__main__':
suite = unittest.TestSuite() # tests = [TestMathFunc("test_add"),TestMathFunc("test_minus"),TestMathFunc('test_divide')]
# suite.addTests(tests) # 直接用addTest方法添加单个TestCase
# suite.addTest(TestMathFunc("test_multi")) # 用addTests + TestLoader
# loadTestsFromName(),传入'模块名.TestCase名'
# suite.addTests(unittest.TestLoader().loadTestsFromName('test_mathfunc.TestMathFunc'))
# suite.addTests(unittest.TestLoader().loadTestsFromNames(['test_mathfunc.TestMathFunc'])) # loadTestsFromNames(),类似,传入列表 # loadTestsFromTestCase(),传入leiTestCase
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc)) with open('test_Report.txt','a') as f: #打开要保存结果的文件
runner = unittest.TextTestRunner(stream=f,verbosity=2)#stream 写入内容
runner.run(suite)
准备环境、清理环境:
这两个方法在每个测试方法执行前以及执行后执行一次
修改测试用例文件 import unittest
from mathfunc import * class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py""" def setUp(self): #setUp用来为测试准备环境
print "do something before test.Prepare environment." def tearDown(self): #tearDown 用来清理测试环境
print "do something after test.Clean up." def test_add(self):
"""Test method add(a, b)"""
print "add"
self.assertEqual(3, add(1, 2))
self.assertNotEqual(3, add(2, 2)) def test_minus(self):
"""Test method minus(a, b)"""
print "minus"
self.assertEqual(1, minus(3, 2)) def test_multi(self):
"""Test method multi(a, b)"""
print "multi"
self.assertEqual(6, multi(2, 3)) def test_divide(self):
"""Test method divide(a, b)"""
print "divide"
self.assertEqual(2, divide(6, 3))
self.assertEqual(2.5, divide(5, 2))
如果想要在所有case执行之前准备一次环境,并在所有case执行结束之后再清理环境,我们可以用 setUpClass()
与 tearDownClass()
:
class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py""" @classmethod
def setUpClass(cls): #执行测试前运行
print ("This setUpClass() method only called once.")
@classmethod
def tearDownClass(cls): #所有测试用例执行完毕后运行
print ("This tearDownClass() method only called once too.") def test_add(self):
"""Test method add(a, b)"""
print ("add")
self.assertEqual(3, add(1, 2))
self.assertNotEqual(3, add(2, 2))
跳过当前用例:
1.skip装饰器:
class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py""" ... @unittest.skip("I don't want to run this case.")
def test_divide(self):
"""Test method divide(a, b)"""
print "divide"
self.assertEqual(2, divide(6, 3))
self.assertEqual(2.5, divide(5, 2))
unittet可以分无条件忽略和有条件忽略,通过装饰器实现
@unittest.skip(reason): skip(reason)装饰器:无条件跳过装饰的测试,并说明跳过测试的原因。
@unittest.skipIf(reason): skipIf(condition,reason)装饰器:条件为真时,跳过装饰的测试,并说明跳过测试的原因。
@unittest.skipUnless(reason): skipUnless(condition,reason)装饰器:条件为假时,跳过装饰的测试,并说明跳过测试的原因。
@unittest.expectedFailure(): expectedFailure()测试标记为失败。
@self.skipTest :函数体内使用,
class MyTestCase(unittest.TestCase):
@unittest.skip("demonstrating skipping")
def test_nothing(self):
self.fail("shouldn't happen")
@unittest.skipIf(mylib.__version__ < (1, 3),
"not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
# windows specific testing code
pass
@unittest.expectedFailure()
def test_windows_support(self):
# windows specific testing code
pass
def test_divide(self):
"""Test method divide(a, b)"""
self.skipTest('Do not run this.')
print "divide"
self.assertEqual(2, divide(6, 3))
self.assertEqual(2.5, divide(5, 2))
忽略测试类:
@unittest.skip("showing class skipping")
class MySkippedTestCase(unittest.TestCase):
def test_not_run(self):
pass
用例结果断言:
|
|||||||||||||||||||||||||||||||||||||||||||
'''
unittest条件断言
tester: cc
此文仅做翻译只用,不介绍具体使用 '''
Skiptest() # 在测试中引发此异常以跳过该异常。
_ShouldStop() # 停止测试
_UnexpectedSuccess() # 测试本来应该是失败的,但是没有失败
Skip() # 无条件跳过测试。
skipIf(condition, reason) # 条件为真时跳过测试
skipUnless(condition, reason) # 条件为假时跳过测试
expectedFailure(test_item) # 标记该测试预期就是失败,如果运行失败时,不算作失败用例。
_is_subtype(expected, basetype) # 判断类型是否符合预期,暂时不知道干什么用的
addTypeEqualityFunc(typeobj, function) # 为自定义检查类提供检查方法
addCleanup( function , *args , **kwargs ) #添加针对每个测试用例执行完tearDown()方法之后的清理方法,添加进去的函数按照后进先出(LIFO)的顺序执行,当然,如果setUp()方法执行失败,那么不会执行tearDown()方法,自然也不会执行addCleanup()里添加的函数。
setUp()#在执行每个测试用例之前被执行,任何异常(除了unittest.SkipTest和AssertionError异常以外)都会当做是error而不是failure,且会终止当前测试用例的执行。
tearDown()#执行了setUp()方法后,不论测试用例执行是否成功,都执行tearDown()方法。如果tearDown()的代码有异常(除了unittest.SkipTest和AssertionError异常以外),会多算一个error。
setUpClass( cls )与tearDownClass( cls )#测试用例们被执行前、后执行的方法,定义时必须加上classmethod装饰符
countTestCases()#返回测试用例的个数,对于TestCase实例来说,这个返回值一直是1.
defaultTestResult()#如果在run()方法中未提供result参数,该函数返回一个包含本用例测试结果的TestResult对象。
shortDescription()#返回测试用例的描述,即函数的docstring,如果没有,返回None。可以用于测试结果输出中描述测试内容。
id()#返回测试用例的编号,通常是如下格式:模块名.类名.函数名。可以用于测试结果的输出。
subTest( msg=_subtest_msg_sentinel, **params)#返回一个上下文管理器,它将返回由可选消息和关键字参数标识的子测试中的封闭代码块。子测试中的失败标志着测试用例失败,但在封闭块结束时恢复执行,允许执行进一步的测试代码。
run( result =None)#运行一个测试用例,将测试结果收集到result变量中,测试结果不返回给调用者。如果result参数的值为None,则测试结果在下面提到的defaultTestResult()方法的返回值中
doCleanups()#无条件强制调用addCleanup()添加的函数,适用于setUp()方法执行失败但是需要执行清理函数的场景,或者希望在tearDown()方法之前执行这些清理函数。
debug()#与run方法将测试结果存储到result变量中不同,debug方法运行测试用例将异常信息上报给调用者。
fail( msg =None)#无条件声明一个测试用例失败,msg是失败信息。
assertFalse( expr, msg=None) #检查表达式是否为假
assertTrue( expr, msg=None) #检查表达式是否为真
assertAlmostEqual与assertNotAlmostEqual(, first, second, places=None, msg=None,delta=None) #判断两个值是否约等于或者不约等于,places表示小数点后精确的位数
assertSequenceEqual(seq1, seq2, msg=None, seq_type=None) #有序序列的相等断言,如元组、列表
assertListEqual( list1, list2, msg=None) #列表相等的特定断言
assertTupleEqual(tuple1, tuple2, msg=None) #元组相等的特定断言
assertSetEqual( set1, set2, msg=None) #集合相等的特定断言
assertIn与assertNotIn( member, container, msg=None) #判断a 是否存在b中
assertIs与assertIsNot( expr1, expr2, msg=None) #判断a是不是b
assertDictEqual( d1, d2, msg=None) #检查两个字典是否相等
assertDictContainsSubset( subset, dictionary, msg=None) #检查字典是否是子集的超集。
assertCountEqual(first, second, msg=None) #判断两个无序列表内所出现的内容是否相等
assertMultiLineEqual( first, second, msg=None) #断言两个多行字符串相等
assertLess( a, b, msg=None) #断言a<b
assertLessEqual( a, b, msg=None) #断言a<=b
assertGreater( a, b, msg=None) #断言a>b
assertGreaterEqual(a, b, msg=None) #断言a>=b
assertIsNone与assertIsNotNone( obj, msg=None) #判断obj是否为空
assertIsInstance(a, b)与assertNotIsInstance(a, b)# 与assertTrue相同,其中的类型b,既可以是一个类型,也可以是类型组成的元组。
assertRaisesRegex( expected_exception, expected_regex,*args, **kwargs)#断言在引发异常中的消息与正则表达式匹配。
assertWarnsRegex( expected_warning, expected_regex,*args, **kwargs)#断言触发警告中的消息与ReGEXP匹配。基本功能类似于AdvestWr.NS.()只有消息与正则表达式匹配的警告。被认为是成功的匹配
assertRegex与assertNotRegex(text, expected_regex, msg=None) #判断文本与正则表达式是否匹配
shortDescription()#返回测试用例的描述,即函数的docstring,如果没有,返回None。可以用于测试结果输出中描述测试内容。
输出测试HTML报告 :HTMLTestRunner
修改执行测试文件:
# -*- coding: utf-8 -*- import unittest
from test_mathfunc import TestMathFunc
from HTMLTestRunner import HTMLTestRunner #引入HTMLtestrunner if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc)) # 执行testmathfunc with open('HTMLReport.html', 'w') as f:
runner = HTMLTestRunner(stream=f, #写入HTML文件
title='MathFunc Test Report', #运行状况
description='generated by HTMLTestRunner.', #执行结果
verbosity=2
)
runner.run(suite)
另一种输出方式:
# -*- coding: utf-8 -*-
import unittest,time
from HTMLTestRunner import HTMLTestRunner
from email.mime.text import MIMEText
from email.header import Header
import smtplib
test_dir='./test_jb/' #目录路径
discover=unittest.defaultTestLoader.discover(test_dir,pattern='test_*.py') #查找当前目录下的所有以test_开头的文件,并执行 if __name__=='__main__':
now=time.strftime('%Y-%m-%d %H_%M_%S')#当前日期
filename=test_dir+now+'result.html' #名称后缀
fp=open(filename,'wb') #写入内容
runner=HTMLTestRunner(stream=fp,title='测试报告',description='用例执行情况') #执行测试方式
runner.run(discover)# 执行测试
fp.close() #关闭测试
原文地址:https://blog.csdn.net/huilan_same/article/details/52944782
单元测试模块unittest使用学习的更多相关文章
- Python中的单元测试模块Unittest快速入门
前言 为什么需要单元测试? 如果没有单元测试,我们会遇到这种情况:已有的健康运行的代码在经过改动之后,我们无法得知改动之后是否引入了Bug.如果有单元测试的话,只要单元测试全部通过,我们就可以保证没有 ...
- 三言两语聊Python模块–单元测试模块unittest
实际上unittest模块才是真正意义上的用于测试的模块,功能强大的单元测试模块. 继续使用前面的例子: # splitter.py def split(line, types=None, delim ...
- Python3+Selenium2完整的自动化测试实现之旅(六):Python单元测试模块Unittest运用
一.Unittest单元测试框架简介 Unitest是Python下的一个单元测试模块,是Python标准库模块之一,安装完Python后就可以直接import该模块,能在单元测试下编写具体的测试用例 ...
- python单元测试模块unittest
1.unittest_demo.py # coding=utf-8 import time import unittest from HtmlTestRunner import HTMLTestRun ...
- python中的单元测试模块unittest
unittest的属性: 该文以思维导图的形式描述unittest的重要属性. 其中前四个是unittest最核心的三个属性. testcase:测试用例: testsuite:测试套件,多个测试用例 ...
- Python单元测试框架unittest之深入学习
前言 前几篇文章该要地介绍了python单元测试框架unittest的使用,本篇文章系统介绍unittest框架. 一.unittest核心工作原理 unittest中最核心的四个概念是:test c ...
- Python单元测试框架unittest
学习接口自动化测试时接触了unittest单元测试框架,学习时参照了虫师编写的<selenium2自动化测试实战>,个人觉得里面讲的例子还比较容易理解的. 一.基础 1.main()和框架 ...
- selenium + python自动化测试unittest框架学习(二)
1.unittest单元测试框架文件结构 unittest是python单元测试框架之一,unittest测试框架的主要文件结构: File >report >all_case.py &g ...
- Python单元测试:unittest使用简介
一.概述 本文介绍python的单元测试框架unittest,这是Python自带的标准模块unittest.unittest是基于java中的流行单元测试框架junit设计的,其功能强大且灵活,对于 ...
随机推荐
- 【Git】Git使用小结
Git与SVN及TFS这类传统的版本管理的区别: 本地机器也会有分支.代码库的概念 SVN常用的做法是每次写一些代码就提交到仓库,但是Git是先提交到本地(commit),然后当本地有个稳定的版本的时 ...
- Sharepoint COMException 0x81020037
研究了很久,ListItem在保存的时候一直在出Sharepoint COMException 0x81020037 根据错误提示,是保存的时候发生冲突导致,苦思冥想,终于解决了,原因如下: List ...
- 一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历
一点一点看JDK源码(五)java.util.ArrayList 后篇之Spliterator多线程遍历 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看J ...
- iOS-WebView(WKWebView)进度条
一直以来,就有想通过技术博客来记录总结下自己工作中碰到的问题的想法,这个想法拖了好久今天才开始着手写自己的第一篇技术博客,由于刚开始写,不免会出现不对的地方,希望各位看到的大牛多多指教.好了,不多说了 ...
- Vuex的第一次接触
前言:最近在做Vue实现去哪网,想要实现在城市列表页面,点击某个城市的时候,主页的头部的城市会随着改变,就是首页和城市页面有共用的数据要分享,这里使用Vuex 1. Vuex是什么? 是Vue官方推荐 ...
- Hive的DML操作
1. Load 在将数据加载到表中时,Hive 不会进行任何转换.加载操作是将数据文件移动到与 Hive表对应的位置的纯复制/移动操作. 语法结构: load data [local] inpath ...
- Cmake3.6.1 下载
下载地址:https://github.com/Kitware/CMake/releases?after=v3.6.2
- MapWindow记录
增加MapWinGIS的新功能,编译完MapWinGIS,可以生成Debug和Release版本的x64和Win32四种版本, 自己基于c#的Mapwindow如果要用到新添加的功能,此时就得重新注册 ...
- Git中分支merge和rebase的适用场景及区别
Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 原理 如下: 假设你现在基于远程分 ...
- silverlight 图形报表开发
前端: <UserControl x:Class="SLThree.CharReport" xmlns="http://schemas.microsoft.com/ ...