unittest框架

前言

  本次内容主要介绍单元测试框架unittest。

一、什么是单元测试?

  就是对一些函数或者类进行测试的过程。

二、单元测试框架的作用?

  • 收集用例
  • 处理断言
  • 测试报告

三、unittest相关概念

1、TestCase

  测试用例。

2、TestSuite

  测试套件。

3、TestLoader

  测试用例加载器。

4、TestRunner

  运行器、执行器。主要用于初始化运行器

5、Fixture

  测试夹具,测试固件。定义在测试类的下面,主要用于测试环境的准备和清理工作,包含有setUp(在每个测试用例执行之前会执行的代码),tearDown(在每个测试用例执行之后会执行的代码),setUpClass(在每个测试类之前只执行一次的代码,需要使用@classmethod声明),tearDownClass(在每个测试类之后只执行一次的代码,需要使用@classmethod声明)四个函数。

四、unittest框架的简单应用

 上图为本次讲解需要用到的相关模块,其中”run_test“是unittest自带的,导入第三方库BeautifulReport生成测试报告。report.html是测试报告文件。

模块1:test_add.py

复制代码
def add(a, b):
    return a + b


# 1,导入 unittest, 是python内置的
import unittest

# 2, 测试类
#TestAdd继承TestCase
class TestAdd(unittest.TestCase):
    def test_add_success(self):
        a = 3
        b = 4
        expected = 7
        actual = add(a, b)
        # unittest 已经实现好的断言方式
        self.assertEqual(expected, actual)
复制代码

模块2:test_login.py

复制代码
import unittest

#定义login()
def login(username=None, password=None):
    if username is None or password is None :
        return {"code": "400", "msg": "用户名或密码为空"}
    if username == 'xiao' and password == '123456':
        return {"code": "200", "msg": "登录成功"}
    return {"code": "300", "msg": "用户名或密码错误"}

#定义测试类,包含4条测试用例
class TestLogin(unittest.TestCase):
    def test_login_success(self):
        username = 'xiao'
        password = '123456'
        expected = {"code": "200", "msg": "登录成功"}
        actual = login(username, password)
        self.assertEqual(expected, actual)

    def test_login_fail1(self):
        username = ''
        password = '123456'
        expected = {"code": "400", "msg": "用户名或密码为空"}
        actual = login(username, password)
        self.assertEqual(expected, actual)

    def test_login_fail2(self):
        username = 'xiao'
        password = ''
        expected = {"code": "400", "msg": "用户名或密码为空"}
        actual = login(username, password)
        self.assertEqual(expected, actual)

    def test_login_fail3(self):
        username = 'xiao'
        password = '123'
        expected = {"code": "300", "msg": "用户名或密码错误"}
        actual = login(username, password)
        self.assertEqual(expected, actual)
复制代码

模块3:run_test.py

复制代码
#导入unittest模块
import unittest
from unittestreport import TestRunner
#TestSuite 测试套件,存储所有的测试用例 #初始化测试套件 suite = unittest.TestSuite() #加载所有的测试用例 loader = unittest.TestLoader() #发现用例 cases = loader.discover(r"./") #将找到的所有测试用例加载到suite suite.addTest(cases) #运行用例 #初始化运行器 # runner = unittest.TextTestRunner() # runner.run(suite) runner = TestRunner(suite,
            filename="output.html",
            tester="小疯狗",
            templates=2
)
runner.run()
复制代码

 五、数据驱动DDT

  为了解决上述模块例如test_login.py中出现的多个测试用例复用同一套测试代码逻辑,提出了数据驱动ddt。以使用不同的测试数据驱动相同的测试业务,也就是说多组数据使用同一个测试函数,且测试用例之间相互独立。可以使用unittestreport中的ddt和list_data,也可以安装第三方库ddt中的ddt和data来实现。@ddt要放在测试类的上面,@list_data要放在测试函数的上面,且@ddt和@list_data是配套使用的。

代码如下:

test_login.py

复制代码
import unittest
from unittestreport import ddt,list_data
from openpyxl_read import openpyxl_read

def login(username=None, password=None):
    if username is None  or password is None:
        return {"code": "400", "msg": "用户名或密码为空"}
    if username == 'xiao' and password == '123456':
        return {"code": "200", "msg": "登录成功"}
    return {"code": "300", "msg": "用户名或密码错误"}
#读取测试数据 new_cases
= openpyxl_read() @ddt class TestLogin(unittest.TestCase): @list_data(new_cases) def test_login_success(self,new_case):#new_case是每条测试用例数据 username = new_case["username"] password = new_case["password"] expected = eval(new_case["expected"]) actual = login(username, password) self.assertEqual(expected, actual)
复制代码

openpyxl_read.py

此模块用于读取excel中的测试数据,代码如下:

复制代码
import openpyxl
from openpyxl.worksheet.worksheet import Worksheet

def openpyxl_read():
    #1、打开文件
    workbook = openpyxl.load_workbook("cases.xlsx")
    #2、获取标签
    sheet:Worksheet=workbook["Sheet1"]
    #3、获取所有的数据内容

    values = list(sheet.values)
    #将列表嵌套元组转成嵌套字典
    title = values[0]
    rows = values[1:]
    #列表推导式
    # new_cases=[dict(zip(title,row))for row in rows]
    new_cases=[]
    for row in rows:
        new_case=dict(zip(title,row))
        new_cases.append(new_case)
    return new_cases
复制代码

cases.xlsx内容如下

 六、数据驱动框架的意义

  • 提高代码的复用率
  • 异常排查效率高,且每条用例相互独立
  • 代码的可维护性高
posted @   小疯狗  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示