Python单元测试框架 Unittest 的简单使用方法

Python单元测试框架 Unittest 的简单使用方法

(第一次接触单元测试,稍微记录一下,别过两天又给忘了)

单元测试是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。

假设在 f.py 下有两个函数,我们需要测试他们:

def add(a, b):
    return a + b

def sub(a, b):
    return a - b

对于 add() sub() 这两个函数我们希望它能够返回两个数的和或差。

比如 add(1, 2) 我们希望它能够返回 3,sub(3, 1) 希望他能够返回 2,而对于 add(1, [2]) 我们希望它能够返回一个 TypeError 异常。

把这样的测试用例放到一个测试模块里,就是一个完整的单元测试。

如果单元测试通过,说明我们测试的这个函数能够正常工作。如果我们对函数代码做了修改,只需要再跑一遍单元测试。如果通过,说明我们的修改不会对函数原有的行为造成影响,如果测试不通过,说明我们的修改与原有行为不一致,要么修改代码,要么修改测试。

现在我们对这两个函数进行测试:

import unittest	# 首先import unittest模块
from f.py import add, sub

# 编写一个测试类  需要从unittest.TestCase中继承
class MyClassTest(unittest.TestCase):

	def test_add(self):
        ans = add(1, 2)
        self.assertEqual(3, ans)
        
	def test_sub(self):
        ans = sub(3, 1)
        self.assertEqual(2, ans)

if __name__ == '__main__':
    unittest.main()	

unittest 会自动测试所有以 test 开头的方法,不以 test 开头的方法不被认为是测试方法,测试的时候不会被执行。

用例执行后,需要判断用例是 Pass 还是 Fail ,可以用 unittest.TestCase 模块的 断言

unittest.TestCase 提供了很多内置的条件判断,我们只需要调用这些方法就可以输出是否是我们所期望的。

assertEqual(a, b, msg="None") 判断a,b是否相等,不相等时,抛出 msg 。

assertTure(x, msg="None") 判断x表达式是否为真,表达式为假时,抛出 msg 。

assertIn(a, b, msg="None") 判断a是否在b里面,a不在b里面时,抛出 msg 。

assertIsNone(x, msg="None") 判断x是否为空,x不为空时,抛出 msg 。

另一种重要的断言就是期待抛出指定类型的 Error,比如通过 add(1, [2]) 就会抛出 TypeError

with self.assertRaises(TypeError):
    add(1, [2])

每个测试可以使用多个断言方式,同时满足的条件下,用例才通过。

试运行一下刚刚写的两个测试,看看结果如何:

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

说明两个测试都通过了,符合预期。

我们测试一下异常。

再添加一个测试方法:

    def test_err(self):
        with self.assertRaises(TypeError):
            add(1, [2])

运行一下:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

也通过了测试。


另外,unittest 还提供了setUp()tearDown()setUpClass()tearDownClass() 四个特殊的方法:

setUp(): 执行每个测试方法前之前,都要执行 setUp() 方法,每个测试用例前都执行。
tearDown(): 执行完每个测试方法之后,都要执行 tearDown() 方法,每个测试用例后都执行。
setUpClass(): 执行所有测试之前,执行 setUpClass() 方法,只执行一次,需使用 @classmethod 装饰器。
tearDownClass(): 执行完所有测试之后,执行 tearDownClass() 方法,只执行一次,需使用 @classmethod 装饰器。

class MyClassTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        print("hello!")

    @classmethod
    def tearDownClass(cls) -> None:
        print('good bye!')

    def setUp(self):
        print('setUp...')

    def tearDown(self):
        print('tearDown...')

    def test_add(self):
        print('test add')
        ans = add(1, 2)
        self.assertEqual(3, ans)

    def test_sub(self):
        print('test sub')
        ans = sub(3, 1)
        self.assertEqual(2, ans)

    def test_err(self):
        print('test err')
        with self.assertRaises(TypeError):
            add(1, [2])

运行结果:

hello!
setUp...
test add
tearDown...
setUp...
test err
tearDown...
setUp...
test sub
tearDown...
good bye!
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

(执行是按字母排序的顺序执行的)

原文地址:https://www.cnblogs.com/lin-xm/p/13676461.html