高效测试用例组织算法pairwise之Python实现

------------------------------------------本文专为《光荣之路培训 》原创,如有转载请注明出处----------------------------------

开篇:

  测试过程中,对于多参数参数多值的情况进行测试用例组织,之前一直使用【正交分析法】进行用例组织,说白了就是把每个参数的所有值分别和其他参数的值做一个全量组合,用Python脚本实现,就是itertools模块中product方法(又称笛卡尔积法)。

  正交分析法的优点是测试用例覆盖率100%,缺点测试用例数量庞大,执行用例消耗的人工巨大。

  Pairwise (结对)算法源于对传统的正交分析方法优化后得到的产物,它的理论来自于数学统计。毫不避讳的说,本人看不懂数学统计中的学术论文,只能从网上找一些通俗简单的说法来理解其基本含义。

  网上很多人都实例都是用  【操作系统,浏览器,语言环境】来举例的,本人也做同样示例:

    操作系统: W(Windows),L(Linux),Mac (Mac) ;浏览器:M(Firefox),O(Opera),IE;语言环境:C(中文),E(英文)

  按照正交分析法:会产生3x3x2=18种组合方式 ,测试用例覆盖率100%。

  Pairwise结对测试用例组织法,可压缩到9种组合方式。因此有点是 测试用例数量少,缺点是一定会有漏测。

引论:

  Pairwise算法的核心理念

    1、一组测试用例(每个用例有3个参数的值组成,如[W,M,C])中每一个2个元素组合起来,两两组合,就有3种组合方式(有位置的[W,M][W,C][M,C]);

    2、如果这第一组测试用两两组合出的3种组合方式,对比原则:[W,M]只会和其他组的第一个元素对比,[W,C]只会和其他组中第二个元素对比。。。。;

          [W,M][W,C][M,C]这三个元素分别出现在其余有效组位置相同的元素中,就可以认为这一组Case为多余Case,并进行删除。

      名词解释:【有效组】表示未被删除的组和未被对比过的组。举例:第1,3组被删除,则第4组要对比的有效组为第2,5,6,7...18组。有效组这里踩过坑%>_<%

    3、最终得到测试用例,就是结对算法计算出来的最优测试用例集合。

  牛逼闪闪的学术证明   

      Pairwise是L. L. Thurstone(29 May1887 – 30 September 1955)在1927年首先提出来的。他是美国的一位心理统计学家。Pairwise也正是基于数学统计和对传统的正交分析法进行优化后得到的产物。

    Pairwise基于如下2个假设:

      (1)每一个维度都是正交的,即每一个维度互相都没有交集。

      (2)根据数学统计分析,73%的缺陷(单因子是35%,双因子是38%)是由单因子或2个因子相互作用产生的。19%的缺陷是由3个因子相互作用产生的。

    因此,pairwise基于覆盖所有2因子的交互作用产生的用例集合性价比最高而产生的。

正文

  一、思路

  对一个测试场景如何从何从输入被测条件,到产出Pairwise测试用例,使用Python编程思路如下:

  1、将allparams=[[‘M‘,‘O‘,‘P‘],[‘W‘,‘L‘,‘I‘],[‘C‘,‘E‘]]进行笛卡尔积全组合处理,生成正则分析法产生的全量测试用例集合的一维数组(len=N);

  2、将全量测试用例中的每个测试用例,都进行两两组合的分解处理,生成与全量测试用例集合 长度相同的二维数组(一维 len=N);

  3、使用Python版Pairwise算法剔除无效测试用例,最终得到有效的结对测试用例集合;

  代码第1,2函数利用Python自带数学计算库itertools编写,代码第3函数为本人死磕出来的代码。

  二、直接上代码

  

 1 # -*- coding: utf-8 -*-
 2 from datetime import *
 3 import random,os,copy,time
 4 import logging
 5 import itertools
 6 ‘‘‘
 7 #Author:Kuzaman
 8 #Time:2017-07-18
 9 ‘‘‘
10 class utils2 :
11     #1、笛卡尔积 对参数分组全排列
12     def product(self,tuple1):
13         newlist=[]
14         for x in eval(‘itertools.product‘+str(tuple(tuple1))):
15             newlist.append(x)
16         return newlist
17
18     #2、对笛卡尔积处理后的二维原始数据进行N配对处理,得到Pairwise计算之前的数据
19     def get_pairslist(self,lista):
20         pwlist = []
21         for i in lista:
22             subtemplist = []
23             for sublista in itertools.combinations(i, 2):
24                 subtemplist.append(sublista)
25             pwlist.append(subtemplist)
26         return pwlist
27
28     #3、进行Pirwise算法计算
29     def pairwise(self,listb):
30         sublistlen = len(listb[1])
31         flag = [0]*sublistlen
32         templistb = copy.deepcopy(listb)
33         delmenu = []
34         holdmenu=[]
35         self.pprint (listb)
36         print (‘--‘*25)
37         for lb in listb:
38             for sublb in lb:
39                 for k in templistb:
40                     Xa = lb.index(sublb)
41                     Ya = listb.index(lb)
42                     if k != lb and sublb == k[Xa]:
43                         # print (sublb,‘===>‘ ,k[Xa],‘相等了。。。‘)
44                         flag[Xa] = 1
45                         break
46                     else:
47                         # print (sublb,‘===>‘ ,k[Xa],‘不不不等了。。。‘)
48                         flag[Xa] = 0
49             # print (‘下标%d,子元素 %s 双匹配对比结果flag:%s‘%(listb.index(lb),lb,flag))
50             if 0 not in flag:
51                 num = listb.index(lb)
52                 delmenu.append(num)
53                 templistb.remove(lb)
54                 # print (‘下标为%d行应删除,内容=%s,‘%(num,lb))
55                 # print (‘delmenu:‘,delmenu)
56             else:
57                 num2 = listb.index(lb)
58                 holdmenu.append(num2)
59                 # print (‘下标为%d行应保留,内容=%s,‘%(num2,lb))
60                 # print(‘holdmenu=‘,holdmenu)
61             # print (‘***‘*20)
62         print (‘保留元素列表:%s \n匹配重复元素列表:%s‘%(holdmenu,delmenu))
63         return templistb
64
65     def pwresult(self,slist,delmenu):
66         for  x in delmenu:
67             slist.remove(slist[x])
68         return slist
69
70     def pprint(self,list):
71         for i in list:
72             print (‘line %d:‘%(list.index(i)+1),i)
73
74 if __name__ == ‘__main__‘:
75     u2 = utils2()
76     allparams=[[‘M‘,‘O‘,‘P‘],[‘W‘,‘L‘,‘I‘],[‘C‘,‘E‘]]#,‘K‘],[1,2,3],[‘Yes‘,‘No‘]]
77     str = u2.product(allparams)
78     strpc = u2.get_pairslist(str)
79     finallist = u2.pairwise(strpc)
80     print(‘最终保留测试用例个数:%d 个‘%(len(finallist)))
81     u2.pprint(finallist)                

  代码解读:

  第三for循环代码39~48行,主要是垂直判断 待检测元素 与 相同位置的元素是否有相同的

  第二for循环代码38~48行,把一组测试用例中的两两配对,从左至右分别和同位置的元素作对比

  第一for循环代码37~48行,遍历每一组测试用例。

  第50~58行代码,判断一组用例的两两配对在其他组同位置上从上到下都能找到相同元素,则将改无效Case从templistb中删除,保持templistb的有效性。

执行结果:

line 1: [(‘M‘, ‘W‘), (‘M‘, ‘C‘), (‘W‘, ‘C‘)]      <---第二个函数get_pairslist(self,lista)处理后的两两配对组合
line 2: [(‘M‘, ‘W‘), (‘M‘, ‘E‘), (‘W‘, ‘E‘)]      <---同第一行解释
line 3: [(‘M‘, ‘L‘), (‘M‘, ‘C‘), (‘L‘, ‘C‘)]
line 4: [(‘M‘, ‘L‘), (‘M‘, ‘E‘), (‘L‘, ‘E‘)]
line 5: [(‘M‘, ‘I‘), (‘M‘, ‘C‘), (‘I‘, ‘C‘)]
line 6: [(‘M‘, ‘I‘), (‘M‘, ‘E‘), (‘I‘, ‘E‘)]
line 7: [(‘O‘, ‘W‘), (‘O‘, ‘C‘), (‘W‘, ‘C‘)]
line 8: [(‘O‘, ‘W‘), (‘O‘, ‘E‘), (‘W‘, ‘E‘)]
line 9: [(‘O‘, ‘L‘), (‘O‘, ‘C‘), (‘L‘, ‘C‘)]
line 10: [(‘O‘, ‘L‘), (‘O‘, ‘E‘), (‘L‘, ‘E‘)]
line 11: [(‘O‘, ‘I‘), (‘O‘, ‘C‘), (‘I‘, ‘C‘)]
line 12: [(‘O‘, ‘I‘), (‘O‘, ‘E‘), (‘I‘, ‘E‘)]
line 13: [(‘P‘, ‘W‘), (‘P‘, ‘C‘), (‘W‘, ‘C‘)]
line 14: [(‘P‘, ‘W‘), (‘P‘, ‘E‘), (‘W‘, ‘E‘)]
line 15: [(‘P‘, ‘L‘), (‘P‘, ‘C‘), (‘L‘, ‘C‘)]
line 16: [(‘P‘, ‘L‘), (‘P‘, ‘E‘), (‘L‘, ‘E‘)]
line 17: [(‘P‘, ‘I‘), (‘P‘, ‘C‘), (‘I‘, ‘C‘)]
line 18: [(‘P‘, ‘I‘), (‘P‘, ‘E‘), (‘I‘, ‘E‘)]      <----同第一行解释
--------------------------------------------------
保留元素列表:[1, 3, 4, 7, 9, 10, 12, 14, 17]        <----有效用例在数组中下标
匹配重复元素列表:[0, 2, 5, 6, 8, 11, 13, 15, 16]     <----被剔除的无效测试用例在数组中下标
最终保留测试用例个数:9 个
line 1: [(‘M‘, ‘W‘), (‘M‘, ‘E‘), (‘W‘, ‘E‘)]
line 2: [(‘M‘, ‘L‘), (‘M‘, ‘E‘), (‘L‘, ‘E‘)]
line 3: [(‘M‘, ‘I‘), (‘M‘, ‘C‘), (‘I‘, ‘C‘)]
line 4: [(‘O‘, ‘W‘), (‘O‘, ‘E‘), (‘W‘, ‘E‘)]
line 5: [(‘O‘, ‘L‘), (‘O‘, ‘E‘), (‘L‘, ‘E‘)]
line 6: [(‘O‘, ‘I‘), (‘O‘, ‘C‘), (‘I‘, ‘C‘)]
line 7: [(‘P‘, ‘W‘), (‘P‘, ‘C‘), (‘W‘, ‘C‘)]
line 8: [(‘P‘, ‘L‘), (‘P‘, ‘C‘), (‘L‘, ‘C‘)]
line 9: [(‘P‘, ‘I‘), (‘P‘, ‘E‘), (‘I‘, ‘E‘)]
[Finished in 0.2s]

  三、代码核心内容白话解释

  pairwise(self,listb)函数包含3层for循环,先画一个二维数组:  

                       i[0]        i[1]        i[2]
listb.index(i)=0 : [(‘M‘, ‘W‘), (‘M‘, ‘C‘), (‘W‘, ‘C‘)]
listb.index(i)=1 : [(‘M‘, ‘W‘), (‘M‘, ‘E‘), (‘W‘, ‘E‘)]
listb.index(i)   : [(‘M‘, ‘L‘), (‘M‘, ‘C‘), (‘L‘, ‘C‘)]
listb.index(i)   : [(‘M‘, ‘L‘), (‘M‘, ‘E‘), (‘L‘, ‘E‘)]
listb.index(i)   : [(‘M‘, ‘I‘), (‘M‘, ‘C‘), (‘I‘, ‘C‘)]
listb.index(i)   : [(‘M‘, ‘I‘), (‘M‘, ‘E‘), (‘I‘, ‘E‘)]
listb.index(i)   : [(‘O‘, ‘W‘), (‘O‘, ‘E‘), (‘W‘, ‘E‘)]
listb.index(i)   : [(‘O‘, ‘L‘), (‘O‘, ‘C‘), (‘L‘, ‘C‘)]
listb.index(i)   : [(‘O‘, ‘L‘), (‘O‘, ‘E‘), (‘L‘, ‘E‘)]
listb.index(i)   : [(‘O‘, ‘I‘), (‘O‘, ‘C‘), (‘I‘, ‘C‘)]
listb.index(i)=n : [(‘O‘, ‘I‘), (‘O‘, ‘E‘), (‘I‘, ‘E‘)]

  

二维列表  listb ,其中的行(发音:hang,二声。横着的那排)从上到下就是第一层for循环 ;每一行中的i[0],i[1],i[2]就是第二层for循环从左至右;第三次for循环元素i[x]从上之下与有效组 templistb通位置元素的对比。

  1、第n行的i[0]要和有效templistb的其他行的i[0]元素对比(第三for),如果有相等的,记录一个标识 如 flag1=True,如果没有相等的记录falg1=False;

  2、直到第二for中的i[0],i[1],i[2]都进行对比后,会得到  [flag1,flag2,flag3 ],所有flag=True则该行为无效用例

  3、第一for遍历全部组合,最终得到保留下来的有效templistb

  见图:

    

完结篇

以上是自己编写的pairwise的全部内容,此算法共耗时3天:

  第一天在确定这究竟是什么算法,看了很多学术文献,看不懂;

  第二天开始写程序,for的嵌套循环设计耽误很久;

  第三天程序成型,有执行结果,发现与参考文章结论不同,随后再仔细研读参考文章,发现掉坑里了。重新推翻代码按照正确思路,用1个小时完成最终结果。

本人做测试的,还不是专业的测试开发,写代码比较费劲,真正应了设计占70%,编码占30%的理。如果像基础在差点,逻辑在乱点,就只能用时间堆了。

希望对需要组织测试用例,或者自动化测试中需要组织用例的同行们有所帮助。

启蒙参考文章:http://blog.csdn.net/aassddff261/article/details/42029325  http://blog.csdn.net/aassddff261/article/details/42776543   感谢作者aassddff261的文章

Python中list知识参考:http://www.runoob.com/python/python-lists.html

------------------------------------------本文专为《光荣之路培训 》原创,如有转载请注明出处----------------------------------

  

时间: 2024-10-11 17:51:02

高效测试用例组织算法pairwise之Python实现的相关文章

DeepFM算法解析及Python实现

1. DeepFM算法的提出 由于DeepFM算法有效的结合了因子分解机与神经网络在特征学习中的优点:同时提取到低阶组合特征与高阶组合特征,所以越来越被广泛使用. 在DeepFM中,FM算法负责对一阶特征以及由一阶特征两两组合而成的二阶特征进行特征的提取:DNN算法负责对由输入的一阶特征进行全连接等操作形成的高阶特征进行特征的提取. 具有以下特点: 结合了广度和深度模型的优点,联合训练FM模型和DNN模型,同时学习低阶特征组合和高阶特征组合. 端到端模型,无需特征工程. DeepFM 共享相同的

常用数据挖掘算法总结及Python实现(高清版)PDF

常用数据挖掘算法总结及Python实现(高清版)PDF百度网盘链接:https://pan.baidu.com/s/1ZR8eCj7pMc_QVHLjOStM5Q 提取码:fzvb 复制这段内容后打开百度网盘手机App,操作更方便哦 原文地址:http://blog.51cto.com/12650227/2332019

数据结构与算法入门-算法介绍(python版本)

//2020.02.29数据结构与算法入门(python版本)第1章 评判算法的优劣指标有哪些?课时1:算法的基本概念 1.算法Algorithm是一个计算过程,是指解决一个问题的方法.2.数据结构是指数据存储的一种结构方式,是静态的.3.程序=数据结构+算法(尼古拉斯凯奇说过的一句著名的话).课时2:时间复杂度介绍 1.估计不同算法运行的快慢方式:时间复杂度2.时间复杂度是指:用来评估算法运行效率的一个式子(单位),与电脑的配置无关,与算法的运行量无关: 3.时间复杂度的表示方法一般使用O(n

建模分析之机器学习算法(附python&amp;R代码)

0序 随着移动互联和大数据的拓展越发觉得算法以及模型在设计和开发中的重要性.不管是现在接触比较多的安全产品还是大互联网公司经常提到的人工智能产品(甚至人类2045的的智能拐点时代).都基于算法及建模来处理.     常见的词汇:机器学习.数据建模.关联分析.算法优化等等,而这些种种又都是基于规律的深度开发(也难怪道德经的首篇就提出道可道非常道,名可名非常名的说法),不管是线性还是非线性,总之存在关联关系,而我们最好理解的就是线性关系,简单的用个函数就能解决.比如我们生活中应用的比较的归纳总结,其

排序算法总结(Python)

目录 1. 介绍 1.1 排序算法分类 1.2 关于时间复杂度 1.3 关于稳定性 2. 细节 2.1 冒泡排序 2.2 选择排序 2.3 插入排序 2.4 希尔排序 2.5 归并排序 2.6 快速排序 2.7 堆排序 2.8 计数排序 2.9 桶排序 2.10 基数排序 参考 1. 介绍 1.1 排序算法分类 内部排序: 数据记录在内存中进行排序 外部排序: 因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存 1.2 关于时间复杂度 平方阶(\(O(n^2)\))排序 各类

高效网页去重算法-SimHash

记得以前有人问过我,网页去重算法有哪些,我不假思索的说出了余弦向量相似度匹配,但如果是数十亿级别的网页去重呢?这下糟糕了,因为每两个网页都需要计算一次向量内积,查重效率太低了!我当时就想:论查找效率肯定是要考虑hash算法,相同字符串的hashcode肯定相同,不同字符串的hashcode却是大不相同,这也不符合要求啊,会不会存在一种算法能够使相似字符串的code值也相同或相似呢,于是就找到了Google的网页去重算法-SimHash.我们在使用SimHash算法前需要根据文档量级选择SimHa

tf–idf算法解释及其python代码实现(下)

tf–idf算法python代码实现 这是我写的一个tf-idf的核心部分的代码,没有完整实现,当然剩下的事情就非常简单了,我们知道tfidf=tf*idf,所以可以分别计算tf和idf值在相乘,首先我们创建一个简单的语料库,作为例子,只有四句话,每句表示一个文档 copus=['我正在学习计算机','它正在吃饭','我的书还在你那儿','今天不上班'] 由于中文需要分词,jieba分词是python里面比较好用的分词工具,所以选用jieba分词,文末是jieba的链接.首先对文档进行分词: i

朴素贝叶斯分类算法介绍及python代码实现案例

朴素贝叶斯分类算法 1.朴素贝叶斯分类算法原理 1.1.概述 贝叶斯分类算法是一大类分类算法的总称 贝叶斯分类算法以样本可能属于某类的概率来作为分类依据 朴素贝叶斯分类算法是贝叶斯分类算法中最简单的一种 注:朴素的意思是条件概率独立性 P(A|x1x2x3x4)=p(A|x1)*p(A|x2)p(A|x3)p(A|x4)则为条件概率独立 P(xy|z)=p(xyz)/p(z)=p(xz)/p(z)*p(yz)/p(z) 1.2.算法思想 朴素贝叶斯的思想是这样的: 如果一个事物在一些属性条件发生

js-FCC算法-Pairwise

找到你的另一半 都说优秀的程序员擅长面向对象编程,但却经常找不到另一半,这是为什么呢?因为你总是把自己局限成为一个程序员,没有打开自己的思维. 这是一个社群的时代啊,在这里你应该找到与你有相同价值观但又互补的另一半. 譬如:你编程能力强,估值11分,如果以20分为最佳情侣来计算,你应该找一个设计能力强,估值为9分的女生. 那么当你遇到一个设计能力为9分的女生,千万别犹豫,大胆去表白.千万别以为后面的瓜比前面的甜哦. 举个例子:有一个能力数组[7,9,11,13,15],按照最佳组合值为20来计算