一. 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的内容为

  1. class Math:
  2.  
  3. def add(self, a, b):
  4. return a + b
  5.  
  6. def minus(self, a, b):
  7. return a - b

3. 在测试用例中引入unittest,被测文件中的类,注意测试用例是以test_开头

  1. import unittest
  2. from revise.My_UnitTest.myClass import Math
  3.  
  4. class Test_MyClass(unittest.TestCase):
  5.  
  6. def setUp(self):
  7. self.m = Math()
  8.  
  9. def tearDown(self):
  10. pass
  11.  
  12. def test_add(self):
  13. result = self.m.add(100, 23)
  14. self.assertEqual(123, result)
  15.  
  16. #减法
  17. def test_minus(self):
  18. result = self.m.minus(235, 111)
  19. self.assertEqual(124, result)

4. 测试用例的执行顺序是以字母a-z和数字的从小到大的顺序来排列的,所以上述两个测试用例执行的顺序是add在前,minus再后,可以改改代码验证一下:

  1. import unittest
  2. from revise.My_UnitTest.myClass import Math
  3.  
  4. class Test_MyClass(unittest.TestCase):
  5.  
  6. def setUp(self):
  7. self.m = Math()
  8.  
  9. def tearDown(self):
  10. pass
  11.  
  12. def test_add(self):
  13. result = self.m.add(100, 23)
  14. print("我先执行")
  15. self.assertEqual(123, result)
  16.  
  17. #减法
  18. def test_minus(self):
  19. result = self.m.minus(235, 111)
  20. print("我后执行")
  21. self.assertEqual(124, result)

运行结果:

  1. Testing started at 12:36 ...
  2. 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
  3. 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
  4. 我先执行
  5. 我后执行
  6.  
  7. Ran 2 tests in 0.001s
  8.  
  9. OK

如果希望minus先执行,add后执行,可以给前者函数名加一个1,后者加一个2

  1. def test_2_add(self):
  2. result = self.m.add(100, 23)
  3. print("我后执行")
  4. self.assertEqual(123, result)
  5.  
  6. #减法
  7. def test_1_minus(self):
  8. result = self.m.minus(235, 111)
  9. print("我先执行")
  10. self.assertEqual(124, result)

5. 如果在setUp里实例化被测文件中的类,那么每一条测试用例都要实例化一次被测类,用setUpClass()可以只实例化一次,同理,tearDownClass也只做一次收尾工作

  1. @classmethod
  2. def setUpClass(cls):
  3. cls.m = Math()
  4.  
  5. @classmethod
  6. def tearDownClass(cls):
  7. pass

6. 用unittest.main()的方法来运行测试用例Test_Myclass.py

  1. import unittest
  2. from revise.My_UnitTest.myClass import Math
  3.  
  4. class Test_MyClass(unittest.TestCase):
  5.  
  6. @classmethod
  7. def setUpClass(cls):
  8. cls.m = Math()
  9.  
  10. @classmethod
  11. def tearDownClass(cls):
  12. pass
  13.  
  14. def test_2_add(self):
  15. result = self.m.add(100, 23)
  16. print("我后执行")
  17. self.assertEqual(123, result)
  18.  
  19. #减法
  20. def test_1_minus(self):
  21. result = self.m.minus(235, 111)
  22. print("我先执行")
  23. self.assertEqual(124, result)
  24.  
  25. if "__name__" == "__main__":
  26. 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中的代码如下:

  1. import unittest
  2. from revise.My_UnitTest.Test_Myclass import Test_MyClass
  3.  
  4. #实例化测试套件对象
  5. s = unittest.TestSuite()
  6. #调用addTest来加载测试用例——addTest(类名("用例函数名称"))——添加一个测试用例
  7. s.addTest(Test_MyClass("test_add"))
  8. s.addTest(Test_MyClass("test_minus"))
  9.  
  10. #使用TextTestRunner来运行测试用例
  11. #实例化
  12. runner = unittest.TextTestRunner()
  13. #用run方法就是用来运行测试用例的
  14. runner.run(s)

运行结果,控制台输出如下:

  1. D:\Program\python34\python.exe D:/python_workshop/python6/revise/My_UnitTest/main.py
  2. ..
  3. ----------------------------------------------------------------------
  4. Ran 2 tests in 0.001s
  5.  
  6. OK

实例2:addTests的使用

  1. import unittest
  2. from revise.My_UnitTest.Test_Myclass import Test_MyClass
  3.  
  4. #实例化测试套件对象
  5. s = unittest.TestSuite()
  6. #加载多个测试用例——参数为列表——列表当中为测试用例
  7. s.addTests([Test_MyClass("test_add"), Test_MyClass("test_minus")])
  8. #使用TextTestRunner来运行测试用例
  9. #实例化
  10. runner = unittest.TextTestRunner()
  11. #用run方法就是用来运行测试用例的
  12. runner.run(s)

运行结果:

  1. D:\Program\python34\python.exe D:/python_workshop/python6/revise/My_UnitTest/main.py
  2. ..
  3. ----------------------------------------------------------------------
  4. Ran 2 tests in 0.000s
  5.  
  6. OK

输出测试报告-text-到文件

#创建一个文件,以写的方式打开

fs = open("test_result.txt", "w")

runner = unittest.TextTestRunner(fs)

runner.run(s)

实例3:输出测试报告到文件

  1. import unittest
  2. from revise.My_UnitTest.Test_Myclass import Test_MyClass
  3.  
  4. #实例化测试套件对象
  5. s = unittest.TestSuite()
  6. #加载多个测试用例——参数为列表——列表当中为测试用例
  7. s.addTests([Test_MyClass("test_add"), Test_MyClass("test_minus")])
  8.  
  9. #使用TextTestRunner来运行测试用例
  10. #打开一个文件
  11. fs = open("test_run_result.txt", "w")
  12. #实例化
  13. runner = unittest.TextTestRunner(fs)
  14. #用run方法就是用来运行测试用例的
  15. runner.run(s)

运行结果,控制台没有输出,发现当前目录下多了一个文本文件test_run_result.txt

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

方式二:unittest.TestLoader.discover方法匹配目录下的用例

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

代码如下:

  1. import unittest, os
  2.  
  3. #实例化测试套件对象
  4. s = unittest.TestSuite()
  5. #1.实例化TestLoader对象 2.使用discover去找到一个目录下的所有测试用例
  6. loader = unittest.TestLoader()
  7. #3.使用addTests将找到的测试用例放在测试套件下
  8. s.addTests(loader.discover(os.getcwd()))
  9. #运行
  10. runner = unittest.TextTestRunner()
  11. runner.run(s)

运行结果:

  1. ....
  2. ----------------------------------------------------------------------
  3. Ran 4 tests in 0.000s
  4.  
  5. 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)

代码修改如下:

  1. import unittest, os, time
  2. from HTMLTestRunnerNew import HTMLTestRunner
  3.  
  4. #实例化测试套件对象
  5. s = unittest.TestSuite()
  6. #1.实例化TestLoader对象 2.使用discover去找到一个目录下的所有测试用例
  7. loader = unittest.TestLoader()
  8. #3.使用addTests将找到的测试用例放在测试套件下
  9. s.addTests(loader.discover(os.getcwd()))
  10.  
  11. #获取当前时间
  12. curTime = time.strftime("%Y-%m-%d_%H-%M-%S")
  13. #在当前目录下创建一个html文件
  14. fp = open(os.getcwd() + "/autoTest_report_{0}.html".format(curTime), "wb")
  15.  
  16. #运行测试用例,生成测试报告
  17. runner = HTMLTestRunner(
  18. stream=fp,
  19. title="单元测试报告",
  20. description="Math类的单元测试报告",
  21. tester="xiaozhai"
  22. )
  23. runner.run(s)

运行效果:

  1. D:\Program\python34\python.exe D:/python_workshop/python6/revise/My_UnitTest/main.py
  2. ok test_add (Test_Myclass.Test_MyClass)
  3. ok test_minus (Test_Myclass.Test_MyClass)
  4. ok test_add (Test_Myclass2.Test_MyClass2)
  5. ok test_minus (Test_Myclass2.Test_MyClass2)
  6.  
  7. Time Elapsed: 0:00:00.001000
  8. Sun Jul 8 18:17:18 2018 - Start Test:test_add (Test_Myclass.Test_MyClass)
  9. Sun Jul 8 18:17:18 2018 - Start Test:test_minus (Test_Myclass.Test_MyClass)
  10. Sun Jul 8 18:17:18 2018 - Start Test:test_add (Test_Myclass2.Test_MyClass2)
  11. 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(补充)的更多相关文章

  1. Appium+python的单元测试框架unittest(1)(转)

    unittest为python语言自带的单元测试框架,python把unittest封装为一个标准模块封装在python开发包中.unittest中常用的类有:unittest.TestCase.un ...

  2. Appium+python的单元测试框架unittest(4)——断言(转)

    (原文:https://www.cnblogs.com/fancy0158/p/10051576.html) 在我们编写的测试用例中,测试步骤和预期结果是必不可少的.当我们运行测试用例时,得到一个运行 ...

  3. python之单元测试框架—unittest

    一. 什么是单元测试?单元测试的对象是什么? 1: 什么是单元测试? 按照定义,单元测试就是对单个模块或者单个类或者单个函数进行测试,一般是开发做的,按照阶段分,一般就是单元测试.集成测试.系统测试. ...

  4. Python之单元测试框架unittest

    创建class继承unittest,每一个测试用例是以test开头的函数,先执行setup,然后用例按照字母的顺序执行,然后执行teardown import unittest class demo( ...

  5. Appium+python的单元测试框架unittest(3)——discover(转)

    (原文:https://www.cnblogs.com/fancy0158/p/10047906.html) TestSuite套件可以添加很多个用例后运行,但是每个用例都需要调用addTest()函 ...

  6. Appium+python的单元测试框架unittest(2)——fixtures(转)

    (原文:https://www.cnblogs.com/fancy0158/p/10046333.html) unittest提供的Fixtures用以在测试执行前和执行后进行必要的准备和清理工作,可 ...

  7. Python单元测试框架unittest之单用例管理(一)

    一.概述 本文介绍python的单元测试框架unittest,unittest原名为PyUnit,是由java的JUnit衍生而来,这是Python自带的标准模块unittest.unittest是基 ...

  8. 单元测试框架unittest

    单元测试:单元测试,是指对软件中的最小可测试单元进行检查和验证,对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义如:c语言中单元指一个函数,java里单元指一个类,图形化的软件中可以 ...

  9. Python单元测试框架unittest使用方法讲解

    这篇文章主要介绍了Python单元测试框架unittest使用方法讲解,本文讲解了unittest概述.命令行接口.测试案例自动搜索.创建测试代码.构建测试套件方法等内容,需要的朋友可以参考下   概 ...

随机推荐

  1. explorer.exe中发生未处理的win32异常

    explorer.exe中发生未处理的win32异常的错误提示,是windows系统比较常见的错误事件,多数在开机遇到,也有在电脑使用过程中遇到. 了解explorer.exe进程 从百度百科了解到, ...

  2. centos7安装tomcat7

    1.去官网下载指定的安装包http://tomcat.apache.org/download-70.cgi 2.把下载下来的安装包放在/opt下 3.使用命令解压下载的文件tar -zxvf apac ...

  3. python引入同一目录下的py文件

    python引入同一目录下的py文件 注意:python2和python3的包内import语法有区别,下面介绍一下python3的包内import语法 例如在admin.py文件中要引入dealco ...

  4. 快压、360压缩、WinRAR关于打开快压通过超高压缩比压缩后的文件不兼容的问题

    今天接收了同事发过来的一个压缩文件,用360压缩打开和用WinRAR打开压缩文件,傻眼了,这发的是什么鬼压缩包.压缩包的文件大小有27533KB,用360压缩工具解压查看只有121.5kb,而且完全没 ...

  5. Python3+Selenium3自动化测试-(五)

    这里来说一说selenium中的等待方式,其实在webdriver只有两种类型等待方式,显式等待和隐式等待,之前是在程序运行过程中使用time模块中的sleep进行代码的休眠进行强制等待,是显式等待中 ...

  6. 002-docker安装-mac上安装docker,17.06在CentOS7 64位机器上安装

    一.mac上安装docker 1.下载 通过这个链接下载:https://download.docker.com/mac/stable/Docker.dmg 2.安装 将 Moby 的鲸鱼图标拖拽到  ...

  7. android 6 (API 23) 及更高版本 面向 NDK 开发者的 Android 变更

    Android N 已经出来,有了好大的变化,对于我们开发者来说,最大的影响莫过于**NDK**相关东西. 以下是在中国谷歌开发者社区看到的.里面有好多的变化,欢迎大家来讨论. 发布人:开发顾问 Dm ...

  8. beego——ORM使用方法

    先来看一个简单示例: models.gp package main import ( "github.com/astaxie/beego/orm" ) type User stru ...

  9. delphi连接sql server的字符串2011-10-11 16:07

    delphi连接sql server的字符串2011-10-11 16:07 一.delphi连接sql server 放一个连接组件 ADOConnection, 其它组件TADODataSet,T ...

  10. ul,li设置inline-block缝隙

    去掉换行符和空白符 margin-left: -0.5em(缝隙大小不确定) ul字号设为0,li设置字号 (有些浏览器设置最小字体) js移除空白子节点