单元测试框架unittest

单元测试:
单元测试,是指对软件中的最小可测试单元进行检查和验证,对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义
如:c语言中单元指一个函数,java里单元指一个类,图形化的软件中可以指一个窗口或者一个菜单等等,总的来说,单元就是人为规定的最小的被测功能模块

单元测试框架:
在单元测试框架出现之前,开发人员在创建可执行测试时饱受折磨,最初的做法是在应用程序中创建一个窗口,配有“测试控制工具”他只是一个窗口,每个测试
对应一个按钮,这些测试的结果要么是一个消息框,要么是直接在窗口本身给出某种显示结果,由于每个测试都需要一个
按钮,所以这些窗口变的非常的拥挤,不可管理;

单元测试框架提供了一种统一的编程模型,可以将测试定义为一些简单的类,这些类中的方法可以调用希望测试的应用程序代码,开发人员
不需要编写自己的测试控制工具,单元测试框架提供了测试运行程序,只需要单击按钮就可以执行所有测试,利用单元测试框架,可以很轻松的插入,设置和
分解有关测试的功能,测试失败时,测试运行程序可以提供有关失败的信息,包含任何可供利用的一场信息和堆栈跟踪,不同编程
语言有不同的单元测试框架,如,java的Junit,TestNg,c#的Nunit ,python的unittest,testtoolssubunit....

单元测试框架的作用:

提供用例组织与执行
提供丰富的断言方法
提供丰富的日志与测试结果

Python的单元测试框架---unittest
unittest单元测试框架不仅仅可以适用于单元测试,还可以适用web自动化测试用例的开发与执行
该测试框架可组织执行测试用例,并且提供了丰富的断言的方法,判断测试用例是否通过,最终声场测试结果

unittest的核心要素:
1.TestCase
一个TestCase的实例就是一个测试用例,什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的准备(setUp)
执行测试代码(run)以及测试后环境的还原(tearDown),单元测试(unittest)的本质就在这里,一个测试用例是一个完整的测试单元
通过运行这个测试单元,可以对某一个问题进行验证;

TestSuite
而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite,TestLoader是用来加载测试用例到TestSuite中的


TextTestRunner
TextTestRunner是用来执行测试用例的,其中的runn()会执行,TestSuite/TestCase中的run(result)方法,测试的结果会保存到TextTestResult
实例中,,包括运行了多少测试用例,成功了多少,失败了多少等等信息

Fixture
而对于一个测试用例环境的搭建和销毁,是一个fixture

二:unittest案例
建立一个:calculator.py文件,然后
构造一个类Math包含整数加法运算

class Math:
    def __init__(self,a,b):
        self.a=int(a)
        self.b=int(b)
    def add(self):
        return self.a+self.b
    

然后在构建一个测试文件testMath.py
用来测试刚刚构建的类

 1 from calculator import Math
 2 import unittest
 3 class testMath(unittest.TestCase):
 4     def setUp(self):
 5         print("start test")
 6     def test_add(self):
 7         j=Math(12,3)
 8         #用到断言,后边还会讲解,
 9         self.assertEqual(j.add(),15)
10         #失败的场景
11         #self.assertEqual(j.add(),12)
12     def tearDown(self):
13         print("test end")
14 if __name__ == '__main__':
15     #构建测试集
16     suite=unittest.TestSuite()
17     suite.addTest(testMath("test_add"))
18 
19     #执行测试:
20     runner=unittest.TextTestRunner()
21     runner.run(suite)

注意当导入文件报错的时候:

可以选择,如图:

这样就不会因为导入文件找不到而报错了;

上述测试的结果为:

三:常用的断言的方法:

断言内容是自动化脚本的重要的内容,正确设置断言以后才能帮助我们判断测试用例执行的结果;

断言的方法:
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) 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)
assertNotinstance(a,b) not isinstance(a,b)

通过上述的加法的离例子,来运行修改上述的代码,运行上述的断言的方法:

这里不在赘述,大家可以通过例子查看;

四:新增的单元测试用例的管理:

前面是针对一个add方法来进行单元测试的,如果需要多个方法进行测试,该如何处理?如新增一个Sub方法来进行单元测试

在上述的calculator.py里面的文件加入一个减法

class Math:
    def __init__(self,a,b):
        self.a=int(a)
        self.b=int(b)
    def add(self):
        return self.a+self.b
    def sub(self):
        return self.a-self.b

在测试文件里面加入一个类叫

Test_sub
在这里面定义一些减法的用例:
在调试的时候在main函数里面多加两条case的调试就好了:
 1 from calculator import Math
 2 import unittest
 3 class testMath(unittest.TestCase):
 4     def setUp(self):
 5         print("start test")
 6     def test_add(self):
 7         j=Math(12,3)
 8         #用到断言,后边还会讲解,
 9         self.assertEqual(j.add(),15)
10         #失败的场景
11         #self.assertEqual(j.add(),12)
12     def test_add1(self):
13         j=Math(10,5)
14         self.assertEqual(j.add(),15)
15 
16     def tearDown(self):
17         print("test end")
18 class Test_sub(unittest.TestCase):
19     def setUp(self):
20         print("start test2")
21 
22     def test_sub1(self):
23         k=Math(10,5)
24         self.assertEqual(k.sub(),5)
25 
26     def tearDown(self):
27         print("test end2")
28 
29 if __name__ == '__main__':
30     #构建测试集
31     suite=unittest.TestSuite()
32     suite.addTest(testMath("test_add"))
33     suite.addTest(testMath("test_add1"))
34     suite.addTest(Test_sub("test_sub1"))
35 
36     #执行测试:
37     runner=unittest.TextTestRunner()
38     runner.run(suite)

执行结果如图:

五:用例合并:

用例公共部分的合并:
上一节课内容中,每个测试类都有setUP() 和tearDown()
而且连个方法的内容都是一样的,用于打印开始与结束提示语句,是否可以合并在一起呢?

要合并:两个类里面的:setUP() 和tearDown()必须一致才能合并,不一致是不能喝并的

 1 from calculator import Math
 2 import unittest
 3 
 4 
 5 class tearupend(unittest.TestCase):
 6     def setUp(self):
 7         print("start test")
 8     def tearDown(self):
 9         print("test end2")
10         
11 class testMath(tearupend):
12 
13     def test_add(self):
14         j=Math(12,3)
15         #用到断言,后边还会讲解,
16         self.assertEqual(j.add(),15)
17         #失败的场景
18         #self.assertEqual(j.add(),12)
19     def test_add1(self):
20         j=Math(10,5)
21         self.assertEqual(j.add(),15)
22         
23 
24 class Test_sub(tearupend):
25     def test_sub1(self):
26         k=Math(10,5)
27         self.assertEqual(k.sub(),5)
28 
29 if __name__ == '__main__':
30         unittest.main

在上述类的继承上:

tearupend 继承了unittest.TestCase
其他的类都继承了:
tearupend

六用例综合框架管理:
前面的测试用例与执行都是写在一个文本,当用例数量不断增加的时候,用例的执行与管理变得非常麻烦,因此需要对用例根据具体的功能模块来
使用单独的模块化管理,就像一所学校要根据不同的年级进行分班管理,也是一样的道理(这里代码不在一一赘述,大家自行完成)

案例 TestProject文件目录里面包含5个文件:
1、StartEnd.py ----------setup,teardown的管理文件
2、calculator.py----------加减法运算方法的实现
3、test_add.py------------加法测试用例
4、test_Sub.py------------减法测试用例
5、runtest.py--------------用例执行管理


runtest要这样写
./是指当前的路径


七:测试报告:

自动化测试执行完成之后,我们需要生成测试报告,生成HTML的一个测试报告,

来查看测试结果,使用HTMLTestRunner模块可以直接生成HTML格式的报告

下载地址:
http://tungwaiyip.info/software/HTMLTestRunner.html

下载完成之后要对其文件进行修改:(因为下载的模块是对应的是Python2编写的,如果使用的是Python3,则需要对这个文件进行修改)

存放路径:
修改完成的模块放在Python路径下的Lib目录里面既可;

这里我已经修改好了,大家可以直接下载:

链接: https://pan.baidu.com/s/1kU7Go4J 密码: 4jc3

原文地址:https://www.cnblogs.com/surewing/p/7896886.html