单元测试:
单元测试,是指对软件中的最小可测试单元进行检查和验证,对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义
如: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