暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

接口测试与开发实战(二十三)_unittest 一

305

一、什么是unittest

unittest是Python内置标准库、主要用于单元测试,类似于JUnit框架。

二、测试组件化

unittest 中内置有5个组件、我们通常分别叫它们为:TestCase(测试用例)、TestSuite(测试用例套件)、TestFixture(测试固件)、TestLoader(测试加载器)、TestRunner(测试执行器)

在学习unittest之前我们一定要知道unittest的五大组件概念

那么我们就来看看测试组件化的具体内容吧!

TestCase:

一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码 (run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。

TestSuite:

多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite、用于组织管理所有的测试用例。

TestRunner:

是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。

TestLoader:

是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。

TestFixture:

对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖 TestCase的setUp()和tearDown()方法来实现。这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUp() 中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的 TestCase留下一个干净的环境。关于fixture,还有一个专门的库函数叫做fixtures,功能更加强大。

使用unittest编写python的单元测试代码,包括如下几个步骤:

1、编写一个python类,继承 unittest模块中的TestCase类,这就是一个测试类

2、在上面编写的测试类中定义测试方法(这个就是指的测试用例),每个方法的方法名要求以 test 打头,没有额外的参数。在该测试方法中 调用被测试代码,校验测试结果,TestCase类中提供了很多标准的校验方法,如 最常见的assertEqual。

3、执行 unittest.main() ,该函数会负责运行测试,它会实例化所有TestCase的子类,并运行其中所有以test打头的方法。

基本工作原理

1、首先需要定义一个测试类、并进行继承至unittest.TestCase类

2、再需要进行定义带有test_开头的方法、该方法则被当做为一个测试用例

3、定义完测试用例后在运行时会由TestLoader类进行加载定义好的测试类、并进行从中查找带有test_开头的方法,并且将带有test_开头的方法进行加载到TestSuite类中集中管理

4、然后再由TestRunner类中的run()进行执行TestSuite中的所有测试用例集

5、最后再将TestRunner执行完后的测试用例后再将结果进行传递给TestResult类进行输出测试结果

6、以上所有的操作都集成到了unittest.main()方法中进行处理

TestCase类

是定义测试用例的基类、在进行定义一个测试用例时都需要进行集成至该类;

测试固件

TestCase类中有四个测试固件方法分别是:

我们可以看到unittest源码中定义的四个方法

这里是部分核心代码源码

class TestCase(object):

    failureException = AssertionError

    longMessage = True

    maxDiff = 80*8

    # 如果一个字符串比_diffThreshold长,则使用普通比较
    # of difflib.  See #11763.
    _diffThreshold = 2**16

    # TestSuite用于类设置的属性

    _classSetupFailed = False

    _class_cleanups = []

    def __init__(self, methodName='runTest'):
        """
        """

        self._testMethodName = methodName
        self._outcome = None
        # 获取的是test方法中的描述内容
        self._testMethodDoc = 'No test'
        try:
            testMethod = getattr(self, methodName)
        except AttributeError:
            if methodName != 'runTest':
                # we allow instantiation with no explicit method name
                # but not an *incorrect* or missing method name
                raise ValueError("no such test method in %s: %s" %
                      (self.__class__, methodName))
        else:
            self._testMethodDoc = testMethod.__doc__
        self._cleanups = []
        self._subtest = None
        .......

 
 # 四个测试固件方法
    def setUp(self):
        "在每次测试用例执行前执行一次"
        pass

    def tearDown(self):
        "在每次测试用例执行完成后执行一次"
        pass

    @classmethod
    def setUpClass(cls):
        "在每次测试用例类执行前执行一次"

    @classmethod
    def tearDownClass(cls):
        "在每次测试用例类执行后执行一次"

   
    ...........

复制

方法详解

方法

描述

示例

setUp(self)

在每次测试用例执行前执行一次


tearDown(self)

在每次测试用例执行完成后执行一次


setUpClass(cls)

在每次测试用例类执行前执行一次

需要使用@classmethod装饰

tearDownClass(cls)

在每次测试用例类执行后执行一次

示例1:

重写TestCase中的setUp tearDown

import unittest


class MyTest(unittest.TestCase):

    def setUp(self):
        print("每条测试用例开始执行前执行")
        
        
    def test_case(self):
        print("我是测试用例1")
        
        
    def tearDown(self):
        print("每条测试用例执行结束后开始执行")

复制

可以看到setUp方法是在每条用例开始前执行一次、tearDown方法是在每条测试用例执行后都会执行一次

示例2:

重写TestCase中的setUpClass tearDownClass

在使用setUpClass与tearDownClass二个方法前需要进行使用@classmethod装饰才生效

classmethod 修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。

import unittest


class MyTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        print("整个测试类中之在开始执行测试方法前执行一次")


    def test_case(self):
        print("我是测试用例1")

    def test_case1(self):
        print("我是测试用例2")


    @classmethod
    def tearDownClass(cls):
        print("在整个测试类中所有测试用例执行完后才执行")

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

复制


文章转载自测试前沿布道者,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论