使用Python的unittest框架编写测试用例


unittest是Python语言中的xUnit测试框架实现。也是在开发中最常用的用来写单元测试的框架。本文将介绍一下什么是unittest以及如何使用unittest开发单元测试。

找到需要测试的目标

要写测试用例,首先需要知道我们要测试的目标是什么,在本文中,我们以一个简单的乘法函数作为待测试对象,这个函数的实现如下:

def multiply(x, y):
    """
    将2个给定的参数相乘,并返回结果

    Args:
        :param x: 乘法算子x
        :param y: 乘法算子y
    Returns:
        x * y                                                   
    """

    return x * y

设计测试用例

想要测试这个函数,那我们首先需要设计一些测试用例,这些测试用例我们可以先以自然语言的形式将它们写到一个表格里,然后再用代码一步步的实现每一个测试用例。 例如,针对于上面的测试目标,设计了如下的测试用例:

编号 测试场景 预期结果
1 输入1, 2 返回2
2 输入1,0 返回0
3 输入None,0 返回异常
4 输入'a',0 返回"aa"

其中3属于异常测试。

使用unittest来实现测试用例

import unittest
import multiply


class TestMultiply(unittest.TestCase):

    def test_multiply_2_numbers(self):
        self.assertEqual(2, multiply.multiply(1, 2))

    def test_muliply_with_zero(self):
        self.assertEqual(0, multiply.multiply(1, 0))

    def test_multiply_with_None(self):
        try:
            multiply.multiply(None, 0)
        except Exception as msg:
            self.assertEqual(TypeError, type(msg))

    def test_multiply_with_char(self):
        self.assertEqual("aa", multiply.multiply("a", 2))


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

输出测试结果

执行

python test_multiply.py

如果一切正常,那么会输出:

....
----------------------------------------------------------------------
Ran 4 tests in 0.001s


OK

否则会输出对应的错误信息。

How it works

首先,我们选择了一个目标(函数)来测试。 其次,我们设计了一系列的测试用例。 然后,我们用unittest实现了这些测试用例,在每个测试用例,我们使用了assertEqual来检查函数的返回结果和预期是否一直。 最后,我们在文件末尾添加了:

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

这段代码是用来启动unittest的入口。这样我们在执行python test_multiply.py就可以跑测试用例了。

Tips

除了assertEquals还有assertTrue,assertFalse等等。但是assertEqual应该是在unittest test中最常用的assert语句了。

发现测试用例

当测试用例写的越来越多,我们必然会将测试用例拆分出来。此时就需要一个统一的入口来发现并执行测试用例,使用unittest的discover方法就能做到:

python -m unittest discover -v test_multipy

其中,test_multipy是刚才我们刚才添加的代码模块,执行结果如下:

test_muliply_with_zero (test_multiply.TestMultiply) ... ok
test_multiply_2_numbers (test_multiply.TestMultiply) ... ok
test_multiply_with_None (test_multiply.TestMultiply) ... ok
test_multiply_with_char (test_multiply.TestMultiply) ... ok


----------------------------------------------------------------------
Ran 4 tests in 0.001s


OK