python之单元测试框架—unittest(补充)
一. unittest最核心的四个概念
unittest中最核心的四个概念是:test case,test suite,test runner,test fixture

TestCase:一个testcase的实例就是一个测试用例:测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)
TestSuite:多个测试用例集合在一起
TestLoader:是用来加载TestCase到TestSuite中的
TextTestRunner:用来执行测试用例的。其中的run(test)会执行TestSuite/TestCase中的run(result)方法
TextTestResult:保存TextTestRunner执行的测试结果
fixture:测试用例环境的搭建和销毁(setUp/setUpClass,tearDown/tearDownClass)
二. unittest初级使用
1. 导入unittest模块、被测文件或者其中的类
2. 创建一个测试类,并继承unittest.TestCase
3. 重写setUp和tearDown方法(如果有初始化条件和结束条件)
4. 定义测试函数,函数以test_开头
5. 在函数体中使用断言来判断测试结果是否符合预期结果
6. 调用unittest.main()方法来运行测试用例
实例
1. 在工程下创建一个My_UnitTest的包,在这个包下面,创建一个被测对象myClass.py和一个测试用例Test_Myclass.py

2. 如果要测试数学中的加法和减法,测试对象myClass.py的内容为
class Math:
def add(self, a, b):
return a + b
def minus(self, a, b):
return a - b
3. 在测试用例中引入unittest,被测文件中的类,注意测试用例是以test_开头
import unittest
from revise.My_UnitTest.myClass import Math
class Test_MyClass(unittest.TestCase):
def setUp(self):
self.m = Math()
def tearDown(self):
pass
def test_add(self):
result = self.m.add(100, 23)
self.assertEqual(123, result)
#减法
def test_minus(self):
result = self.m.minus(235, 111)
self.assertEqual(124, result)
4. 测试用例的执行顺序是以字母a-z和数字的从小到大的顺序来排列的,所以上述两个测试用例执行的顺序是add在前,minus再后,可以改改代码验证一下:
import unittest
from revise.My_UnitTest.myClass import Math
class Test_MyClass(unittest.TestCase):
def setUp(self):
self.m = Math()
def tearDown(self):
pass
def test_add(self):
result = self.m.add(100, 23)
print("我先执行")
self.assertEqual(123, result)
#减法
def test_minus(self):
result = self.m.minus(235, 111)
print("我后执行")
self.assertEqual(124, result)
运行结果:
Testing started at 12:36 ... D:\Program\python34\python.exe "D:\Program\PyCharm 2018.1.4\helpers\pycharm\_jb_unittest_runner.py" --path D:/python_workshop/python6/revise/My_UnitTest/Test_Myclass.py Launching unittests with arguments python -m unittest D:/python_workshop/python6/revise/My_UnitTest/Test_Myclass.py in D:\python_workshop\python6\revise\My_UnitTest 我先执行 我后执行 Ran 2 tests in 0.001s OK
如果希望minus先执行,add后执行,可以给前者函数名加一个1,后者加一个2
def test_2_add(self):
result = self.m.add(100, 23)
print("我后执行")
self.assertEqual(123, result)
#减法
def test_1_minus(self):
result = self.m.minus(235, 111)
print("我先执行")
self.assertEqual(124, result)
5. 如果在setUp里实例化被测文件中的类,那么每一条测试用例都要实例化一次被测类,用setUpClass()可以只实例化一次,同理,tearDownClass也只做一次收尾工作
@classmethod
def setUpClass(cls):
cls.m = Math()
@classmethod
def tearDownClass(cls):
pass
6. 用unittest.main()的方法来运行测试用例Test_Myclass.py
import unittest
from revise.My_UnitTest.myClass import Math
class Test_MyClass(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.m = Math()
@classmethod
def tearDownClass(cls):
pass
def test_2_add(self):
result = self.m.add(100, 23)
print("我后执行")
self.assertEqual(123, result)
#减法
def test_1_minus(self):
result = self.m.minus(235, 111)
print("我先执行")
self.assertEqual(124, result)
if "__name__" == "__main__":
unittest.main()
三. 断言Assert
TestCase类提供了一系列的断言,即结果比对的函数
|
Method |
Checks that |
New in |
|
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 |
3.1 |
|
assertIsNot(a, b) |
a is not b |
3.1 |
|
assertIsNone(x) |
x is None |
3.1 |
|
assertIsNotNone(x) |
x is not None |
3.1 |
|
assertIn(a, b) |
a in b |
3.1 |
|
assertNotIn(a, b) |
a not in b |
3.1 |
|
assertIsInstance(a, b) |
isinstance(a, b) |
3.2 |
|
assertNotIsInstance(a, b) |
not isinstance(a, b) |
3.2 |
四. unittest进阶使用
方式一:类名("方法名")的集合
testsuite:
addTest() 添加一个测试用例
addTests([..]) 添加多个测试用例,addTests的参数是一个测试用例的集合
注意:addTests中执行用例的顺序是按添加的先后顺序进行的,如果这样添加用例可能造成断言失败:
suite.addTests([TestFileOperate("test_00_read_all"),
TestFileOperate("test_01_write_data"),
TestFileOperate("test_03_read_all"),
TestFileOperate("test_02_add_data")])
正确的做法是:
suite.addTests([TestFileOperate("test_00_read_all"),
TestFileOperate("test_01_write_data"),
TestFileOperate("test_02_add_data"),
TestFileOperate("test_03_read_all")])
s = unittest.TestSuite()
s.addTest(testStudent("test_do_homework"))
runner = unittest.TextTestRunner()
runner.run(s)
实例1:addTest的使用
在My_UnitTest包下创建一个main.py

main.py中的代码如下:
import unittest
from revise.My_UnitTest.Test_Myclass import Test_MyClass
#实例化测试套件对象
s = unittest.TestSuite()
#调用addTest来加载测试用例——addTest(类名("用例函数名称"))——添加一个测试用例
s.addTest(Test_MyClass("test_add"))
s.addTest(Test_MyClass("test_minus"))
#使用TextTestRunner来运行测试用例
#实例化
runner = unittest.TextTestRunner()
#用run方法就是用来运行测试用例的
runner.run(s)
运行结果,控制台输出如下:
D:\Program\python34\python.exe D:/python_workshop/python6/revise/My_UnitTest/main.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK
实例2:addTests的使用
import unittest
from revise.My_UnitTest.Test_Myclass import Test_MyClass
#实例化测试套件对象
s = unittest.TestSuite()
#加载多个测试用例——参数为列表——列表当中为测试用例
s.addTests([Test_MyClass("test_add"), Test_MyClass("test_minus")])
#使用TextTestRunner来运行测试用例
#实例化
runner = unittest.TextTestRunner()
#用run方法就是用来运行测试用例的
runner.run(s)
运行结果:
D:\Program\python34\python.exe D:/python_workshop/python6/revise/My_UnitTest/main.py .. ---------------------------------------------------------------------- Ran 2 tests in 0.000s OK
输出测试报告-text-到文件
#创建一个文件,以写的方式打开
fs = open("test_result.txt", "w")
runner = unittest.TextTestRunner(fs)
runner.run(s)
实例3:输出测试报告到文件
import unittest
from revise.My_UnitTest.Test_Myclass import Test_MyClass
#实例化测试套件对象
s = unittest.TestSuite()
#加载多个测试用例——参数为列表——列表当中为测试用例
s.addTests([Test_MyClass("test_add"), Test_MyClass("test_minus")])
#使用TextTestRunner来运行测试用例
#打开一个文件
fs = open("test_run_result.txt", "w")
#实例化
runner = unittest.TextTestRunner(fs)
#用run方法就是用来运行测试用例的
runner.run(s)
运行结果,控制台没有输出,发现当前目录下多了一个文本文件test_run_result.txt

控制台输出的信息写到文本文件中了

方式二:unittest.TestLoader.discover方法匹配目录下的用例
假如现在目录下存在两个测试用例,Test_Myclass.py和Test)_Myclass2.py,如果用addTests的方法添加用例到测试套件,未免有点麻烦,这时候需要使用TestLoader()这个类

代码如下:
import unittest, os #实例化测试套件对象 s = unittest.TestSuite() #1.实例化TestLoader对象 2.使用discover去找到一个目录下的所有测试用例 loader = unittest.TestLoader() #3.使用addTests将找到的测试用例放在测试套件下 s.addTests(loader.discover(os.getcwd())) #运行 runner = unittest.TextTestRunner() runner.run(s)
运行结果:
.... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
注意:源码中discover方法, start_dir是要寻找的目录路径,pattern是查找条件,即在指定的目录下查找以"test"开头的测试用例(事实上,这个查找是不区分大小写的,即Test开头的也能找到)

方式三:unittest.TestLoader.loadTestsFromModule匹配模块中的测试用例
ps:TetLoader类、TestSuite类需要先实例化再使用
五. 美化测试报告—html
python有提供第三方库支持输出的测试报告为html样式
库名:HtmlTestRunner
导入:from HtmlTestRunnerNew import HTMLTestRunner
使用方式:
s = unittest.TestSuite()
s.addTests(测试用例)
fp = open(dir_config.htmlreport_dir + "/API_autoTest_{0}.html".format(curTime), "wb")
runner = HTMLTestRunnerNew.HTMLTestRunner(
stream = fp,
title = "QCD接口测试报告",
description = "QCD接口测试报告",
tester = "xiaozhai"
)
runner.run(s)
代码修改如下:
import unittest, os, time
from HTMLTestRunnerNew import HTMLTestRunner
#实例化测试套件对象
s = unittest.TestSuite()
#1.实例化TestLoader对象 2.使用discover去找到一个目录下的所有测试用例
loader = unittest.TestLoader()
#3.使用addTests将找到的测试用例放在测试套件下
s.addTests(loader.discover(os.getcwd()))
#获取当前时间
curTime = time.strftime("%Y-%m-%d_%H-%M-%S")
#在当前目录下创建一个html文件
fp = open(os.getcwd() + "/autoTest_report_{0}.html".format(curTime), "wb")
#运行测试用例,生成测试报告
runner = HTMLTestRunner(
stream=fp,
title="单元测试报告",
description="Math类的单元测试报告",
tester="xiaozhai"
)
runner.run(s)
运行效果:
D:\Program\python34\python.exe D:/python_workshop/python6/revise/My_UnitTest/main.py ok test_add (Test_Myclass.Test_MyClass) ok test_minus (Test_Myclass.Test_MyClass) ok test_add (Test_Myclass2.Test_MyClass2) ok test_minus (Test_Myclass2.Test_MyClass2) Time Elapsed: 0:00:00.001000 Sun Jul 8 18:17:18 2018 - Start Test:test_add (Test_Myclass.Test_MyClass) Sun Jul 8 18:17:18 2018 - Start Test:test_minus (Test_Myclass.Test_MyClass) Sun Jul 8 18:17:18 2018 - Start Test:test_add (Test_Myclass2.Test_MyClass2) Sun Jul 8 18:17:18 2018 - Start Test:test_minus (Test_Myclass2.Test_MyClass2)


参考文章
https://blog.csdn.net/huilan_same/article/details/52944782
python之单元测试框架—unittest(补充)的更多相关文章
- Appium+python的单元测试框架unittest(1)(转)
unittest为python语言自带的单元测试框架,python把unittest封装为一个标准模块封装在python开发包中.unittest中常用的类有:unittest.TestCase.un ...
- Appium+python的单元测试框架unittest(4)——断言(转)
(原文:https://www.cnblogs.com/fancy0158/p/10051576.html) 在我们编写的测试用例中,测试步骤和预期结果是必不可少的.当我们运行测试用例时,得到一个运行 ...
- python之单元测试框架—unittest
一. 什么是单元测试?单元测试的对象是什么? 1: 什么是单元测试? 按照定义,单元测试就是对单个模块或者单个类或者单个函数进行测试,一般是开发做的,按照阶段分,一般就是单元测试.集成测试.系统测试. ...
- Python之单元测试框架unittest
创建class继承unittest,每一个测试用例是以test开头的函数,先执行setup,然后用例按照字母的顺序执行,然后执行teardown import unittest class demo( ...
- Appium+python的单元测试框架unittest(3)——discover(转)
(原文:https://www.cnblogs.com/fancy0158/p/10047906.html) TestSuite套件可以添加很多个用例后运行,但是每个用例都需要调用addTest()函 ...
- Appium+python的单元测试框架unittest(2)——fixtures(转)
(原文:https://www.cnblogs.com/fancy0158/p/10046333.html) unittest提供的Fixtures用以在测试执行前和执行后进行必要的准备和清理工作,可 ...
- Python单元测试框架unittest之单用例管理(一)
一.概述 本文介绍python的单元测试框架unittest,unittest原名为PyUnit,是由java的JUnit衍生而来,这是Python自带的标准模块unittest.unittest是基 ...
- 单元测试框架unittest
单元测试:单元测试,是指对软件中的最小可测试单元进行检查和验证,对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义如:c语言中单元指一个函数,java里单元指一个类,图形化的软件中可以 ...
- Python单元测试框架unittest使用方法讲解
这篇文章主要介绍了Python单元测试框架unittest使用方法讲解,本文讲解了unittest概述.命令行接口.测试案例自动搜索.创建测试代码.构建测试套件方法等内容,需要的朋友可以参考下 概 ...
随机推荐
- [荐][转]为何应该使用 MacOS X(论GUI环境下开发人员对软件的配置与重用)
一周前我和 Tinyfool 闲聊苹果操作系统,都认为对于开发人员来说,苹果操作系统(MacOS)是上佳的选择.Tinyfool 笔头很快,当即就写了一篇长文章,我则笔头很慢,今天才全部码好.他的文章 ...
- git学习------>写给 Git 初学者的7个建议
PS:本文转载于(http://blog.jobbole.com/50603/),本文由 伯乐在线 - 吴鹏煜 翻译. 英文出处:(http://sixrevisions.com/web-develo ...
- mysql与sql server参照对比学习mysql
mysql与sql server参照对比学习mysql 关键词:mysql语法.mysql基础 转自桦仔系列:http://www.cnblogs.com/lyhabc/p/3691555.html ...
- linux一路填坑...
1.安装ubuntu 从ubuntu9.0开始,一路更新,越来越垃圾,更可恶的是工作上经常指定特定的版本,于是乎,我电脑里装了n个版本的ubuntu. Win7 + Ubuntu 15.10 1)装完 ...
- Nothing is impossible
题记: <你凭什么上北大>--贺舒婷.依稀记得这篇文章是我高二的时候在<青年文摘>读到的,从此她就成了我为之奋斗的动力.北大,也是我梦中的学府,虽然自己也曾刻苦过,但是还是没有 ...
- 详解HTTP中GET与POST的区别,不是你看过的标准答案!
防吐槽声明:本文适合程序员新人,自认阅文无数.技术超叼的大神不用看. GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含 ...
- springmvc 标签
https://www.baeldung.com/spring-mvc-form-tags 1. Overview In the first article of this series we ...
- 3. Longest Substring Without Repeating Characters(最长子串,双指针+hash)
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- 『NiFi 学习之路』入门 —— 下载、安装与简单使用
一.概述 "光说不练假把式." 官网上的介绍多少让人迷迷糊糊的,各种高大上的词语仿佛让 NiFi 离我们越来越远. 实践是最好的老师.那就让我们试用一下 NiFi 吧! 二.安装 ...
- 单例模式及getInstance()的用法
一般在单例模式下使用.getInstance()创建对象:但并不是所有有私有构造方法,对外通过getInstance方法提供 实例的情况就是单例模式. 注:单例模式:一个类有且只有一个实例.1,一个私 ...