一 前言

 

        单元测试对软件开发来说也是相当重要,好的软件项目离不开单元测试。当然单元测试也是一项复杂的工程,在复杂的环境软件环境中,手写单元测试相当困难,所以学习一种好的测试框架对程序员来说非常必要。下面聊聊python 的基础测试框架unitest。

二 特性简介

       

unnittest_单元测试

三 uniteest核心原理

unittest最核心的四部分是:测试用例TestCase,测试套件TestSuite,测试运行器TestRunner,测试脚手架TestFixture

TestCase:一个独立的测试单元,检查输入特定的数据时的响应,需要继承unittest提供的基类:TestCase

TestSuite:测试用例集合,可以通过addTest()方法手动增加Test Case,也可以通过TestLoader自动添加Test Case,TestLoader在添加用例时,会没有顺序。

TestRunner:运行测试用例的驱动类,用于执行和输出测试结果的组件,可以执行TestCase,也可以执行TestSuite,执行后TestCase和TestSuite会自动管理TESTResult。

TestFixture:简单来说就是做一些测试过程中需要准备的东西,比如创建临时的数据库,文件和目录等,每个测试用例运行时都会调用一次setUp()、tearDown()、init()

整个的流程就是首先要写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由TestTestRunner来运行TestSuite,运行的结果保存在TextTestReusult中,整个过程集成在unittest.main模块中。

 

demo

unnittest_单元测试_02

 

unnittest_用例_03

unnittest_单元测试_04

 

unnittest_unnittest_05

 上面的代码演示了如何编写一个简单的测试,下面说一下怎么控制用例执行的顺序。我们就要用到TestCase,添加到TestCaseDE中的case是会按照添加的顺序执行的。并将结果输出到文件

unnittest_单元测试_06

 HTMLTestRunner python3版本安装

 pip install HTMLTestRunner-Python3

unnittest_unnittest_07

 

四 unitest 进阶 

return_vaule

mock 对象的 return_vaule 的作用:它将忽略 mock 对象的行为,指定其返回值。

mock可以添加为实现的方法

unnittest_unnittest_08

unnittest_用例_09

unnittest_用例_10

 

side_effect

mock 对象的side_effect 的作用:通过side_effect指定mock对象的副作用,这个副作用就是当你调用这个mock对象时会调用的函数,也可以选择抛出一个异常,来对程序的错误状态进行测试,指定为list等

unnittest_unnittest_11

patch装饰器

  它是一个装饰器,需要把你想模拟的函数写在里面,然后在后面的单元测试案例中为它赋一个具体实例,再用 return_value 来指定模拟的这个函数希望返回的结果就可以了

unnittest_unnittest_12

 @mock.pathc(模块名.“函数名”)

unnittest_unnittest_13

unnittest_单元测试_14

 如果 patch 多个外部函数,那么调用遵循自下而上的规则,比如:

unnittest_用例_15

 

五   前置后置测试代码


import unittestclass TestFixtures01(unittest.TestCase):    # 所有用例执行前执行
    def setUp(self) -> None:
        print("setUp开始")

    def tearDown(self) -> None:
        print("tearDown结束")

    # 每条用例执行前执行
    @classmethod
    def setUpClass(cls) -> None:
        print("setUpClass开始")

    在一个单独类的测试完成运行之后被调用的类方法   
    @classmethod
    def tearDownClass(cls) -> None:
        print("tearDownClass结束")

    # 测试用例
    def test_001(self):
        print("测试用例001")


class TestFixtures02(unittest.TestCase):
    def test_002(self):
        print("测试类2")


# 每个模块执行前执行
def setUpModule():
    """
    在所有测试类在调用之前会被执行一次,函数名是固定写法,会被unittest框架自动识别
    """
    print('集成测试 >>>>>>>>>>>>>>开始')


def tearDownModule():
    print("集成测试 >>>>>>>>>>>>>>结束")


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