UnitTest单元测试初体验

介绍

UnitTest是Python自带的测试框架,主要用于单元测试~说到UnitTest需要了解几个概念:TestCase(测试用例),TestFixture(测试固件),TestSuite(测试套件),TestRunner(测试运行器)。接下来分别学习一下:
首先,我们写一个简单的计算器类,其中有加减乘除四个方法,我们将针对这个计算器类进行单元测试。

#coding:utf-8
class MyCalculator():
    def __init__(self):
        pass
    #加
    def add(self,data1,data2):
        return data1+data2
    #减
    def minus(self,data1,data2):
        return data1-data2
    #乘
    def multiply(self,data1,data2):
        return data1*data2
    #除
    def divide(self,data1,data2):
        return data1/data2

测试用例与测试固件:

新建一个测试类,继承unittest.TestCase,在该类中写的每一个函数均可理解为一条测试用例。正常来讲,每个测试用例的内容就是每个测试点。如下代码:

# -*- coding:utf-8 -*-
from firstpackage.MyCalculator import MyCalculator
import unittest
import HTMLTestRunner

class TestCalculator(unittest.TestCase):

    def setUp(self):
        self.myCalculator=MyCalculator()
        print('所有用例执行之前都会执行这里!')

    def tearDown(self):
        print('所有用例执行之后都会执行这里!')

    def test_add(self):
        result=self.myCalculator.add(1,2)
        self.assertEqual(result,3)
        print('执行了test_add测试用例')

    def test_minus(self):
        result=self.myCalculator.minus(3,2)
        self.assertEqual(result,1)
        print('执行了test_minus测试用例')

    def test_multiply(self):
        result=self.myCalculator.multiply(2,2)
        self.assertEqual(result,4)
        print('执行了test_multiply测试用例')

    def test_divide(self):
        result=self.myCalculator.divide(6,2)
        self.assertEqual(result,3)
        print('执行了test_divide测试用例')

上面代码就是针对于我们的计算器编写的单元测试代码,我们先导入了需要的模块,其中unittest模块是python自带的,所以直接导入即可;随后新建了一个类TestCalculator,然后又继承了unittest.TestCase,此时TestCalculator就变成了测试实例;其中的test_add,test_minus,test_multiply,test_divide分别是四个测试用例,每个测试用例均是调用了计算器中的功能,得到返回结果后,又与预期结果进行断言,如果断言成功则该用例执行成功,如果断言失败,则该用例执行失败。说到这,说一下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
assertIsNot(a, b)a is not b
assertIsNone(x)x is None
assertIsNotNone(x)x is not None
assertIn(a, b)a in b
assertNotIn(a, b)a not in b
assertIsInstance(a, b)isinstance(a,b)
assertNotIsInstance(a, b)not isinstance(a,b)

你会发现上面代码中多了两个方法setUp,teardown。他们就是我们要说的测试固件,什么是测试固件?简单来说就是测试固有的部分,也就是各个测试用例相同的部分。setup代表起始,teardown代表结束,这两个都是unittest.TestCase中的函数,我们是将它方法重写而已。这两个函数的代码会在每个测试用例执行的前后各执行一次。在例子中,初始化Calculate对象是各个用例的共同部分,便写在了setup中;如果没有setup,我们就需要在每个测试用例都进行初始化,比较麻烦。
除了setup和teardown,还需要了解两个固件:setUpClass和tearDownClass,这两个方法中的代码会在所有的用例执行前后各执行一次,注意,是所有的用例执行前后各执行一次,不是每个用例执行前后哦。还需要注意的是这两个方法都需要classmethod装饰器。

    @classmethod
    def setUpClass(cls):
        print("整个测试之前执行这里")

    @classmethod
    def tearDownClass(cls):
        print("整个测试之后执行这里")

测试套件

什么是测试套件?测试套件就是测试用例的集合。我们可以根据需求选取各个测试用例组成测试套件,然后运行该套件,便会执行套件中的各个用例。
有两种方法进行组合测试套件,第一种方法如下代码:这是一个返回测试套件的方法,先是初始化了unittest.TestSuite对象,随后建立了用例的列表,最后调用addTests()将用例列表添加到测试条件中,并将套件返回。

def makeSuite1():
        mySuite=unittest.TestSuite()
        myTestCases=[TestCalculator('test_add'),TestCalculator('test_minus'),
                     TestCalculator('test_divide'),TestCalculator('test_multiply')]
        mySuite.addTests(myTestCases)
        return mySuite

PS:你也可以调用addTest()进行一个测试用例的添加:

        mySuite.addTest(TestCalculator('test_add'))

另一种建立测试套件的方法是调用unittest.makeSuite(),如下代码:是将TestCalculator(类)中test开头的测试用例(函数)组合测试套件,并返回。

def makeSuite2():
        mySuite=unittest.makeSuite(TestCalculator,'test')
        return mySuite

那么这两种方法有什么区别呢?显而易见,第一种方法灵活,第二中方法方便;除此之外,第一种方法的用例执行顺序便是你添加的顺序,而二种方法的执行顺序是按照函数名除test之外的第一个字母在字母表中的顺序。

测试运行器

测试运行器,顾名思义,便是用来执行测试用例(套件)的。最常见的是TextTestRunner,它可以执行测试并将结果打印出来。我们先是初始化unittest.TextTestRunner对象,随用调用它的run()即可,传入的参数便是我们组成的测试套件。

if __name__=="__main__":
    runner=unittest.TextTestRunner()
    runner.run(makeSuite1())

运行结果如图:
执行成功的结果
执行失败的结果
是不是感觉测试结果不是很直观?接下来介绍一下HTMLTESTRunner,这是一个第三方模块,可以将运行结果形成html形式。需要注意的是该模块不能通过pip下载,需要在网上下载后放到python的安装目录lib文件夹下。该模块是基于python2开发的,如果在python3下使用,需要修改源码,这里不多赘述,可以参考https://www.cnblogs.com/miniren/p/5301081.html(感谢该作者)。

if __name__=="__main__":
    file=open("report.html","wb")
    runner=HTMLTestRunner.HTMLTestRunner(stream=file,title="测试报告",
                                         description="网页版的unittest测试报告")
    runner.run(makeSuite1())

上面的代码便是用HTMLTestRunner运行测试,先建立了一个html文件用于保存运行结果,随后初始化了HTMLTestRunner对象,最后调用run()执行测试。运行后会形成一个html文件,打开如图:
HTMLTestRunner运行结果图
UnitTest用起来是不是很简单呢?

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值