工作原理:
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)

准备环境、清理环境:

test fixture之setUp() 和tearDown()

这两个方法在每个测试方法执行前以及执行后执行一次

修改测试用例文件

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

用例结果断言:

assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)
assertAlmostEqual(a, b) round(a-b, 7) == 0
assertNotAlmostEqual(a, b) round(a-b, 7) != 0
assertGreater(a, b) a > b
assertGreaterEqual(a, b) a >= b
assertLess(a, b) a < b
assertLessEqual(a, b) a <= b
assertRegexpMatches(s, r) r.search(s)
assertNotRegexpMatches(s, r) not r.search(s)
assertItemsEqual(a, b) sorted(a) == sorted(b) and works with unhashable objs
 
   
'''
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

 
 
 
 
 
 

最新文章

  1. powershell
  2. SQL Server中Text和varchar(max)数据类型区别
  3. Python入门3
  4. HTML学习体会
  5. linux win 通用的获取Mac的方法
  6. java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
  7. android开发 如何调用SO
  8. iOS开发 multipart 上传多张图片
  9. ABAP中Conversion Routine示例
  10. windows 通过ssh连接到Linux主机
  11. POJ3352 Road Construction(边双连通分量)
  12. 介绍Google App Engine
  13. 51单片机或PLC驱动3.5寸至52寸的数字TFTLCD屏、VGA接口显示器、电视机
  14. js 的数据类型转换
  15. guava function and predicate 函数式编程
  16. mac 环境下使用virtual box 虚拟机(win7)与主机之间互相ping通
  17. UIView类绘图出现错误提示
  18. ios 监听TextField中内容
  19. python-opencv aplpha混合
  20. HDU 1014 Uniform Generator 欧几里得

热门文章

  1. js获取浏览器上一访问页面URL地址,document.referrer方法
  2. latex 字母上面加符号
  3. 转:system.Security.Cryptography C# 加密和解密
  4. iOS:URL Scheme(完结)(18-1-3更)
  5. chromium之ScopedNSAutoreleasePool浅析
  6. MYSQL命令简要笔记
  7. 扩展运算符及其在vuex的辅助函数里的应用详解
  8. vue 图片压缩 基于cli3 配置
  9. 【JVM】上帝视角看JVM内存模型,分而治之论各模块详情
  10. 【Spark】Spark性能优化之Whole-stage code generation