python之单元测试框架—unittest(补充)

1|0一. 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)

2|0二. unittest初级使用


1. 导入unittest模块、被测文件或者其中的类

2. 创建一个测试类,并继承unittest.TestCase

3. 重写setUp和tearDown方法(如果有初始化条件和结束条件)

4. 定义测试函数,函数以test_开头

5. 在函数体中使用断言来判断测试结果是否符合预期结果

6. 调用unittest.main()方法来运行测试用例

2|1实例


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()

3|0三. 断言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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4|0四. unittest进阶使用


4|1方式一:类名("方法名")的集合


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

4|2输出测试报告-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

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

4|3方式二: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开头的也能找到)

4|4方式三:unittest.TestLoader.loadTestsFromModule匹配模块中的测试用例


ps:TetLoader类、TestSuite类需要先实例化再使用

5|0五. 美化测试报告—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)

 

 

 

6|0参考文章


https://blog.csdn.net/huilan_same/article/details/52944782

 


__EOF__

本文作者cnhkzyy
本文链接https://www.cnblogs.com/my_captain/p/9250664.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   cnhkzyy  阅读(474)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示