0


单元测试学习

回顾测试理论基础

单元测试基础知识

什么是单元测试

单元测试流程、测试计划

测试策略设计、实现

单元测试-执行

HTML报告生成

1软件测试分类

目标

回顾测试理论知识-测试分类

**1. **测试分类 代码可见度上-划分分类:

  1. 黑盒测试

  2. 灰盒测试

  3. 白盒测试

**1.1 **黑盒测试

作用:是针对整个产品系统进行的测试,验证系统是否满足需求规格的定义,及软件产品的正确性和性能等

是否满

足其需求规格的要求。

**1.2 **灰盒测试

作用:是介于白盒测试与黑盒测试之间的一种测试,灰盒测试多用于集成测试阶段,不仅关注输出、输入的

正确性

,同时也关注程序内部的情况。

**1.3 **白盒测试

作用:是通过程序的源代码进行测试而不使用用户界面。这种类型的测试需要从代码内部在算法,路径,条件等等中的缺点或者错误,进而加以修正。

2单元测试基础

**1.1 **案例

  1. 组装一台电脑,选购各种配件(CPU、主板、内存、硬盘、电源)等,组装完成后,电脑运行启动无反应。

  2. 编写一个程序,编写完成程序运行不起来(程序由N个不同功能函数和语句组成)

**1.2 **问题

  1. 无法确定各配件哪个有问题。

  2. 无法确定那个函数或语句出现问题。

**2. **什么是单元测试?

概念:单元测试是针对程序的最小单元来进行正确性检验的过程。

单元:一个单元可能是单个程序、类、对象、方法(函数)等。

**2.1 **优点:
  1. 减少BUG

  2. 快速定位BUG

  3. 提高代码质量

  4. 减少调试时间

**2.2 **缺点:
  1. 周期时间长

  2. 耗费资源

  3. 能力要求高

**3. 单元测试-**总结

  1. 概念

  2. 优点

  3. 缺点

5

如何进行单元测试

目标

  1. 了解单元测试流程

如何进行单元测试?

单元测试流程
  1. 单元测试-计划
  1. 确定要测试代码范围

  2. 评估标准(确定被测代码的覆盖率)

  1. 测试策略-设计
  1. 拿到开发代码进行调整(可独立执行)
  1. 测试策略-实现
  1. 根据调整好的代码-画流程图

  2. 根据流程图画流图-确定复杂度、路径

  3. 根据复杂度和路径确定测试用例(测试数据)

  1. 单元测试-执行
  1. 使用测试框架(UnitTest)编写单元测试用例

  2. 测试用例(代码)和测试数据分离

  3. 生成测试报告

**1. 单元测试-**计划

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

    1. 确定单元测试范围(那些代码要做单元测试) 

    2. 评估标准-(被测代码的逻辑覆盖率) 
**1.1 **如何确定单元测试代码范围?

依据:二八原则(20%的代码中隐藏了80%的缺陷)

如何确定**20%**代码?
    1. 频率:使用频率高的代码段; 

    2. 复用性:(是否已被复用) 

            1). 全新 

            2). 部分复用 

            3). 全部复用 

    3. 开发人员: 

            1). 技术 

            2). 业务 

    4. 复杂度:业务逻辑复杂度(一般认为圈复杂度在7级以上代码包括在20%的代码中) 
如何确定圈复杂度等级?
    圈复杂度:在学习测试策略实现时讲解 
附录**-**测试范围汇总格式

**1.2 **评估标准
    如何确定逻辑覆盖率? 

            1. 语句覆盖率 

            2. 分支覆盖率 

            3. 条件覆盖率 

            4. 路径覆盖率 

            5. 分支-条件覆盖率 

练习**1 **

提示用户输入一个数,如果该数大于0则加1,否则减1;

代码:

#提示用户输入一个数,如果该数大于0则加一,如果小于0则减一

num=int(input("请输入一个数:"))
if num>0:
    num=num+1
elif num<=0:
    num=num-1
print("num的值为:"+str(num))

流程图:

流程图
    说明:使用统一规定标准图形,描述程序运行的具体步骤 

    目的: 

            1) 确定覆盖率 

            2) 根据流程图画流图 (流图-->测试策略实现时学习) 

什么是语句覆盖率?
    语句:非分支非判断的代码 
练习**1 **测试数据
    1. 输入 3=2/3

    2. 输入 0=2/3

    3. 输入 -2=2/3
语句覆盖率**-**总结
    1. 语句 

    2. 计算方式:被覆盖语句/总语句 
分支覆盖率
    分支:判断语句的分支;如:if判断有两个分支 
练习**1 **分支覆盖率测试数据

本题有两个分支

    1. 输入 3=1/2

    2. 输入 0=1/2

    3. 输入-2=1/2
分支覆盖率**-**总结
    1. 分支 

    1. 计算方式:覆盖分支/总分支数 
条件覆盖率

条件:结果为true或false

练习**2 **

输入用户名和密码,如果用户名为:admin,密码为:123456,输出验证成功;否则输出验证失败;

代码:

#输入用户名和密码,如果用户名为:admin,密码为:123456,输出验证成功;否则输出验证失败;
username=input("请输入用户名:")
password=input("请输入密码:")
#注意input输入的是字符串类型
if username=="admin" and password=="123456":
    print("验证成功")
else:
    print("验证失败")

流程图:

练习2分析

  1. 条件个数

练习2测试数据

  1. 用户名:admin 密码:123456

  2. 用户名:zhangsan 密码:123456

  3. 用户名:admin 密码:456789

练习**3 **

输入两个数a,b,如果a>5 and b<5 执行语句3;否则 elif a==5 or b<10 执行语句4;否则执行语句5

代码:

流程图:

练习3分析

  1. 条件个数

练习3测试数据

  1. a=3,b=6

  2. a=6,b=3

  3. a=6,b=6

练习**4 **

9输入用户名和密码:

如果 username= "admin" and password="123456" 执行语句3;否则执行语句4

如果 username= "zhangsan" and password="654321" 执行语句5;否则执行语句6

练习4分析

  1. 条件个数

练习4测试数据

  1. 用户名:admin 密码:123456

  2. 用户名:zhang 密码:123456

路径覆盖率

路径:从开始到结束的过程

分析练习2路径

  1. 路径个数

分析练习3路径

  1. 路径个数

练习3路径覆盖数据

  1. a=6,b=3

路径覆盖率**-**总结

  1. 路径概念

  2. 计算方式:覆盖路径/全部路径

  3. 路径和分支区别

分支**-**条件覆盖率

10说明:分支和条件的组合

练习2测数据 分支**-**条件覆盖率

  1. 用户名:admin 密码:123456

分析练习**2 分支-**条件覆盖率

  1. 分支个数

  2. 条件个数

  3. 分支条件个数

练习3测试数据 分支**-**条件覆盖率

  1. a=6,b=6

练习3分析 分支**-**条件覆盖率

  1. 分支个数

  2. 条件个数

  3. 分支条件个数

练习**4 **汇总

  1. 语句覆盖率

  2. 分支覆盖率

  3. 条件覆盖率

  4. 路径覆盖率

  5. 分支条件覆盖率

提示:

练习4:路径有4条,但有一条永远不可成立,所以路径为3条;

练习**4 **测试数据

  1. 用户名:admin 密码:123456

11**1.3 **测试策略设计、实现

目标

  1. 了解单元测试-测试策略

**1. **什么是单元测试策略?

概念:针对单元测试选择测试的一种方式

**2. 单元测试策略-**方式

  1. 自上向下

  2. 自下向上

  3. 孤立策略

**2.1 **策略 自上向下

方式:从最上层函数往下开始逐层测试

案例**1 **

两个函数(求和、求减),求和函数内调用求减函数;

案例1分析

  1. 编写求和函数

  2. 编写求减函数

  3. 在求和函数内调用求减函数

  4. 调用求和函数

案例**1 **问题

  1. 我们只想测试求和函数不测求减函数该如何做?

打桩

概念:打桩就是模拟编写一个我们需要引用的函数

提示:一般我们只模拟写个函数名,直接返回相应的结果即可

示例:

def fun_1(self):

return true

自上向下**-**总结:

  1. 方式

  2. 打桩(模拟调用的函数)

  3. 缺点(成本高)

**2.2 **策略 自下向上

方式:从最底层函数往上开始逐层测试

自下向上**-**总结:

  1. 方式

  2. 缺点(周期长)

**2.3 **策略 孤立策略

方式:选择需要进行测试的函数进行测试

孤立策略**-**总结:

  1. 方式

  2. 【推荐使用】

  3. 优点:选择重要的代码进行测试

**3. **测试策略实现

13**3.1 **什么是测试策略实现?

概念:把我们选定的代码,转向流程图、流图及用例的过程

**3.2 **测试策略实现如何操作?

  1. 将测试代码转换成流程图

  2. 根据流程图转换为流图

案例**2 **

函数(test001)判断参数a,如果a>0,输出语句1;

案例**2 **流程图

什么是流图?

概念:表达程序业务逻辑的复杂度一种示意图

构成:

  1. 圈:判断条件、语句块(一条或多条语句)两者都圈

  2. 线:箭头指向的线,用来连接圈和圈的指向

流图的目的?

  1. 确定单元的复杂度级别

  2. 确定测试用例

备注: 路径的个数为复杂度的级别(一条路径为1个复杂度级别)

14案例**2 **流图

测试用例 模板

案例**2 **总结

  1. 路径:2 (1-2-3,1-3)

  2. 复杂度:2

  3. 用例个数:2

案例**3 **

函数(test002)判断参数a,b;如果a>0 and b<10 输出语句1;否则输出语句2;

代码:

流程图:

流图:

案例**3 **总结

  1. 复杂度

  2. 路径明细

思考?

15如果把案例3的条件 a>0 and b<10 换成 条件1 or 条件2 那么复杂度是多少?

案例**4 **

输入两个数,如果两个数同时为大于0小于10,那么就进行求和运算;否则判断两个数是否同时大于等于10小

于20那么

就进行求减运算,否则输入错误;

代码:

流程图:

流图:

案例**4 **总结

  1. 路径数:

  2. 路径明细:

  3. 复杂度:

案例5 while循环

使用while循环求1-10相加之和;

代码:

流程图:

流图:

案例**5 **总结

  1. 路径数:

  2. 路径明细:

  3. 复杂度:

案例**6 **

提示输入三角形三条边,进行判断三角形类型(等边、等腰、普通)并进行提示,否则提示不是三角形;

提示:

三角形:两边之和大于第三边;

16等腰三角形:两条边相等

等边三角形:三条边相等

案例**6 **步骤分析

  1. 代码:
  1. 自定义函数

  2. 判断是否为三角形

  3. 判断是否为等边三角形

  4. 非等边三角形继续判断是否为等腰三角形

  5. 如果不是等腰三角形,输出普通三角形

  1. 流程图

  2. 流图

  3. 用例

总结

  1. 单元测试计划

  2. 测试策略设计

  3. 测试策略实现

17**1.4 单元测试-**执行

目标

  1. 回顾UnitTest框架使用

  2. 基于UnitTest测试三角形案例

  3. 在UnitTest框架中使用数据分离

什么是单元测试执行?

概念:通过单元测试框架对要进行测试代码的实践过程

**1. 练习1 **

  1. 通过Python语言编写一个运算的类(Calc),类中包含两个函数:
  1. add(self,a,b) 返回a+b之和

  2. sub(self,a,c) 返回a-c之差

提示:通过练习1,我们先简单复习下UnitTest框架的使用

**1.1 练习1 **步骤分析

  1. 新建Calc类

  2. 在Calc类中新建add函数

  3. 在Calc类中新建sub函数

  4. 调用对象中方法

**1.2 练习1 **单元测试

  1. 导包 UnitTest 、Calc类

  2. 新建单元测试类 Test01(集成 unitTest.TestCase)

  3. 新建testAdd()函数

1). 导入Calc类中的add函数

182). 添加断言

  1. 新建testSub()函数

1). 导入Calc类中的sub函数

2). 添加断言

  1. 执行测试

1). unittest.main()

**1.3 **总结

  1. 导包

  2. setUp 函数作用

  3. tearDown 函数作用

  4. 断言

  5. 运行测试函数

**1.4 **问题

  1. 练习1我们数据直接写入代码中,如果数量庞大,我们需要频繁改动数据或复制冗余代码进行实现数据测

试目的。

  1. 做不到数据分离(代码和数据分开),不便维护;

参数化

概念:根据需求动态获取数据并进行赋值的过程

**2. 参数化-**方式

  1. XML格式(1)

  2. CSV格式(2)

  3. JSON串 (3)

  4. TXT文本(4)

提示:括号内为推荐使用优先级,从小到大;1-2为扩展了解,3-4建议重点了解

3. XML是什么?

概念:XML是一种标记语句,很类似HTML标记语言;后缀 .xml

193.1 XMLHTML区别?

XML是传输和存储数据,焦点在数据;HTML是显示数据,焦点在外观;

3.2 XML格式是什么?

<?xml version="1.0" encoding="UTF-8"?><book category="面授"> <title>单元测试</title>

<author>XST</author>

<year>2008</year>

<price>39.95</price>

</book>
  1. 必须有XML声明语句:<?xml version="1.0" encoding="UTF-8"?>

  2. 必须要有一个根元素,如:<book>

  3. 标签大小写敏感

  4. 属性值用双引号

  5. 标签成对

  6. 元素正确嵌套

  7. 标签名可随意命名,但有以下限制

  1. 不能以数字或者标点符号开始参

2)不能以字符 “xml”(或者 XML、Xml)开始

  1. 名称不能包含空格

**3.3 **需求

对三角形案例单元测试使用XML格式进行参数化

**3.4 **操作步骤

  1. 编写XML数据文件

  2. 编写读取XML模块函数

  3. 单元测试模块中引用XML读取函数

  4. 执行

**3.5 **重点分析

  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

**3.6 XML-**总结

  1. 读取方式

  2. 什么是XML

  3. XML与HTML区别

  4. XML编写格式

  5. 缺点:不适合大量参数化数据时使用

4. CSV格式

概念:CSV是一种以逗号做分割的表格格式; 后缀 .csv

4.1 使用CSV实现三角形案例参数化**-**操作步骤

  1. 创建CSV文件

  2. 编写CSV读取模块函数

  3. 单元测试-引用CSV读取函数

  4. 执行

**4.2 **重点分析

  1. 导包 import csv

  2. 打开csv文件

with open("../Data/sjx.csv","r",encoding="utf-8") as f:

lines=csv.reader(f)

**4.3 CSV-**总结

  1. 读取方式

  2. 生成CSV文件方式

  3. 编码

215. 什么是JSON

概念:一种轻量级数据交换格式;后缀名 .json

提示:

接口测试一般使用JSON为接口传递数据规范格式,所以我们有必要对如何获取JSON数据做个了解;

5.1 JSON格式

格式:{"name":"张三","age":28}

提示:由键值对组成,健名和值之间使用分号(:)分割,多个键值对之间使用逗号(,)分割

5.2 使用JSON实现三角形案例参数化**-**操作步骤

  1. 编写JSON文件

  2. 编写JSON读取模块函数

  3. 单元测试-引用JSON读取函数

  4. 执行

**5.3 **难点分析

  1. 导入JSON包(import JSON)

  2. 打开JSON文件并解析

with open('../DataXML/sjx.json','r',encoding='utf-8') as f:

file=json.load(f)

**5.4 JSON-**总结

  1. JSON概念

  2. JSON格式

  3. 如何导入JSON包

  4. 如何加载JSON

6. TXT文本

概念:一种纯文本格式; 后缀名 .txt

6.1 TXT文本优点:

  1. 编写测试数据方便

  2. 使用模块函数读取时便捷

6.2 使用TXT实现三角形案例参数化**-**操作步骤

  1. 创建txt文本并写入测试数据

  2. 编写读取txt模块函数

  3. 单元测试-引用JSON读取函数

  4. 执行

**6.3 **难点分析

  1. 如何读取txt文本?

with open(r'../DataXML/三角形.txt','r',encoding='utf-8') as f:

  1. 如何去除行尾/n换行符?

line.strip()

6.4 TXT总结

  1. TXT文本读取

  2. 去除行尾回车符(/n)

**7. 参数化-**总结

  1. XML

  2. CSV

  3. JSON

  4. TXT

23HTML报告生成

目标

对单元测试生成HTML报告进行简单回顾

1. 如何生成HTML报告?

1.1. 导入HTML报告模板模板

HTMLTestRunner.py

1.2 编写生成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='Tes

t Case Report')

runner.run(disconver)

**1.3 **生成报告示例图

2425

标签: 单元测试 log4j

本文转载自: https://blog.csdn.net/qq_51250393/article/details/134173339
版权归原作者 哒哒等等 所有, 如有侵权,请联系我们删除。

“单元测试学习”的评论:

还没有评论