单元测试

单元测试是对程序最小单元的正确性检验,如函数、类或方法。其优点包括减少BUG、快速定位问题和提高代码质量。流程包括计划、设计、实现和执行。在计划阶段,确定测试代码范围,考虑频率、复用性和复杂度。设计阶段选择测试策略,如自顶向下、自底向上或孤立策略,并进行打桩。实施时将测试代码转换为流程图和用例,执行阶段使用单元测试框架进行实践。参数化测试中,常见的数据格式有XML、CSV、JSON和TXT。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是单元测试

概念:单元测试是针对程序的最小单元来进行正确性检验的过程。
单元:一个单元可能是单个程序、类、对象、方法(函数)等。

优点

  1. 减少BUG
  2. 快速定位BUG
  3. 提高代码质量
  4. 减少调试时间

缺点

  1. 周期时间长
  2. 耗费资源
  3. 能力要求高

单元测试流程

A单元测试-计划

概念:对要测试代码的确定以及这些被测代码的评估标准、优先级等说明

  • 确定要测试代码范围
    依据:二八原则(20%的代码中隐藏了80%的缺陷)
    如何确定20%代码
  1. 频率:使用频率高的代码段;
  2. 复用性:(是否已被复用)
    1). 全新 2). 部分复用 3). 全部复用
  3. 开发人员: 1). 技术 2). 业务
  4. 复杂度:业务逻辑复杂度(一般认为圈复杂度在7级以上代码包括在20%的代码中)

测试范围汇总格式:
在这里插入图片描述

  • 评估标准(确定被测代码的覆盖率)
  1. 语句覆盖率(非分支非判断的代码)
    计算方式:被覆盖语句/总语句
  2. 分支覆盖率(判断语句的分支;如:if判断有两个分支)
    计算方式:覆盖分支/总分支数
  3. 条件覆盖率(结果为true或false)
    计算方式:覆盖条件/总条件数
  4. 路径覆盖率(从开始到结束的过程)
    计算方式:覆盖路径/全部路径
  5. 分支-条件覆盖率(分支和条件的组合)
    计算方式:分支覆盖率+条件覆盖率
B 测试策略-设计

拿到开发代码进行调整(可独立执行)

  • 概念:
    针对单元测试选择测试的一种方式
  • 方式:
  1. 自上向下(从最上层函数往下开始逐层测试,缺点:成本高)
  2. 自下向上(从最底层函数往上开始逐层测试,缺点:周期长)
  3. 孤立策略(选择需要进行测试的函数进行测试,优点:选择重要的代码进行测试)
  • 打桩
    概念:打桩就是模拟编写一个我们需要引用的函数
    提示:一般我们只模拟写个函数名,直接返回相应的结果即可
C 测试策略-实现
    1) 根据调整好的代码-画流程图
    2) 根据流程图画流图-确定复杂度、路径
    3) 根据复杂度和路径确定测试用例(测试数据)
  • 概念:
    把我们选定的代码,转向流程图、流图及用例的过程
  • 测试策略实现如何操作
  1. 将测试代码转换成流程图
  2. 根据流程图转换为流图
  • 什么是流图
    概念:表达程序业务逻辑的复杂度一种示意图
    构成:
    1. 圈:判断条件、语句块(一条或多条语句)两者都圈
    2. 线:箭头指向的线,用来连接圈和圈的指向
  • 流图的目的
    1. 确定单元的复杂度级别
    2. 确定测试用例
      备注: 路径的个数为复杂度的级别(一条路径为1个复杂度级别)
      在这里插入图片描述
  • 测试用例模板
    在这里插入图片描述
D 单元测试-执行
    1) 使用测试框架(UnitTest)编写单元测试用例
    2) 测试用例(代码)和测试数据分离
    3) 生成测试报告
  • 概念:
    通过单元测试框架对要进行测试代码的实践过程
  • 步骤:
  1. 导包
  2. setUp 函数作用
  3. tearDown 函数作用
  4. 断言
  5. 运行测试函数
  • 案例:
    通过Python语言编写一个运算的类(Calc),类中包含两个函数:

    1. add(self,a,b) 返回a+b之和
    2. sub(self,a,c) 返回a-c之差

    分析:

    1. 新建Calc类
    2. 在Calc类中新建add函数
    3. 在Calc类中新建sub函数
    4. 调用对象中方法

    代码:

1. 导包 UnitTest 、Calc类
2. 新建单元测试类 Test01(集成 unitTest.TestCase)
3. 新建testAdd()函数
        1). 导入Calc类中的add函数
        2). 添加断言
4. 新建testSub()函数
        1). 导入Calc类中的sub函数
        2). 添加断言
5. 执行测试
        1). unittest.main()

注意:
我们数据直接写入代码中,如果数量庞大,我们需要频繁改动数据或复制冗余代码进行实现数据测试目的。做不到数据分离(代码和数据分开),不便维护。

  • 参数化
    根据需求动态获取数据并进行赋值的过程
  • 参数化方式:
    1. XML格式(1)缺点:不适合大量参数化数据时使用
      概念:
      XML是一种标记语句,很类似HTML标记语言;后缀 .xml
      规则:
      1. 必须有XML声明语句:<?xml version="1.0" encoding="UTF-8"?>
      2. 必须要有一个根元素,如:
      3. 标签大小写敏感
      4. 属性值用双引号
      5. 标签成对
      6. 元素正确嵌套
      7. 标签名可随意命名,但有以下限制
      1) 不能以数字或者标点符号开始参
      2)不能以字符 “xml”(或者 XML、Xml)开始
      3) 名称不能包含空格
      步骤:

      1. 导入XML包 from xml.dom import minidom
      2. 加载解析 dom=minidom.parse(filename)
      3. 获取对象 root=dom.documentElement
      4. 获取子元素 aas=root.getElementsByTagName(one)[0]
      5. 获取子元素值 aas.getElementsByTagName(two)[0].firstChild.data
        读取方式:parse()
    2. CSV格式(2)
      概念:
      CSV是一种以逗号做分割的表格格式; 后缀 .csv
      步骤:

      1. 导包 import csv
      2. 打开csv文件
        with open("…/Data/sjx.csv",“r”,encoding=“utf-8”) as f:
        lines=csv.reader(f)
        读取方式;reader()
    3. JSON串 (3)
      概念:
      一种轻量级数据交换格式;后缀名 .json
      格式:
      {“name”:“张三”,“age”:28}
      提示:由键值对组成,健名和值之间使用分号(:)分割,多个键值对之间使用逗号(,)分割
      步骤:

      1. 导入JSON包(import JSON)
      2. 打开JSON文件并解析
        with open(’…/DataXML/sjx.json’,‘r’,encoding=‘utf-8’) as f:
        file=json.load(f)
        读取方法 load()
    4. TXT文本(4)
      概念:
      一种纯文本格式; 后缀名 .txt
      优点:

      1. 编写测试数据方便
      2. 使用模块函数读取时便捷

      步骤:

      1. 如何读取txt文本?
        with open(r’…/DataXML/三角形.txt’,‘r’,encoding=‘utf-8’) as f:
      2. 如何去除行尾/n换行符?
        line.strip()
        读取方法:readlines()
        注意:去除行尾回车符(/n)

HTML报告生成

  • 导入HTML报告模板模板
HTMLTestRunner.py
  • 编写生成HTML模块
 # 导入unittest包
    import unittest
    # 导入 HTMLTestRunner模板包
    from UnitTest.Day02.ReadData.HTMLTestRunner import HTMLTestRunner
    #导入时间包
    import time
    # 定义测试模块路径
    dirpath='.'
    disconver=unittest.defaultTestLoader.discover(dirpath,pattern='test*.py')
    if __name__=='__main__':
        #存放报告的文件夹
        report_dir='../TestReport'
        #报告名称含时间,时间格式
        now=time.strftime("%Y-%m-%d %H_%M_%S")
        #报告完整路径+名称
        report_name=report_dir+'/'+now+'result.html'
        #打开报告写入结果
        with open(report_name,'wb')as f:
            runner=HTMLTestRunner(stream=f,title="UnitTest Report-SJX",description='Test Case Report')
            runner.run(disconver)
  • 生成报告示例图
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值