unittest
认识unittest
什么是单元测试?
单元测试负责对最小的软件设计单元(模块)进行验证,它使用软件设计文档中对模块的描述作为指南,对重要的程序分支进行测试以发现模块中的错误。在Python语言下有诸多单元测试框架,如doctest、unittest、pytest、nose等,unittest框架(原名PyUnit框架)为Python语言自带的单元测试框架,Python2.1及其以后的版本已将unittest作为一个标准模块放入Python开发包中。
首先创建一个被测试类calculator.py
class Count:
def __init__(self,a,b):
self.a=int(a)
self.b=int(b)
#计算加法
def add(self):
return self.a + self.b
不用测试框架写一个测试类:
from calculator_method import Count
#测试两个整数相加
class TestCount:
def test_add(self):
try:
j=Count(2,3)
add=j.add()
assert(add==5),'Integer addition result errort!'
except AssertionError as msg:
print(msg)
else:
print('Test Pass!')
#执行测试类的测试方法
mytest=TestCount()
mytest.test_add()
首先,引入calculator文件中的Count类,然后在test_add()方法中调用Count类并传入两个参数2和3;最后调用Count类中的add()方法对两个参数做加法运算,并通过assert()方法判断add()的返回值是否等于5.如果不相等则抛出自定义的异常信息,如果相等则打印“TestPASS!”。
通过unittest单元测试框架编写测试用例:
from calculator_method import Count
import unittest
class TestCount(unittest.TestCase):
def setUp(self):
print("test start:")
def test_add(self):
j=Count(2,3)
self.assertEqual(j.add(),5)
def tearDown(self):
print("test end.")
if __name__ == '__main__':
unittest.main()
首先引入unittest模块,创建TestCount类继承unittest的TestCase类,我们可以将TestCase类看成是对特定类进行测试的集合。
setUp()方法用于测试用例执行前的初始化工作,这里只简单打印“test Start”信息。tearDown()方法与setUp()方法相呼应,用于测试用例执行之后的善后工作,这里打印“test end”信息。
在test_add()中首先调用Count类并传入要计算的数,通过调用add()方法得到两数相加的返回值。这里不再使用繁琐的异常处理,而是调用unittest框架所提供的assertEqual()方法对add()返回值进行断言,判断两者是否相等,assertEqual()方法由TestCase类继承而来。
unittest提供了全局的main()方法,使用它可以方便的将一个单元测试模块变成可以直接运行的测试脚本。main()方法使用TestLoader类来搜索所有包含在该模块中以“test"命名开头的测试方法,并自动执行它们。
补充:
if __name__ == "__main__":语句说明
在后面的实例中我们会经常用到这个语句,在解释它之前先补充点Python知识:
1. Python文件的后缀为.py。
2. .py文件即可以用来直接执行,就像一个小程序一样,也可以用来作为模块被导入。
3. 在Python中导入模块一般使用import。
if __name__ == '__main__'的意思是:当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,
if __name__ == '__main__'之下的代码块不被运行。
- TestCase(测试用例): 所有测试用例的基类,它是软件 测试中最基本的组成单元。
一个test case就是一个测试用例,是一个完整的测试流程,包括测试前环境的搭建setUp,执行测试代码(run),以及测试后环境的还原(tearDown)。测试用例是一个完整的测试单元,可以对某一问题进行验证。 - TestSuite(测试套件):多个测试用例test case集合就是TestSuite,TestSuite可以嵌套TestSuite。
- TestLoader:是用来加载 TestCase到TestSuite中,其中有几个loadTestsFrom_()方法,就是从各个地方寻找TestCase,创建他们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
- TextTestRunner:是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
- TextTestResult:测试结果会保存到TextTestResult实例中,包括运行了多少用例,成功与失败多少等信息。
- TestFixture:又叫测试脚手,测试代码的运行环境,指测试准备前和执行后要做的工作,包括setUp和tearDown方法。
测试流程:
-
写好TestCase:一个class继承unittest.TestCase,就是一个测试测试用例,其中有多个以test开头的方法,那么 每一个这样的,在load的时候会生成一个TestCase实例。如果一个class中有四个test开头的方法,最后load到suite中时则有四个测试用例
-
由TestLoder加载TestCase到TestSuite
-
然后由TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中。
说明:
a. 通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者可以直接通过TextTestRunner来执行用例。
b. Runner执行时,默认将结果输出到控制台,我们可以设置其输出到文件,在文件中查看 结果,也可以通过HTMLTestRunner将结果输出到HTML)。
- 方法一:创建一个测试集的容器,收集测试用例
suite=unittest.TestSuite()
- 方法二:收集测试用例,以对象(实例)的形式来添加用例
suite.addTest(TestMath("test_add")) #添加加法的测试用例到测试集suite里面
suite.addTests(TestMath("test_add"),TestMath("test_sub"),TestMath("test_div"))
- 方法三:从测试类里面加载用例到suite:
ts=nuittest.TestLoader() #用例加载器
suite.addTest(ts.loadTestsFromTestCase())
- 方法四:
ts=unittest.TestLoader() #用例加载器
suite.addTest(ts.loadTestsFromModule(testMathMethod))