【UnitTest】UnitTest的简单实现

市场上有很多的测试框架,选择哪款测试框架其实无所谓,只要能解决问题,就是好的测试方式。

UnitTest 原本是 python 自带的单元测试框架,在逐渐完善加强功能的过程中,成为目前自动化测试领域比较主流的框架。

官方文档:点这里

UnitTest 的一些概念

  • test fixture(测试固件)
    test fixture表示执行测试时所需的准备工作,以及相关的清理操作。比如,创建临时目录或启动服务器进程等操作。主要通过 setUp/tearDown 以及 setUpClass/tearDownClass 实现。
  • test case(测试用例)
    unittest提供了一个基类TestCase,创建新测试类的时候,必须要继承该基类。
  • test suite(测试套件)
    用于聚合一起执行的测试。即将需要执行的测试用例整合起来,作为一个测试集,使用命令可以直接执行该测试集。
  • test runner(测试执行器)
    test runner是用于执行测试并提供结果的组件,且可以通过图形界面、文本或返回特殊值来表示执行测试的结果。

UnitTest 的运行demo

  1. 导入unittest模块
  2. 创建一个测试类,并继承unittest模块中的TestCase类
  3. 定义测试用例,函数名以test开头
  4. 完善测试用例的代码逻辑,如增加断言机制
  5. 然后就可以运行啦
  • 测试demo
# 导入unitTest 默认库,这是python自带的库,不需要安装
import unittest
# 注意一定要继承基类 TestCase
class CasesDemo(unittest.TestCase):
    def test_1(self):
        print("test1")

    def test_2(self):
        print("test2")

    def test_3(self):
        print("test3")

if __name__ == "__main__":
	# 执行测试用例
    unittest.main()
  • 运行结果

运行结果

UnitTest 的一些基本规则

  • 所有的UnitTest类,如果需要使用,则一定要继承为TestCase类
  • TestCase中默认已经封装有很多的断言方法,可以直接调用,通过 self 进行调用
  • 所有用例都需要用test开头
    每一个以test开头的函数就是一个测试用例
    如图有 test_1,test_2,test_3 共三个测试用例
    在这里插入图片描述
  • 用例的运行顺序都是固定的模式,基于UnitTest本身的内部机制。目前是基于ASCII码的大小规则执行的:0-9<A-Z<a-z。
    在这里插入图片描述
  • setUp/tearDown的作用域分为两种,函数和类
  • setUpClass/tearDownClass
    • setUpClass:作用域为类,只在该类执行前先执行一遍
    • tearDownClass:作用域为类,只在该类执行后执行一遍
# 导入unitTest 默认库
import unittest
class CasesDemo(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        print("setUpClass\n")
        
    @classmethod
    def tearDownClass(cls) -> None:
        print("tearDownClass\n")

    def test_1(self):
        print("test1")

    def test_a(self):
        print("test2")

    def test_A(self):
        print("test3")

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

运行结果
运行结果

  • setUp/ tearDown
    • setUp:作用域为函数,在每个函数执行前均执行一遍
    • tearDown:作用域为函数,在每个函数执行后均执行一遍
# 导入unitTest 默认库
import unittest
class CasesDemo(unittest.TestCase):
    def setUp(self) -> None:
        print("setUp")

    def tearDown(self) -> None:
        print("tearDone")

    def test_1(self):
        print("test1")

    def test_a(self):
        print("test2")

    def test_A(self):
        print("test3")

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

运行结果
在这里插入图片描述

数据和代码分离

  • UnitTest通过ddt实现数据驱动。ddt,全称叫做data driver
    test,数据驱动测试,专门用于搭配数据驱动来实现的基于数据传递的自动化测试,通过装饰器的形式进行调用。
  • 所有的框架设计都会考虑数据和代码分离,而数据驱动的模式,就是实现代码与数据分离的

输入多个测试值

  • 如果只有一个参数,但需要输入多个测试值,可以使用该方法
# 导入unitTest 默认库
# 导入ddt,需要安装
import unittest
from ddt import ddt, data, unpack, file_data

@ddt
class CasesDemo(unittest.TestCase):
    """
    data装饰器: 将传入值基于','进行分割
    """
    # 输入多个测试值,使用','进行分割
    @data("xx", "eeee")
    def test_1(self, text):
        print("test1:%s" % text)

if __name__ == "__main__":
    unittest.main()
  • 测试结果:输入了两个测试值,相当于执行了两条测试用例。

在这里插入图片描述

输入多组测试值

  • 如果参数有多个,且需要输入多组测试值,就需要使用unpack进行二次分割
# 导入unitTest 默认库
import unittest
from ddt import ddt, data, unpack, file_data

@ddt
class CasesDemo(unittest.TestCase):

    """
    data装饰器: 将传入值基于','进行分割
    unpack: 二次分割
    """
    # 输入多组测试值
    @data(['kw1', "xxx"], ["kw", "ddd"])
    @unpack
    def test_2(self, kw, text):
        print("test_kw:%s" % kw)
        print("test_text:%s" % text)

if __name__ == "__main__":
    unittest.main()
  • 测试结果:输入了两组测试值,相当于执行了两条测试用例。

在这里插入图片描述

输入测试数据文件

  • yaml和excel是两种主流的测试用例管理,这里以yaml文件为例
# first_demo.py
# 导入unitTest 默认库
import unittest
from ddt import ddt, data, unpack, file_data

@ddt
class CasesDemo(unittest.TestCase):
    # 输入参数文件,param.yml为数据保存的yml文件,与代码保存在同一目录,均在test_case下
    @file_data('../test_case/param.yml') 
    def test_3(self, **kwargs):  # 直接传入数组
        input1 = kwargs["input"]
        button = kwargs["button"]
        print("test_inoput1:%s/%s/%s" % (input1["name"], input1["value"], input1["text"]))
        print("test_button:%s/%s" % (button["name"], button["value"]))

if __name__ == "__main__":
    unittest.main()
# param.yml
 - input:
    name: id
    value: test1
    text: 222
  button:
    name: id1
    value: su
 - input:
    name: testid
    value: eee
    text: eee
  button:
    name: testid1
    value: 222
  • 测试结果:文件中保存几组数据,就执行几次测试用例。该方法将测试数据从代码中分离了出来。
    在这里插入图片描述

多线程的实现

  • 方式1:通过@tomorrow装饰器实现
  • 方式2:通过threading模块实现

参考文献

【1】python自动化笔记(九)——unittest框架四大核心概念学习
【2】Python中的unittest模块


版权声明:本文为qq_38942551原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。