虽然本人对 python 的 unittest 不熟悉,但还是硬着头皮把这篇文章写了,希望写完之后,自己能对这个单测框架了解的多一些。
2018 5.1 假期来临,突然想到还有一篇没有写完的文章,接杯热水继续写起来。
python unittest 实际上是参考 jUnit 实现的,甚至连命名都跟 java 一样都是驼峰命名(这个有点让有强迫症的人看了隐隐的不爽)
unittest 包含 4 个基本概念
test fixture
代表准备和清理的操作。像setUp
testDown
都属于 test fixture
test case
代表最基本的测试单元,检查在特定输入的情况下是否有一个特定的输出。通过集成 unitest 中的TestCase类,可以快速的写出一个 test case
test suite
test suite 由一组 test case 组成,不过其中也可以包含 test suite。代表所有的 case 合集
test runner
test runner 运行所有的 case,并将结果展现给用户。展现的方式可以是图形或文本,等等。
测试的对象是一个简单的 Player 类 (代码保存为 player.py
),通过 move 方法,可以改变 player 的 x, y 坐标
# coding: utf-8
class Player(object):
""" Player with position and can move in 2D world """
def __init__(self):
self.x = 0
self.y = 0
def move(self, xoff, yoff):
self.x += xoff
self.y += yoff
if __name__ == '__main__':
p = Player()
p.move(1, 2)
print("Player position: ({}, {})".format(p.x, p.y))
继续我们刚才写的代码,我们再写一些测试代码。
# coding: utf-8
# @Filename: simple_player_test.py
#
import unittest
from player import Player
class SimplePlayerTest(unittest.TestCase):
def setUp(self):
self.p = Player()
def runTest(self):
self.p.move(1, 2)
assert self.p.x == 1
assert self.p.y == 2
def tearDown(self):
print("tearDown calling")
上面的代码中,我们继承了 TestCase 类,重写了其中的setUp
, runTest
和tearDown
方法。setUp
通常用来准备测试环境。之后的runTest
会包含一些测试的操作。之后的tearDown
做一些环境的清理操作。
如果setUp
运行过程中跑出了异常,runTest
不会被运行,tearDown
方法也不会运行。
如果setUp
执行成功, 那么无论runTest
是否成功,tearDown
方法都将被执行。
如果测试用例中有AssertionError
异常抛出,测试框架会任务用例失败(Failure)。其他非 “assert"检查抛出的异常会被测试框架任务错误(Error)
具体的用例之后,我们后面再说。先保持一点耐心。
使用上面的刚写好的SimplePlayerTest
先创建一个实例。
testCase = SimplePlayerTest()
有时候可能我们很好多东西要测试,然后共用setUp
函数。将原来的测试类代码稍微修改下为
class SimplePlayerTest(unittest.TestCase):
def setUp(self):
self.p = Player()
def tearDown(self):
self.p.x = 0
self.p.y = 0
def testMoveUp(self):
self.p.move(0, 1)
assert self.p.x == 0 and self.p.y == 1
def testMoveLeft(self);
self.p.move(-1, 0)
assert self.p.x == -1 and self.p.y == 0
这个测试用例中我们没有提供 runTest 方法,而是用了两个不同的测试方法。创建类实例时需要想构造器传递方法名称,指明哪个测试方法将要被运行。
moveUpCase = SimplePlayerTest("testMoveUp")
moveLeftCase = SimplePlayerTest("testMoveLeft")
测试用例实例可以根据它们所测试的特性组合到一起。PyUnit 为此提供了一个机制叫做” 测试套件 “(test suite)。它由 unittest 模块中的 TestSuite 类表示:
suite = unittest.TestSuite()
suite.addTest(moveUpCase)
suite.addTest(moveLeftCase)
因为创建一个包含很多相似名称的测试方法的 TestCase 子类是一种很常见的模式,所以 unittest 模块提供一个便捷方法,makeSuite,来 创建一个由测试用例类内所有测试用例组成的测试套件:
suite = unittest.makeSuite(SimplePlayerTest, 'test')
需要注意的是,当使用 makeSuite 方法时,测试套件运行每个测试用例的顺序是由测试方法名根据 Python 内建函数 cmp 所排序的顺序而决定的
所以如果有两个函数testA()
, testB()
无论testA
定义在后面还是前面,testA
都是先与testB
执行。