Python单元测试框架 unittest
目的和任务:
能够利用Python测试框架编写测试程序,生成测试报告。
实验环境:
(1)window10操作系统;
(2)python开发环境
实验内容:
unittest框架:
① 一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
②多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
③ TestLoader是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
④ TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
⑤对一个测试用例环境的搭建和销毁,是一个fixture。
白盒测试用例设计方法:
语句覆盖:每条语句至少执行一次。
判定覆盖:每个判定的所有可能结果至少出现一次。(又称“分支覆盖”)
条件覆盖:每个条件的所有可能结果至少执行一次。
判定/条件覆盖:一个判定中的每个条件的所有可能结果至少执行一次,并且每个判断本身的所有可能结果至少执行一次。
多重条件覆盖(组合覆盖):每个判定中的所有可能的条件结果的组合,以及所有的入口点都至少执行一次。(注意“可能”二字,因为有些组合的情况难以生成。)
完全路径覆盖:每条路径至少执行一次。
基本路径覆盖:根据流图计算环复杂度,得到基本路径覆盖的用例数。
分割后的完全路径覆盖:每条路径至少执行一次,每个条件的所有可能结果至少执行一次。
上述就是实验前的前置知识。
函数DoWork的程序流程图:
函数DoWork的控制流图:
设计的测试用例如下:
"""
Test method work(x, y, z)
语句覆盖:
测试用例的输入为:{x = 5, y = 6, z = 7}
程序执行的路径是:abd
"""
"""
Test method work(x, y, z)
判定覆盖:
测试用例的输入为:{x = 5,y = 6, z = 7} {x = 1, y = 2, z = 3}
程序执行的路径是:abd;ace
"""
"""
Test method work(x, y, z)
条件覆盖:
测试用例的输入为:{x = 4,y = 6, z = 7} {x = 1, y = 2, z = 13}
程序执行的路径是:abd;ace
覆盖分值:bd;ce
"""
"""
Test method work(x, y, z)
判定/条件覆盖:
测试用例的输入为:{x = 4,y = 6, z = 9} {x = 3, y = 5, z = 10}
程序执行的路径是:abd;ace
覆盖分值:bd;ce
"""
"""
Test method work(x, y, z)
组合覆盖:
测试用例的输入为:{x = 4,y = 6, z = 6} {x = 4,y = 5, z = 10} {x = 3,y = 6, z = 6} {x = 3,y = 5, z = 10} {x = 5,y = 5, z = 5}
程序执行的路径是:abd;acd;acd;ace;abe
"""
unittest实例:
mathfunc.py
import math
def work(x, y, z):
k = 0
j = 0
if x > 3 and z < 10:
k = x * y - 1
j = math.sqrt(k)
if x == 4 or y > 5:
j = x * y + 10
j = j % 3
return k, j
test_mathfunc.py
# -*- coding: utf-8 -*-
import unittest
from mathfunc import *
class TestMathFunc(unittest.TestCase):
"""Test mathfuc.py"""
def setUp(self):
print
"do something before test.Prepare environment."
def tearDown(self):
print
"do something after test.Clean up."
def test_statementCoverage(self):
"""
Test method work(x, y, z)
语句覆盖:
测试用例的输入为:{x = 5, y = 6, z = 7}
"""
self.assertEquals(work(5, 6, 7), (29, 1))
def test_determineCoverage(self):
"""
Test method work(x, y, z)
判定覆盖:
测试用例的输入为:{x = 5,y = 6, z = 7} {x = 1, y = 2, z = 3}
"""
self.assertEquals(work(5, 6, 7), (29, 1))
self.assertEquals(work(1, 2, 3), (0, 0))
def test_conditionCoverage(self):
"""
Test method work(x, y, z)
条件覆盖:
测试用例的输入为:{x = 4,y = 6, z = 7} {x = 1, y = 2, z = 13}
"""
self.assertEquals(work(4, 6, 7), (23, 1))
self.assertEquals(work(1, 2, 13), (0, 0))
def test_decisionConditionCoverage(self):
"""
Test method work(x, y, z)
判定/条件覆盖:
测试用例的输入为:{x = 4,y = 6, z = 9} {x = 3, y = 5, z = 10}
"""
self.assertEquals(work(4, 6, 9), (23, 1))
self.assertEquals(work(3, 5, 10), (0, 0))
def test_combinationCoverage(self):
"""
Test method work(x, y, z)
组合覆盖:
测试用例的输入为:{x = 4,y = 6, z = 6} {x = 4,y = 5, z = 10} {x = 3,y = 6, z = 6} {x = 3,y = 5, z = 10} {x = 5,y = 5, z = 5}
"""
self.assertEquals(work(4, 6, 6), (23, 1))
self.assertEquals(work(4, 5, 10), (0, 0))
self.assertEquals(work(3, 6, 6), (0, 1))
self.assertEquals(work(3, 5, 10), (0, 0))
self.assertEquals(work(4, 6, 9), (23, 1))
self.assertEquals(work(5, 5, 5), (24, 1.8989794855663558))
test_suite.py:
# -*- coding: utf-8 -*-
import unittest
from test_mathfunc import TestMathFunc
if __name__ == '__main__':
suite = unittest.TestSuite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestMathFunc))
with open('UnittestTextReport.txt', 'a') as f:
runner = unittest.TextTestRunner(stream=f, verbosity=2)
runner.run(suite)