unittest框架
unittest是python内置的单元测试框架,具备编写用例、组织用例、执行用例、输出报告等自动化框架的条件。
单元测试框架的优点
一般来说不用单元测试框架也能编写单元测试,因为单元测试本身就是通过一段代码去验证另一段代码,所以不用单元测试框架也能编写单元测试。只是使用框架时有更多的优点:
1.提供用例组织与执行
当测试用例达到成百上千条时,就产生了扩展性与维护性等问题,此时就需要考虑用例的规范与组织问题了。单元测试框架便能很好的解决这个问题
2.提供丰富的比较方法
不论是功能测试还是单元测试,在用例完成之后都需要将实际结果与预期结果进行比较(断言),从而断定用例是否执行通过。单元测试框架一般会提供丰富的断言方法。例如:相等\不相等,包含\不包含,True\False的断言方法等
3.提供丰富的日志
当测试用例执行失败时能抛出清晰的失败原因,当所有用例执行完成之后能提供丰富的执行结果。例如,总执行时间、失败用例数、成功用例数等
单元测试重要的概念
使用unittest前需要了解该框架的五个概念,即test case,test suite,testLoader,test runner,test fixture
1.Test Case:
一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程。包括测试前准备环境的搭建(SetUP)、实现测试过程的代码(run),以及测试后环境的还原(tearDown)。单元测试(Unittest)的本质也就在这里,一个测试用例就是一个完整的测试单元,通过运行这个测试单元,可以对某一个功能进行验证
2.Test Suite:
一个功能的验证往往需要多个测试用例,可以把多个测试用例集合在一起执行,这就产生了测试套件TestSuite的概念。TestSuite用来组装单个测试用例。可以通过addTest加载TestCase到TestSuite中,从而返回一个TestSuite实例。而且TestSuite也可以嵌套TestSuite
3.Test Runner:
测试的执行也是单元测试中非常重要的一个概念,一般单元测试框架中都会提供丰富的执行策略和执行结果。在Unittest单元测试框架中,通过TextTestRunner类提供的run()方法来执行test suite/test case。test runner可以使用图形界面、文本界面,或返回一个特殊的值等方式来表示测试执行的结果
4.Test Fixture:
对一个测试用例环境的搭建和销毁,就是一个Fixture,通过覆盖TestCase的setUP()和tearDown()方法来实现。这有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUP()中建立数据库连接来进行初始化,在tearDown()中清除数据库产生的数据,然后关闭连接
注:tearDown()方法的过程很重要,要为下一个TestCase留下一个干净的环境。
unitest的工作原理
通过unittest类调用分析,可将框架的工作流程概况如下:
编写TestCase,由TestLoader加载TestCase到TestSuite,然后由TextTestRunner来运行TestSuite,最后将运行的结果保存在TextTestResult中。
CountTest.py
#待测试代码
class Count():
def __init__(self, x, y):
self.x = int(x)
self.y = int(y)
def Add(self, c):
sum = self.x + self.y + c
return sum
def Subtract(self):
subtract = self.x - self.y
return subtract
def Product(self):
product = self.x * self.y
return product
def Division(self):
division = self.x / self.y
return division
if __name__ == "__main__":
count = Count(6, 3)
print(count.Add(2))
print(count.Subtract())
print(count.Product())
print(count.Division())
#输出结果
"""
11
3
18
2.0
"""
CountUnitTest.py
import unittest
import CountTest #引用CountTest
class TestAddCount(unittest.TestCase):
def setUp(self):
print("测试开始")
#assertEqual(arg1, arg2, msg=None) 验证arg1=arg2,不等则fail
def test_add_case(self):
count = CountTest.Count(6, 3)
self.assertEqual(count.Add(2), 11) # 测试函数的返回值
def test_subtract_case(self):
count = CountTest.Count(6, 3)
self.assertEqual(count.Subtract(), 3)
def test_product_case(self):
count = CountTest.Count(6, 3)
self.assertEqual(count.Product(), 18)
def test_division_case(self):
count = CountTest.Count(6, 3)
self.assertEqual(count.Division(), 2)
def tearDown(self):
print("测试结束")
if __name__ == "__main__":
unittest.main()
#输出结果
'''
测试开始
测试结束
测试开始
测试结束
测试开始
测试结束
测试开始
测试结束
Ran 4 tests in 0.003s
OK
'''
参考文章:
Unittest单元测试框架