您的位置:首页 > 编程语言 > Python开发

python unittest 基本介绍

2015-11-11 11:02 465 查看
1介绍下unittest的基本使用方法:

1.import unittest
2.定义一个继承自unittest.TestCase的测试用例类
3.定义setUp和tearDown,在每个测试用例前后做一些辅助工作。

4.定义测试用例,名字以test开头。

5.一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。

6.调用unittest.main()启动测试
7.如果测试未通过,会输出相应的错误提示。如果测试全部通过则不显示任何东西,这时可以添加-v参数显示详细信息。

具体例子如下:

# -*- coding: cp936 -*-
import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
def setUp(self): #测试前的准备工作
pass

def test_testcase1(self): #测试用例1,且必须以test开头才能被认作是一个测试用例
pass

def test_testcase2(self):
pass

def test_testcase3(self):
pass

def runTest(self):

pass

def tearDown(self): #测试后的清除数据工作
pass

if __name__ == "__main__":

unittest.main() #必须调用main启动此次测试

查看了unittest的源代码发现,这个类中有四个testcase,3个以test开头,另一个是runTest,但是结果只运行了test开头的3个testcase,是因为代码中写着如果有test开头的则运行test开头的testcase,如果没有test开头的testcase而又存在runTest,怎运行runtest这个测试用例,在这里例子中,如果把3个test开头的testcase注释掉,则显示运行了一条testcase,即runTest。

测试结果:

...
----------------------------------------------------------------------
Ran 3 tests in 0.078s

OK

2 下面是unittest模块的常用方法:

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 2.7
assertIsNot(a, b) a is not b

2.7 assertIsNone(x) x is None 2.7
assertIsNotNone(x) x is not None 2.7

assertIn(a, b) a in b 2.7
assertNotIn(a, b) a not in b 2.7
assertIsInstance(a, b) isinstance(a, b) 2.7
assertNotIsInstance(a, b) not isinstance(a, b) 2.7

3也有其他的unittest方法,用于执行更具体的检查,如:

Method Checks that New in

assertAlmostEqual(a, b) round(a-b, 7) == 0

assertNotAlmostEqual(a, b) round(a-b, 7) != 0

assertGreater(a, b) a > b 2.7

assertGreaterEqual(a, b) a >= b 2.7

assertLess(a, b) a < b 2.7

assertLessEqual(a, b) a <= b 2.7

assertRegexpMatches(s, re) regex.search(s) 2.7

assertNotRegexpMatches(s, re) not regex.search(s) 2.7

assertItemsEqual(a, b) sorted(a) == sorted(b) and works with unhashable objs 2.7

assertDictContainsSubset(a, b) all the key/value pairs in a exist in b 2.7

单元测试例子:

import random

import unittest

class TestSequenceFunctions(unittest.TestCase):

def setUp(self):

self.seq = range(10)

def test_shuffle(self):

# make sure the shuffled sequence does not lose any elements

random.shuffle(self.seq)

self.seq.sort()

self.assertEqual(self.seq, range(10))

# should raise an exception for an immutable sequence

self.assertRaises(TypeError, random.shuffle, (1,2,3))

def test_choice(self):

element = random.choice(self.seq)

self.assertTrue(element in self.seq)

def test_sample(self):

with self.assertRaises(ValueError):

random.sample(self.seq, 20)

for element in random.sample(self.seq, 5):

self.assertTrue(element in self.seq)

if __name__ == '__main__':

unittest.main()

或者用下面的代码替代最后执行testcase的代码:

suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)

TestSequenceFunctions继承自unittest.TestCase,重写了setUp()方法,并且定义了三个以'test'开头的 方法,那这个TestSequenceFunctions类到底是个什么呢?它是一个测试用例,还是三个测试用例?说是三个测试用例的话,它本身继承自 TestCase,说是一个测试用例的话,里面又有三个test_*()方法,明显是三个测试用例。其实,我们只要看一些TestLoader是如何加载 测试用例的,就一清二楚了,在loader.TestLoader类中有一个loadTestsFromTestCase()方法:

def loadTestsFromTestCase(self, testCaseClass):

"""Return a suite of all tests cases contained in testCaseClass"""

if issubclass(testCaseClass, suite.TestSuite):

raise TypeError("Test cases should not be derived from TestSuite." \

" Maybe you meant to derive from TestCase?")

testCaseNames = self.getTestCaseNames(testCaseClass)

if not testCaseNames and hasattr(testCaseClass, 'runTest'):

testCaseNames = ['runTest']

loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))

return loaded_suite

getTestCaseNames()是从TestCase这个类中找所有以“test”开头的方法,然后注意第9行,在构造TestSuite对象时, 其参数使用了一个map方法,即对testCaseNames中的每一个元素,使用testCaseClass为其构造对象,其结果是一个 TestCase的对象集合,可以用下面的代码来分步说明:

[python]
view plain
copy







testcases = []

for name in testCaeNames:

testcases.append(TestCase(name))

loaded_suite = self.suiteClass(tuple(testcases))

可见,对每一个以test开头的方法,都为其构建了一个TestCase 对象,值得注意的是,如果没有定义test开头的方法,而是将测试代码写到了一个名为runTest的方法中,那么会为该runTest方法构建 TestCase对象,如果定义了test开头的方法,就会忽略runTest方法。 至此,基本就清楚了,每一个以test开头的方法,都会为其构建TestCase对象,也就是说TestSequenceFunctions类中其实定义 了三个TestCase,之所以写成这样,是为了方便,因为这几个测试用例的fixture是相同的,如果每一个测试用例单独写成一个TestCase的 话,会有很多的冗余代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: