【测试算法】深入浅出Pairwise 算法


深入浅出Pairwise 算法

作者:王勇 


软件测试是软件开发中很重要的一环,在软件成本中也占着很大的比重。本文在介绍pairwise算法的基础上,提出了针对某一类问题的扩展算法并加以实现。

       本文的组织结构如下:

第一,  本文首先简要介绍一下测试界中的著名的pairwise算法(约占文章的50%)。

第二,  然后提出了一种对pairwise算法的扩展算法(扩展算法更适合用于测试某一类场合)。

第三,  最后,基于扩展算法,使用java语言开发出测试用例生成工具jCase。

 

目录

1 软件测试...3

2 pairwise算法...3

2.1 pairwise算法详解...4

2.2 Pairwise算法的效率...6

2.3 pairwise算法的比较...6

3 Pairwise扩展算法...7

3.1 Pairwise维度...7

3.2 Pairwise算法中重要维度算法...8

4 Pairwise程序...9

5 Pairwise的不足...10


软件测试

软件测试是软件工程中一个重要的活动,它有4个原则:

(1)尽早的和不间断的进行软件测试

(2)对所有产品进行全面测试

(3)关注软件开发全过程

(4)根据不同的需求,选用适当的测试模型

软件测试分为黑盒测试和白盒测试。Pairwise算法就是针对软件测试中的黑盒测试提出来的一个行之有效的测试方法。

2 pairwise算法

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

Pairwise基于如下2个假设:

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

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

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

2.1 pairwise算法详解

假设有3个维度,每个维度有几个因子。如下:

浏览器:M,O,P

操作平台:W(windows),L(linux),i(ios)

语言:C(chinese),E(english)

求解:

使用pairwise算法,有多少个测试case?具体是什么case?

 

我们沿用数学做题的格式。

解:

如果不用pairwise算法,我们需要 3*3*2=18个测试case。下面是具体的case:

1,M W C

2,MW E

3,M L C

4,M L E

5,M I C

6,M I E

7,O W C

8,O W E

9,O L C

10,O L E

11,O I C

12,O I E

13,P W C

14,P W E

15,P L C

16,P L E

17,P I C

18,P I E

一共有18个,很繁琐。但是这是100%的测试覆盖率,缺陷率也是100%。

现在我们使用pairwise,看看结果如何?

首先咱们从最下方一个18号开始,它是 P I E,两两组合是 PI ,PE ,IE。看这3个组合在以上的相同位置出现过没有,PI在17号,PE在16号,IE在12号出现过。所以18这个case就可以舍去。

最终剩下的如下:

1,MWC

4,MLE

6,         MIE

7,         OWE

9,         OLC

11,    OIC

14,    PWE

15,    PLC

17,PIC

共计9个测试case,节省了50%的测试case。

现在我们从上面开始重新做一次。1号是MWC,两两组合是MW MC WC 都出现过,去掉。

最终剩下的是:

2,MWE

4, MLE

5, MIC

8, OWE

10, OLE

11, OIC

13 PWC

15 PLC

18 PIE

       这样也是剩下9个测试case,但是具体的case内容不一样。经过L. L. Thurstone证明,pairwise算法最终剩下的测试case个数肯定相同,但是可以有不同的case组合。

2.2 Pairwise算法的效率

       Pairwise算法和正交分析法进行比较,当有3个维度,每个维度有4个因子的时候:

(1)正交分析法的case数量:4*4*4=64个

(2)Pairwise算法的case数量:20个

Pairwise的case数量是正交设计法的三分之一。当维度越多的时候,效果越明显。当有10个维度的时候 4*4*4*4*3*3*3*2*2*2=55296个测试case,pairwise为24个。是原始测试用例规模的0.04%。

2.3 pairwise算法的比较

       Pairwise算法和单因素测试用例设计的比较,能够覆盖到两个维度的正交组合设计。能适当减少遗漏的测试。

       Pairwise算法和全正交设计法的比较,全正交设计法,测试case太多,投入的成本太大。Pairwise算法在数学统计分析的基础上,对传统的全正交设计法进行了优化,适当的提高了效率。

3 Pairwise扩展算法

       基于XXXX的各类项目,经过初步统计如下:

项目名称

项目组

维度个数

备注

xxx1

张组

3

平台,机器,软件版本

xxx2

张组

4

Ip和域名,udp,后缀表

xxx3

齐组

2

Ip黑白名单,域名黑白名单

xxx4

3

注册商,ip和域名

 

       可以看出,每一个项目的维度都保持在5个以下,并且有重要维度和一般维度的区分。根据这2个特点,提出了pairwise的扩展算法。

3.1 Pairwise维度

XXXX的各类项目维度都不多,并且每个维度的因子也不太多。测试人员可以很好的把握测试维度,难度不高。适合pairwise算法。

3.2 Pairwise算法中重要维度算法

在一般维度方面,重要性是平均的,所以在维度1上,是一个平面,它和维度2(平面),相交,是一条线,具体到因子,就是一个点。所以我们找到了一组case。

在重要维度方面,重要性不是平均的,我们采用正交表的曲面理论。比如维度1是重要维度,我们采用曲面表示,如果维度2也是重要维度,那么,维度1和维度2相交,就是2条线。具体到因素,就是2个点(或者多个点)。如果维度2是一般维度(平面),曲面和平面相交,也有可能是1条线,也可能是2条线。我们这里选1条线。

综上所述,重要维度方面要适当增加测试case。具体怎么加见如下方法:

1,         按照输入维度的顺序全排列测试case。(输入维度的顺序代表重要性从高到底)

2,         从第一个开始往下使用pairwise算法过滤case。

3,         从最后一个开始往上使用pairwise算法过滤case。

4,         找出以上2组中相同case的数量,就是要增加的case的数量。

5,         增加的case是步骤4中相同的case的,变换维度1和维度2生成的case。

4 Pairwise程序

       现有很多程序都是围绕pairwise算法产生的,最著名的就是ReduceArray;SmartDesgin 和微软的PICT。

按照pairwise扩展算法开发了一个jCase程序,部署在http://xxxxx.cn/ 上的测试工具库中。基本理论如第3小节所述。

开发环境:eclipse 3.2

JDK:1.6+

部署容器:tomcat

核心流程:

1,         获取维度和因子进行全排列。

2,         得到具体的case的两两因子组合(带位置)。

3,         判断这个case中两两因子组合是否在上面出现过,如果出现一个就删除掉。全部都没出现过,就保留这个case。

4,         按照不同的顺序使用pairwise算法再过滤一遍。

5,         得到2组数据,找出相同的case。

6,         按照维度的顺序增加case。

核心代码如下:

private booleanjudge(String[] tpm, HashMap copyresult) {

        Stringstr = "";

        for(int i=0; i<tpm.length; i++)

        {

            str+= tpm[i]+";";

        }

        str= str.substring(0,str.length()-1);

        copyresult.remove(str);

        ArrayList r =newArrayList();

        int len = tpm.length;

        for (int i = 0; i < len; i++){

            for (int j = i + 1; j < len;j++) {

                String[]st = newString[len];

                for (int k = 0; k < len; k++){

                    st[k]= "*";

                }

                st[i]= tpm[i];

                st[j]= tpm[j];

                Stringss = java.util.Arrays.asList(st).toString();

                ss= ss.replaceAll("\\[","").replaceAll("\\]","");

//                  System.out.println(ss);

                r.add(ss);

            }

        }

        boolean bol =true;

        for (int i = 0; i < r.size();i++) {

            boolean flag =false;

            Stringk = (String) r.get(i);

            Iteratoriter = copyresult.entrySet().iterator();

            while (iter.hasNext()) {

                Map.Entryentry = (Map.Entry) iter.next();

                Stringt = (String)entry.getKey();

                if (cnniccompare(t, k)) {

                    bol= bol && true;

                    flag= true;

                    break;

                }

            }

            if (!flag)

                bol= false;

        }

        copyresult.put(str,str);

        return bol;

    }

5 Pairwise的不足

       (1)Pairwise对于维度的分解来说,需要对业务很熟悉。以及需要正交测试法的理论支持。需要中等专业的测试人员才能完成。

       (2)pairwise还是有一定的遗漏。相比于全正交设计法来说,pairwise算法对于多于2个因素相互作用所产生的bug,没有覆盖到。


转自:http://blog.csdn.net/aassddff261/article/details/42776543

  • 14
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的 MATLAB 程序,用于实现 pairwise constraints 算法: ```matlab function [labels, energy] = pairwise_constraints(data, constraints, lambda) % data: 输入数据矩阵,每行表示一个样本,每列表示一个特征。 % constraints: 约束矩阵,每行表示一个约束条件,第一列是约束的第一个样本的索引,第二列是约束的第二个样本的索引,第三列是约束类型,1 表示第一个样本应比第二个样本大,-1 表示第一个样本应比第二个样本小。 % lambda: 正则化参数,控制平滑和约束的权重。 % labels: 输出标签向量,与输入数据矩阵的行数相同。 % energy: 最终能量值。 % 初始化标签向量为每个样本的中位数标签 labels = median(data, 1) > data; % 计算初始能量值 energy = compute_energy(data, labels, constraints, lambda); % 迭代优化标签向量和能量值 for i = 1:100 % 优化标签向量 labels = optimize_labels(data, labels, constraints, lambda); % 计算能量值 new_energy = compute_energy(data, labels, constraints, lambda); % 如果能量值没有变化,则退出循环 if abs(new_energy - energy) < 1e-6 break; end energy = new_energy; end end function energy = compute_energy(data, labels, constraints, lambda) % 计算能量值 % 平滑能量项 smooth_energy = sum(sum((data - labels).^2)); % 约束能量项 constraint_energy = 0; for i = 1:size(constraints, 1) if constraints(i, 3) == 1 constraint_energy = constraint_energy + max(0, labels(constraints(i, 1), :) - labels(constraints(i, 2), :)); else constraint_energy = constraint_energy + max(0, labels(constraints(i, 2), :) - labels(constraints(i, 1), :)); end end % 总能量值 energy = smooth_energy + lambda * constraint_energy; end function labels = optimize_labels(data, labels, constraints, lambda) % 优化标签向量 % 计算每个样本的邻居标签 neighbour_labels = zeros(size(data)); for i = 1:size(constraints, 1) if constraints(i, 3) == 1 neighbour_labels(constraints(i, 1), :) = neighbour_labels(constraints(i, 1), :) + labels(constraints(i, 2), :); neighbour_labels(constraints(i, 2), :) = neighbour_labels(constraints(i, 2), :) + labels(constraints(i, 1), :); else neighbour_labels(constraints(i, 1), :) = neighbour_labels(constraints(i, 1), :) + labels(constraints(i, 2), :); neighbour_labels(constraints(i, 2), :) = neighbour_labels(constraints(i, 2), :) + labels(constraints(i, 1), :); end end % 计算每个样本的邻居数量 neighbour_counts = sum(constraints(:, 3) ~= 0); neighbour_counts(neighbour_counts == 0) = 1; % 计算每个样本的平均邻居标签 neighbour_labels = neighbour_labels ./ neighbour_counts; % 更新标签向量 labels = (data + lambda * neighbour_labels) > median(data, 1); end ``` 这个程序实现了 pairwise constraints 算法,其中 `data` 是输入数据矩阵,`constraints` 是约束矩阵,`lambda` 是正则化参数。该算法通过迭代优化标签向量和能量值来最小化平滑能量项和约束能量项的和,从而得到最终的标签向量和能量值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值