单元测试01

本篇博客

1. 测试方法分类
2. 为什么要做单元测试,以及适用项目
3. UT开展
4. UT计划(逻辑覆盖率重要)
  4.1 语句覆盖率
  4.2 分支覆盖率
  4.3 条件覆盖率
  4.4 路径覆盖率
  4.5 分支-条件覆盖率
5. UT设计
  5.1 自顶向下
  5.2 自底向上
  5.3 孤立策略
6. UT实现(重要)
  6.1 根据代码画流程图
  6.2 根据流程图画出流图(圈和线)
  6.3 确定路径
  6.4 编写测试用例

1. 测试方法分类

测试方法分类:
注意:评估标准

1) 按照是否执行进行分类:

静态测试

动态测试

2) 按照测试手段分类:

手工测试

自动化测试

3)按照测试对象进行分析:

黑盒

对象:系统功能测试
优点:简单
缺点:介入时间晚,发现重大bug时难以修复
评估标准:需求覆盖率100%

灰盒
对象:系统模块间接口
优点:介入时间早于黑盒测试
缺点:需要测试有相应的代码能力
评估标准:接口覆盖率


白盒
对象:代码,函数
优点:介入时间早
缺点:测试人员需要由代码能力
评估标准:逻辑覆盖率

2为什么要做单元测试,以及适用项目

价值:提前介入测试,发现代码级别的bug
适用项目
1.大型的、项目周期长
2.新系统、新团队
3.涉及财产、生命的项目

3 UT开展

UT开展:UT计划,UT设计,UT实现,UT执行

4 UT计划

确定单元测试范围
依据标准:二八原则
20%的代码中隐藏了80%的缺陷


如何确定20%的代码?

  • 使用频率:高
  • 复用性:全新的
  • 开发人员背景:弱
  • 业务:不熟
  • 复杂度:一般认为复杂度在7级以上的为20%的代码

可以写下面的excel。判断哪些为20%代码需要做单元测试。

确定评估标准:逻辑覆盖率

逻辑覆盖率:语句覆盖率,分支覆盖率,条件覆盖率,路径覆盖率,分支-条件覆盖率

4.1 语句覆盖率

什么是语句:非分支分判断


练习:输入数字,判断是否大于0,如果大于0那么对该数字+1,否则-1

# 提示用户输入
num = int(input('请输入数字:'))

if num > 0:
    num += 1

else:
    num -= 1

全部的语句:3个(输入代码,执行-1操作,执行+1操作)

输入数字3,语句覆盖率:2⁄3

输入数字-1,语句覆盖率:2⁄3


计算方式:被测的语句/全部的语句

4.2 分支覆盖率

分支:if语句的两个分支
计算方式:被测试的分支个数/全部的分支个数

总的分支数:判断框个数*2

练习:输入数字,判断是否大于0,如果大于0那么对该数字+1,否则-1

总的分支数:2

输入数字5,分支覆盖率:1⁄2。

4.3 条件覆盖率  

什么是条件:结果为True或者False
计算方式:被测条件数/全部条件数 

练习1:输入用户名:admin  and  密码:123 登陆成功,否则失败。

条件1 and 条件2:条件1成立了才判断条件2 ,条件1失败了,就不判断条件2了。条件1,条件2都成立了,条件才成立。

# 条件覆盖率
# 请输入用户名和密码
username = input('请输入用户名')
password = input('请输入密码')

if username == 'admin' and password == '123':
    print('登陆成功')


else:
    print('登陆失败')

 

总的条件数:4个(条件框:username,passwd。都有两种结果)

输入数据:admin 123456 条件覆盖率为:2⁄4。(不能写1⁄2

输入数据:zhang 123456 条件覆盖率为:1⁄4。(第一个条件失败了,第二个条件就不判断了)

输入数据:admin 654321 条件覆盖率为:2⁄4。

练习2:输入用户名:admin  or  密码:123 登陆成功,否则失败。

条件1 or 条件2:条件1成立了不用判断条件2 ,条件1失败了,才判断条件2。条件1,条件2只要一个成立,条件就成立。

# 条件覆盖率
# 请输入用户名和密码
username = input('请输入用户名')
password = input('请输入密码')

if username == 'admin' or password == '123':
    print('登陆成功')

else:
    print('登陆失败')

 

总的条件数:4个(条件框:username,passwd。都有两种结果)

输入数据:admin 123456 条件覆盖率为:1⁄4。

输入数据:zhang 123456 条件覆盖率为:2⁄4。

输入数据:admin 654321 条件覆盖率为:1⁄4。

4.4 路径覆盖率

什么是路径:从开始到结束的过程
计算公式:被测路径数/全部路径数

被测路径数:一定为1 (一个测试用例肯定一条路径开始到结束。)

4.5 分支-条件覆盖率 

分支-条件:分支和条件的组和
计算方式
被测分支数+被测条件数/全部分支数+全部条件数

通俗:分子+分子    分母+分母

练习1:直接上图

 输入a=3, b=6   条件覆盖率:FFT 3/8

 输入a=6, b=3   条件覆盖率:TT 2/8

 输入a=6, b=6   条件覆盖率:TFFT 4/8

 输入a=6, b=3   路径覆盖率:1/3

 输入a=6, b=6   分支-条件覆盖率:6/12  (分支覆盖率:2/4  条件覆盖率:4/8)

练习2:直接上图

输入数据:admin 123456 条件覆盖率:3/8

输入数据:fghsja 123456 条件覆盖率:2/8

数据:admin 654321

语句覆盖率:4/6

分支覆盖率:2/4

条件覆盖率:3/8

分支-条件覆盖率:5/12

路径覆盖率:1/4

5 UT设计

UT设计按测试策略:
1)自顶向下
从最上层函数开始逐层开展测试
注意:需要对函数中调用的函数打桩(模拟调用的函数)
测试成本高


2)自底向上
从最下层的函数开始逐层向上开展测试
测试周期长


3)孤立策略(推荐)
选择需要进行测试函数即可

6 UT实现

UT实现测试用例产生过程:

1.先将测试的代码转为流程图


2.将流程图转化为流图(流图中只有圈和线)

:判定框中的条件     或者   一条或者多条语句

判定框中的条件:一个条件一个圈(条件1 and 条件2 :两个圈)

一条或多条语句:如果多条语句写在一起的就是一个圈。

线:带有箭头指向的连接


通过流图描述的是程序的复杂度(圈复杂度)
路径的个数描述的就是复杂度的级别


3.确定测试路径


4.编写测试用例

1)if 语句

def test001(a):

    if a > 0:
        print('高伟光')
    # 复杂度:2

上左:流程图        上右:流图

复杂度:2   

2) if else语句

def test002(a):
    if a > 0:
        print('高伟光')
        print('伟光')
    else:
        print('迪丽热巴')

    # 复杂度:2

复杂度:2   

路径:1-3-4   1-2-4

用例数为:2  

练习:if else 语句2

def test004(a,b):
    if a > 0 and b > 0:
        print('高伟光')
        print('伟光')
    else:
        print('迪丽热巴')

    # 复杂度:3

复杂度:3级

路径:

1-2-3-5

1-4-5

1-2-4-5

练习:if else语句3

def test003(a,b):
    if a > 0 or b > 0:
        print('高伟光')
        print('伟光')
    else:
        print('迪丽热巴')

    # 复杂度:3

复杂度:3级

路径:

1-3-5

1-2-3-5

1-2-4-5

练习:if 嵌套if语句  判断三角形

# 输入三条边,判断是等边,等腰,普通三角形

def sjxpd(a,b,c):

    if a + b > c and a + c > b and b + c > a:

        if a == b and b == c:
            print('等边三角形')
     
elif a == b or b == c or a == c:
print('等腰三角形') else: print('普通三角形') else: print('不是三角形') sjxpd(3,3,2) sjxpd(3,3,3)

圈圈的参考:

1:a+b>c

2:a+c>b

3:b+c>a

(路径1,路径2,路径3 and(与) 的关系)

4:a==b 

5:b==c

(路径4,路径5 and(与) 的关系)

6:等边三角形

7:a==b

8:b==c

9:a==c

(路径7,路径8,路径9 or(或) 的关系)

10:等腰三角形

11:普通三角形

12:不能组成三角形

13:结束

思考为什么7-9路径不行?

3)while循环:1-10的求和

# 1- 10 之前的求和

i = 1
sum = 0
while i <= 10:

    sum+= 1
    i += 1

print(sum)

复杂度:2级

路径:

1-2-4-5

1-2-3-2-4-5

4)elif语句:输入数字判断求和求差

a = int(input('输入第一个数字:'))
b = int(input('输入第二个数字:'))

if a > 0 and a < 10 and b >= 0 and b < 10:
    print(a+b)

elif a > 10 and a < 20 and b >= 10 and b < 20:
    print(a-b)

else:
    print('输入有误')

圈圈的参考:

1:输入,输入

2、3、4、5:条件一,条件二,条件三,条件四(if里的条件)

6:求和

7、8、9、10:条件一,条件二,条件三,条件四(elif里的条件)

11:求查

12:输入错误

13:结束

路径:8+1=9       条件个数+1

1:     1-2-7-12-13

2:     1-2-7-8-12-13

3:     1-2-7-8-9-12-13

4:     1-2-7-8-9-10-12-13

5:     1-2-7-8-9-10-11-13

6:      1-2-3-7

7:      1-2-3-4-7

8:      1-2-3-4-5-7

9:      1-2-3-4-5-6-13

注意:路径6、路径7、路径8并没有到结束,到7的.。前面路径1-5都是从7出发到结尾,所以没必要再搞一遍。

路径数一般都是:条件个数+1  

也要特例:如果条件冲突,也有可能实际路径总数比计算的路径数总数(条件个数+1)少一点。后面就有这样的例子。

也有特例:可能有的时候,实际比计算的多,那就是有的重复了,那就是多一点测试用例。最主要的就是把该测的都要测到。多也可要,也可不要。

原文地址:https://www.cnblogs.com/zhangyangcheng/p/12526939.html