什么是单元测试
概念:单元测试是针对程序的最小单元来进行正确性检验的过程。
单元:一个单元可能是单个程序、类、对象、方法(函数)等。
优点
- 减少BUG
- 快速定位BUG
- 提高代码质量
- 减少调试时间
缺点
- 周期时间长
- 耗费资源
- 能力要求高
单元测试流程
A单元测试-计划
概念:对要测试代码的确定以及这些被测代码的评估标准、优先级等说明
- 确定要测试代码范围
依据:二八原则(20%的代码中隐藏了80%的缺陷)
如何确定20%代码
- 频率:使用频率高的代码段;
- 复用性:(是否已被复用)
1). 全新 2). 部分复用 3). 全部复用- 开发人员: 1). 技术 2). 业务
- 复杂度:业务逻辑复杂度(一般认为圈复杂度在7级以上代码包括在20%的代码中)
测试范围汇总格式:

- 评估标准(确定被测代码的覆盖率)
- 语句覆盖率(非分支非判断的代码)
计算方式:被覆盖语句/总语句 - 分支覆盖率(判断语句的分支;如:if判断有两个分支)
计算方式:覆盖分支/总分支数 - 条件覆盖率(结果为true或false)
计算方式:覆盖条件/总条件数 - 路径覆盖率(从开始到结束的过程)
计算方式:覆盖路径/全部路径 - 分支-条件覆盖率(分支和条件的组合)
计算方式:分支覆盖率+条件覆盖率
B 测试策略-设计
拿到开发代码进行调整(可独立执行)
- 概念:
针对单元测试选择测试的一种方式 - 方式:
- 自上向下(从最上层函数往下开始逐层测试,缺点:成本高)
- 自下向上(从最底层函数往上开始逐层测试,缺点:周期长)
- 孤立策略(选择需要进行测试的函数进行测试,优点:选择重要的代码进行测试)
- 打桩
概念:打桩就是模拟编写一个我们需要引用的函数
提示:一般我们只模拟写个函数名,直接返回相应的结果即可
C 测试策略-实现
1) 根据调整好的代码-画流程图
2) 根据流程图画流图-确定复杂度、路径
3) 根据复杂度和路径确定测试用例(测试数据)
- 概念:
把我们选定的代码,转向流程图、流图及用例的过程 - 测试策略实现如何操作
- 将测试代码转换成流程图
- 根据流程图转换为流图
- 什么是流图
概念:表达程序业务逻辑的复杂度一种示意图
构成:- 圈:判断条件、语句块(一条或多条语句)两者都圈
- 线:箭头指向的线,用来连接圈和圈的指向
- 流图的目的
- 确定单元的复杂度级别
- 确定测试用例
备注: 路径的个数为复杂度的级别(一条路径为1个复杂度级别)

- 测试用例模板

D 单元测试-执行
1) 使用测试框架(UnitTest)编写单元测试用例
2) 测试用例(代码)和测试数据分离
3) 生成测试报告
- 概念:
通过单元测试框架对要进行测试代码的实践过程 - 步骤:
- 导包
- setUp 函数作用
- tearDown 函数作用
- 断言
- 运行测试函数
-
案例:
通过Python语言编写一个运算的类(Calc),类中包含两个函数:- add(self,a,b) 返回a+b之和
- sub(self,a,c) 返回a-c之差
分析:
- 新建Calc类
- 在Calc类中新建add函数
- 在Calc类中新建sub函数
- 调用对象中方法
代码:
1. 导包 UnitTest 、Calc类
2. 新建单元测试类 Test01(集成 unitTest.TestCase)
3. 新建testAdd()函数
1). 导入Calc类中的add函数
2). 添加断言
4. 新建testSub()函数
1). 导入Calc类中的sub函数
2). 添加断言
5. 执行测试
1). unittest.main()
注意:
我们数据直接写入代码中,如果数量庞大,我们需要频繁改动数据或复制冗余代码进行实现数据测试目的。做不到数据分离(代码和数据分开),不便维护。
- 参数化
根据需求动态获取数据并进行赋值的过程 - 参数化方式:
-
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) 名称不能包含空格
步骤:- 导入XML包 from xml.dom import minidom
- 加载解析 dom=minidom.parse(filename)
- 获取对象 root=dom.documentElement
- 获取子元素 aas=root.getElementsByTagName(one)[0]
- 获取子元素值 aas.getElementsByTagName(two)[0].firstChild.data
读取方式:parse()
-
CSV格式(2)
概念:
CSV是一种以逗号做分割的表格格式; 后缀 .csv
步骤:- 导包 import csv
- 打开csv文件
with open("…/Data/sjx.csv",“r”,encoding=“utf-8”) as f:
lines=csv.reader(f)
读取方式;reader()
-
JSON串 (3)
概念:
一种轻量级数据交换格式;后缀名 .json
格式:
{“name”:“张三”,“age”:28}
提示:由键值对组成,健名和值之间使用分号(:)分割,多个键值对之间使用逗号(,)分割
步骤:- 导入JSON包(import JSON)
- 打开JSON文件并解析
with open(’…/DataXML/sjx.json’,‘r’,encoding=‘utf-8’) as f:
file=json.load(f)
读取方法 load()
-
TXT文本(4)
概念:
一种纯文本格式; 后缀名 .txt
优点:- 编写测试数据方便
- 使用模块函数读取时便捷
步骤:
- 如何读取txt文本?
with open(r’…/DataXML/三角形.txt’,‘r’,encoding=‘utf-8’) as f: - 如何去除行尾/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)
- 生成报告示例图

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

被折叠的 条评论
为什么被折叠?



