unittest自动化测试框架
框架简介
框架的概念:
在系统开发过程中,框架是指对特定应用领域中的应用系统的部分设计和实现子系统的整体结构。
框架将应用系统划分为类和对象,定义类和对象的责任,类和对象如何互相协作,以及对象之间的控制线程。这些共有的设计因素由框架预先定义,应用开发人员只须关注于特定的应用系统特有部分。
自动化测试框架的定义为:
由一个或多个自动化测试基础模块、自动化测试管理模块、自动化测试统计模块等组成的工具集合。
- 按框架的定义来分,自动化测试框架可以分为:基础功能测试框架、管理执行框架;
- 按不同的测试类型来分,可以分为:功能自动化测试框架、性能自动化测试框架;
- 按测试阶段来分,可以分为:单元自动化测试框架、接口自动化测试框架、系统自动化测试框架;
- 按组成结构来分,可以分为:单一自动化测试框架、综合自动化测试框架;
- 按部署方式来分,可以分为:单机自动化测试框架、分布式自动化测试框架。
Unittest测试框架使用介绍
熟悉Unittest测试框架是后续使用Python进行自动化测试的基础,Unittest框架(又名PyUnit框架)为Python语言的单元测试框架。
其官方介绍文档链接为:https://docs.python.org/2.7/library/unittest.html#module-unittest
Unittest测试框架使用介绍:
- 用import语句引入unittest模块
- 让所有执行测试的类都继承于TestCase类,可以将TestCase看成是对特定类进行测试的方法的集合
- setUp()方法中进行测试前的初始化工作,teardown()方法中执行测试后的清除工作,它们都是TestCase中的方法
- 编写测试的方法最好以test开头(可以直接运行):def test_add(self) 、 def test_sub(self)等,可以编写多个测试用例对被测对象进行测试
- 在编写测试方法过程中,使用TestCase class提供的方法测试功能点,比 如:assertEqual等
- 调用unittest.main()方法运行所有以test开头的方法
应用实例
对模块中的加法功能测试
存在一个calc.py的模块,里面存在一个加法功能:
def sum(a,b):
return a+b
#encoding: utf-8
import unittest #导入unittest
import calc #导入被测模块
class mytest(unittest.TestCase):
def setUp(self): #初始化工作
pass
def tearDown(self): #退出清理工作
pass
def testsum(self): #具体的测试用例,一定要以test开头
self.assertEqual(calc.sum(1,2),2,"testing sum")
if __name__=="__main__":
unittest.main()
unittest中常用的assert语句
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):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)
assertNotIsInstance(a, b):not isinstance(a, b)
assertGreater(a, b):a > b
assertGreaterEqual(a, b):a >= b
assertLess(a, b):a < b
assertLessEqual(a, b):a <= b
unittest创建测试代码的方式
方式一:创建子类继承unittest.TestCase,然后重写runTest方法
class WidgetTestCase(unittest.TestCase):
def setUp(self):
pass
def runTest(self):
pass
def tearDown(self):
pass
方式二:编写以test开头的方法 class WidgetTestCase(unittest.TestCase):
def setUp(self):
pass
def test_xx1(self)
def test_xx2(self)
...
def test_xxN(self)
def tearDown(self):
pass
unittest构建测试套件(测试用例集合)
前提Tester是继承了unittest.TestCase的子类
方式一:
Suite = unittest.TestSuite()
Suite.addTest(Tester('test_default_size'))
Suite.addTest(Tester('test_resize'))
方式二(推荐):
def suite():
suite = unittest.TestSuite()
suite.addTest(Tester('test_default_size'))
suite.addTest(Tester('test_resize'))
return suite
方式三(推荐):
def suite():
tests = ['test_default_size', 'test_resize']
return unittest.TestSuite(map(Tester, tests))
构建测试套件举例
存在如下类calc:
#encoding: utf-8
class calc(): #计算器类
def __init__(self,a,b): #初始化
self.numa = a
self.numb = b
def sum(self): #加法
return self.numa+self.numb
def sub(self): #减法
return self.numa-self.numb
def multi(self): #乘法
pass
测试方法如下:
import unittest #导入unittest
import calc
class mytest(unittest.TestCase):
def setUp(self): #初始化工作
self.testnum = calc.calc(3,4)
def tearDown(self): #退出清理工作
del self.testnum
def testsum(self): #具体的测试用例
self.assertEqual(self.testnum.sum(),7,"testing sum")
def testsub(self): #具体的测试用例
self.assertEqual(self.testnum.sub(),-1,"testing sub")
def testmulti(self): #具体的测试用例
self.assertEqual(self.testnum.multi(),12,"testing multi")
def suite():
suite = unittest.TestSuite()
suite.addTest(mytest("testsum"))
suite.addTest(mytest("testsub"))
return suite
if __name__=="__main__":
unittest.main(defaultTest = 'suite')
unittest忽略测试用例
Python 2.7支持忽略部分测试用例不执行,分无条件忽略和有条件忽略, 通过装饰器实现。
使用unitest.skip装饰器族跳过test method或者test class,这些装饰器包括:
- @unittest.skip(reason):无条件跳过测试,reason描述为什么跳过测试
- @unittest.skipIf(conditition,reason):condititon为true时跳过测试
- @unittest.skipUnless(condition,reason):condition不是true时跳过测试
- @expected failure:使用@unittest.expectedFailure装饰器,如果test失败了,这个test不计入失败的case数目
举例:
def testsub(self): #具体的测试用例
self.assertEqual(self.testnum.sub(),-1,"testing sub")
@unittest.skip("test skipping") #跳过测试用例
def testmulti(self): #具体的测试用例
self.assertEqual(self.testnum.multi(),12,"testing multi")
运行测试集
unittest使用TestRunner类作为测试用例的基本执行环境,来驱动整个单元测试过程,在单元测试时,一般不直接使用TestRunner类,而是使用其子类TextTestRunner来完成测试,并将结果以文本方式显示出来。
runner=unittest.TextTestRunner()
runner.run(suite)
同时,在unittest模块中定义了一个名为main的全局方法,使用它可以很方便地将一个单元测试模块变成可以直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中的测试方法,并自动执行它们。
如果Python程序员能够按照约定(以test开头)来命名所有的测试方法,那么只需要在测试模块的最后加入如下几行代码即可:
if __name__ == "__main__": #__name__为模块内置属性 __main__表示直接执行
unittest.main()
#或者加参数: unittest.main(defaultTest = 'suite')