UnitTest 学习

news2024/11/18 3:28:11

UnitTest

    • 一、UnitTest 基本使用
      • 1. TestCase 测试用例
      • 2. TestSuite 和 TestRunner
      • 3. TestLoader 测试加载
      • 4. Fixture
    • 二、断言与参数化
      • 断言
      • 参数化
    • 三、测试报告
      • 获取项目的绝对路径
      • 登录案例
      • 跳过

一、UnitTest 基本使用

  1. UnItTest 框架介绍
    UnitTest是python自带的一个单元测试框架,测试人员也经常用来做自动化测试,用来管理和执行用例
  2. 使用的原因:
    能够组织多个用例去执行
    提供丰富的断言方法
    能够生成测试报告
  3. 核心要素
1. TestCase 测试用例,这个测试用例是unittest的组成部分,作用是用来书写真正的用例代码(脚本)
2. Testsuite 测试套件,作用是用来组装(打包)Testcase的,即可以将多个用例脚本文件组装到一起
3. TestRunner 测试执行,作用是用例执行 Testsuite(测试套件)的
4. TestLoader 测试加载,是对Testsuite (测试套件)功能的补充,作用是用来组装(打包)Testcase的
5. Fixture 测试夹具,是一种代码结构,书写前置方法(执行用例之前的方法)代码和后置方法(执行用例之后的方法)代码

1. TestCase 测试用例

书写真正的用例代码(脚本)

  • 步骤
    • 导包 unnitest:import unittest
    • 定义测试类,需要继承unittest.TestCase类,习惯性类名以Test开头
    • 书写测试方法,必须以test开头
    • 执行
  • 注意事项
    代码的文件名字,需要满足标识符的规则
'''
TestCase 测试用例的使用
'''
import unittest


# 继承unittest.TestCase类,就是测试类
class TestDemo(unittest.TestCase):
    # 书写测试方法,方法名必须以test开头
    def test_method1(self):
        print("测试方法1")

    def test_method2(self):
        print("测试方法2")

# 执行 在类名或者方法名后右键运行
# 在主程序使用 unittest.main()来执行
if __name__ == '__main__':
    unittest.main()

2. TestSuite 和 TestRunner

  1. TestSuite (测试套件)
    将多条用例脚本集合在一起,就是套件,即用来组装用例的
  • 步骤
    – 导包 unittest
    – 实例化套件对象 unittest.TestSuite()
    – 添加用例方法
  1. TestRunner (测试执行)
  • 步骤
    – 导包 unittest
    – 实例化执行对象 unittest.TextTestRunner()
    – 执行对象执行套件对象 执行对象.run(套件对象)
import unittest
# 实例化套件对象
from day0610.testcase import TestDemo
# 实例化套件对象
suite = unittest.TestSuite()

# 添加用例方法
# 套件对象.addTest(测试类名('测试方法名'))
suite.addTest(TestDemo('test_method1'))
suite.addTest(TestDemo('test_method2'))

# 添加整个测试类
# 套件对象.addTest(unittest.makeSuite('测试类名'))
suite.addTest(unittest.makeSuite(TestDemo))

# 实例化执行对象
runner = unittest.TextTestRunner()
# 执行对象执行  执行对象.run(套件对象)
runner.run(suite)

3. TestLoader 测试加载

作用和TestSuite一样,组装用例代码,同样也需要TextTestRunner()去执行

import unittest
# 实例化加载对象并加载用例,得到套件对象
# suite = unittest.TestLoader().discover('用例所在的目录','用例代码文件名.py')
suite = unittest.TestLoader().discover('.','testcase.py')
# 实例化执行对象并执行
# runner = unittest.TextTestRunner()
# runner.run(suite)
unittest.TextTestRunner().run(suite)
  • TestLoader 和 TestSuite的区别
    • TestSuite
      灵活,方便控制要执行的测试用例,但是需要手动添加测试用例
    • TestLoader
      可以自动搜索满足条件的测试用例,不方便控制要执行的测试用例

4. Fixture

在用例执行前后会自动执行的代码结构

  • 方法级别 Fixture
    在每个用例执行前后都会自动调用,方法名是固定的
 # 每个用例执行前都会自动调用
    def setUp(self): # 前置
        pass

    # 每个用例执行后都会自动调用
    def tearDown(self): # 后置
        pass
  • 类级别 Fixture
    在类中所有的测试方法执行前后,会自动执行的代码,只执行一次
@classmethod
def setUpClass(cls): # 类前置
    pass

@classmethod
def tearDownClass(cls): # 类后置
    pass
  • 模块级别 Fixture(了解)
    在代码文件执行前后执行一次
def setUpModule():
    pass
    
def tearDownModule():
    pass

二、断言与参数化

跳过:某些用例由于某种原因不想执行,设置为跳过
生成测试报告:suite和runner(第三方)

断言

断言:使用代码自动地判断预期结果和实际结果是否相符

  • assertEqual(预期结果,实际结果)
    判断预期结果和实际结果是否相等,如果相等,用例通过;如果不相等,抛出异常,用例不通告
  • assertIn(预期结果,实际结果)
    判断预期结果是否包含在实际结果中,如果存在,用例通过;如果不存在,抛出异常,用例不通告
import unittest
class TestAssert(unittest.TestCase):
    def test_equal_1(self): 
        self.assertEqual(10, 10) # 用例通过

    def test_equal_2(self):
        self.assertEqual(10, 11) # 用例不通过

    def test_in(self):
        self.assertIn('admin', '欢迎admin登录')  # 用例通过
  • 使用suite来运行
import unittest
from day0610.demo4 import TestAssert

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAssert))
unittest.TextTestRunner().run(suite)

参数化

参数化:将测试数据定义到json文件,使用

  • 通过参数的方式来传递数据,从而实现数据和脚本分离,并且可以实现用例的重复执行(在书写用例方法时,测试数据使用变量代替,在执行的时候进行数据传递)
  • unittest测试框架,本身不支持参数化,但是可以通过安装unittest扩展插件parameterized来实现
  • 环境准备
    因为参数化的插件,不是unittst自带的,所以想要使用需要进行安装,python中的包(插件、模块)的安装,使用 pip 工具
    pip install parameterized # 在cmd终端中执行
    tips: pip install -i https://pypi.douban.com/simple/ parameterized 可以临时指定pip下载源
  • 使用
    1.导包 from para… import para…
    2.修改测试方法,将测试方法中的测试数据使用变量表示
    3.组织测试数据,格式[(),(),()] 一个元组就是一组测试数据
    4.参数化,在测试方法上方使用装饰器 @parameterized.expand(测试数据)
    5.运行(直接 TestCase 或者使用 suite 运行)

  • add_data.json 要使用的数据
[
  [1,1,2],
  [1,2,3],
  [4,1,5],
  [2,3,5],
  [4,5,9]
]
  • 读取json文件,并返回需要的数据
import json

def build_add_data():
    with open('add_data.json') as f:
        data = json.load(f)  # [[],[],[]] ---> [(),(),()]
    return data
  • 使用数据
class TestAdd(unittest.TestCase):
    @parameterized.expand(build_add_data())
    def test_add(self,a,b,expect):
        print(f'a:{a}:,b:{b},expect:{expect}')
        self.assertEqual(expect, add(a, b))
  • 复杂的数据格式处理
[
  {
    "a": 1,
    "b": 2,
    "expect": 3
  },
...
]
def build_add_data_1():
    with open('add_data_1.json') as f:
        data_list = json.load(f)  # [{},{},{}}] ---> [(),(),()]
        new_list = []
        for data in data_list:
            # 简化写法,因为字典里所有值都是我们需要的,如果有某些值不需要,再使用get获取所需的键值
            new_list.append(tuple(data.values()))
            # a = data.get('a')
            # b = data.get('b')
            # expect = data.get('expect')
            # new_list.append((a,b,expect))
        return new_list

三、测试报告

HTML测试报告:执行完测试用例之后,以HTML方式将执行结果生成报告

  • 安装
    pip install HTMLTestReport
  • 使用
    1.导包 unittest、HTMLTestReport
    2.组装用例(套件、loader)
    3.使用HTMLTestReport中的runner执行套件
    4.查看报告
import unittest
from htmltestreport import HTMLTestReport

# 套件
from day0610.demo6 import TestAdd

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAdd))

# 运行对象
# runner = HTMLTestReport(报告文件路径.html,报告标题,其他描述信息)
runner = HTMLTestReport('test_repoet.html','加法用例测试报告','描述信息')
runner.run(suite)

在这里插入图片描述

获取项目的绝对路径

  • 项目是分目录书写的,使用相对路径,可能会出现找不到文件的情况,此时需要使用相对路径
  • 方法:
    1.在项目的根目录中,创建一个python文件(app.py)
    2.在这个文件中,获取项目的目录,在其他代码中使用路径拼接完成绝对路径的书写
    获取当前文件的绝对路径:abspath = os.path.abspath(_file_)
    获取文件路径的目录名称:dirname = os.path.dirname(filepath)
import os

# __file__ 特殊的变量,表示当前代码文件名
path1 = os.path.abspath(__file__) # D:\PyCharm\Code\studyType\day0610\app.py
print(path1)

path2 = os.path.dirname(path1) # D:\PyCharm\Code\studyType\day0610
print(path2)

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

登录案例

  1. 对登录函数进行测试,登录函数定义在tool.py中
  2. 在case中书写测试用例对login函数 进行测试,使用断言
  3. 将login函数的测试数据定义在json文件中,完成参数化(data目录)
  4. 生成测试报告,在report目录中
  • 登录函数
def login(username,password):
    if username == 'admin' and password == '123456':
        return '登录成功'
    else:
        return '登录失败'
  • 测试数据
# login_data.json
[
  {
    "desc": "正确的用户名和密码",
    "username": "admin",
    "password": "123456",
    "expect": "登录成功"
  },
  {
    "desc": "错误的用户名",
    "username": "root",
    "password": "123456",
    "expect": "登录失败"
  },
  {
    "desc": "错误的密码",
    "username": "admin",
    "password": "123",
    "expect": "登录失败"
  },
  {
    "desc": "错误的用户名和密码",
    "username": "root",
    "password": "123",
    "expect": "登录失败"
  }
]
  • 读取数据的方法
# read_data.py
def build_login_data():
    with open(BASE_DIR+'/data/login_data.json',encoding='utf-8') as f:
        data_list = json.load(f)
        new_list = []
        for data in data_list:
            # 字典中的desc不需要
            username = data.get('username')
            password = data.get('password')
            expect = data.get('expect')
            new_list.append((username,password,expect))
        return new_list
  • 测试用例代码
# test_login.py
import unittest

from day0610.commom.read_data import build_login_data
from day0610.tool import login
from parameterized import parameterized

class TestLogin(unittest.TestCase):
    @parameterized.expand(build_login_data())
    def test_login(self,username,password,expect):
        print(f'username:{username},password:{password},expect:{expect}')
        self.assertEqual(expect,login(username,password))
  • Suite代码
# login.py
import unittest

from day0610.app import BASE_DIR
from day0610.case.test_login import TestLogin
from htmltestreport import HTMLTestReport

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestLogin))

runner = HTMLTestReport(BASE_DIR+'/report/login.html','登录的测试报告')
runner.run(suite)

跳过

对于一些未完成的或者不满足测试条件的测试函数和测试类,可以跳过执行

  • 使用方法
    直接将函数标记成跳过:@unittest.skip(‘跳过的原因’)
    根据条件判断测试函数是否跳过:@unittest.skipif(condition,reason)
import unittest

version = 10


class TestSkip(unittest.TestCase):
    @unittest.skip('不想执行')
    def test_1(self):
        print('方法1')

    @unittest.skipIf(version >= 30, '版本号大于等于30,方法不执行')
    def test_2(self):
        print('方法2')

    def test_3(self):
        print('方法3')


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/634144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTTP 和 HTTPS 协议原理【网络基础】

文章目录 1. HTTP 的优点2. HTTP 的缺点明文可能会被窃听通信方可能被伪装报文可能被篡改 2.1 弥补 HTTP 的缺点(概述)加密明文通信加密内容加密 验证通信方报文完整性校验 3. HTTPS 协议3.1 SSL/TLS 协议概述3.2 加密机制对称加密非对称加密混合加密 3.…

一文终结SQL 子查询优化

概要 子查询(Subquery)的优化一直以来都是 SQL 查询优化中的难点之一。关联子查询的基本执行方式类似于 Nested-Loop,但是这种执行方式的效率常常低到难以忍受。当数据量稍大时,必须在优化器中对其进行去关联化(Decoor…

深入理解深度学习——Transformer:基础知识

分类目录:《深入理解深度学习》总目录 相关文章: 作为当下最先进的深度学习架构之一,Transformer被广泛应用于自然语言处理领域。它不单替代了以前流行的循环神经网络(recurrent neural network, RNN)和长短期记忆(long short-term memory, …

网络安全入门学习第十七课——PHP数组

文章目录 一、索引数组二、关联数组三、数组定义1、多维数组2、赋值方式3、短数组定义法([ ] PHP 5.4起增加的) 四、访问数组五、遍历数组1、使用 for 循环2、foreach语句遍历 六、合并两个数组1、“”联合运算符2、array_combine 函数 七、数组排序函数八、数组增删…

redis 全系列目录

redis常用资源_存在,及合理的博客-CSDN博客Redis 官网 推荐CRUG网站redis 中文 官网Spring Data Redis 客户端工具官网Distributed Locks with Redis | Redishttps://github.com/redisson/redisson 分布式锁实现大数据高并发Redis一本通-张文亮编著-微信读书 书籍推荐https://b…

Misc(三)

LSB 这题没见过,是看的wp 首先了解LSB是什么 LSB简介 最低有效位( least significant bit,LSB)指的是一个二进制数字中的最低位。最低有效位和最高有效位是相对应的概念。LSB是一种常被用做图片隐写的算法。LSB属于空域算法中的一…

学成在线----day6

1、断点续传 断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上…

【文生图系列】Stable Diffusion原理篇

文章目录 Stable Diffusion的组成什么是扩散扩散是如何工作的去噪声绘制图像将文本信息添加到图像生成器中参考 “文生图”,或者AI绘画,最近异常火爆,输入一些描述性的语句,AI就能够生成相应的画作。甚至引发了一个问题&#xff1…

智能饮品柜颠覆升级,点赋科技引领行业跨越式发展

智能科技的迅速发展,不断改变人们的生活方式和商业模式,在众多领域迎来了新的机会和挑战。其中,饮品行业聚集了大量的消费者和商家,成为了一个具有广泛发展空间和潜力的市场。而在这个市场上,点赋科技认为智能饮品柜作…

ARM基础(3):MPU内存保护单元详解及例子

MPU(Memory Protection Unit)是ARM处理器中的一个特性,它提供了内存保护和访问控制的功能,通常用于实现操作系统的内存隔离和保护。比如我们可以设置所有的RAM为不可执行,这样就可以避免代码注入攻击。最近做项目过程中,使用的几个…

深度研究微软的资产负债表和财务状况以及未来投资价值

来源:猛兽财经 作者:猛兽财经 微软股票的关键指标 猛兽财经认为,微软公布的2023财年第三季度财务业绩,有三个关键指标值得投资者关注。 第一个关键指标是利息收入。微软的利息收入目前已经同比增长了44%,从2022财年第…

【Kubernetes存储篇】常见存储方案及场景分析

文章目录 一、持久化存储理论1、为什么要做数据持久化存储?2、常见持久化存储方案 二、案例:持久化存储方案1、emptydir临时存储卷2、hostPath本地存储卷3、NFS网络共享存储卷 一、持久化存储理论 官方中文参考文档: 1、为什么要做数据持久…

【三、网络配置与系统管理】

1 网络配置 ifconfig 显示网络接口的配置信息 [rootredis100 ~]# ifconfig ens33: flags4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.10.100 netmask 255.255.255.0 broadcast 192.168.10.255inet6 fe80::f5c3:6a96:fe05:1965 prefixlen 64 scop…

该怎么学Python?自学Python的方法和资料整理!

导语 Python 作为一门简洁、易学且功能强大的编程语言&#xff0c;备受程序员和初学者的喜爱。如果你也想学习 Python&#xff0c;但不知从何入手&#xff0c;本文将为你整理一些自学 Python 的方法&#xff0c;助你快速入门并掌握这门语言。 为什么学习Python&#xff1f;&a…

【2023华中杯】C题 空气质量预测与预警 56页论文及Python代码

【2023华中杯】C题 空气质量预测与预警 56页论文及Python代码 1 题目 空气污染对人类健康、生态环境、社会经济造成危害&#xff0c;其污染水平受诸多因素的影响&#xff0c; 如 PM2.5、PM10、CO、气温、风速、降水量等&#xff0c;探究 PM2.5 等污染物浓度的因素&#xff0c…

POI导出Excel (满满的干货啊)

已经实现的POI导出Excel 步骤一&#xff1a;导入依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi…

【js】js前端技巧之图片格式转换(File、Blob、base64):

文章目录 一、类型简介二、BLOB 与 File&#xff1a;【1】BLOB 转 File【2】File 转 BLOB 三、 BLOB 与 base64&#xff1a;【1】BLOB(url) 转 base64【2】base64 转 BLOB 四、File 与 base64&#xff1a;【1】File 转 base64【2】base64 转 File 五、案例&#xff1a; 一、类型…

AWS CodeWhisperer 心得体会:安装与使用

大家好&#xff0c;今天我要和大家分享一下我在使用 AWS CodeWhisperer 这个工具时的心得体会。首先&#xff0c;让我们了解一下什么是 AWS CodeWhisperer。 什么是 AWS CodeWhisperer&#xff1f; AWS CodeWhisperer 是一个用于帮助开发者在 AWS 云平台上更轻松地编写、测试…

从源码全面解析 dubbo 服务订阅的来龙去脉

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小黄&#xff0c;独角兽企业的Java开发工程师&#xff0c;CSDN博客专家&#xff0c;阿里云专家博主&#x1f4d5;系列专栏&#xff1a;Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

LearnOpenGL-高级光照-1.Blinn-Phong

本人初学者&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 文章目录 高级光照Phong光照的缺点Blinn-Phong介绍例子 GLSL中遇到的BUG 高级光照 Phong光照的缺点 造成Phong光照缺点的两个条件 当物体的高光反光度&#xff08;shiness&#xff09;比较小时 什么是高光…