Maison  >  Article  >  développement back-end  >  Comment Python implémente l'algorithme d'organisation par paires (cas de test efficaces)

Comment Python implémente l'algorithme d'organisation par paires (cas de test efficaces)

黄舟
黄舟original
2017-07-20 15:37:182735parcourir

L'éditeur suivant vous proposera une méthode d'implémentation Python d'un algorithme efficace d'organisation des cas de test par paires. L'éditeur le trouve plutôt bon, je vais donc le partager avec vous maintenant et le donner comme référence pour tout le monde. Suivons l'éditeur et jetons un coup d'oeil.

Ouverture :

Pendant le processus de test, des cas de tests sont organisés pour le cas de multi- Paramètres de paramètres avec plusieurs valeurs., J'utilise [Méthode d'analyse orthogonale] pour organiser les cas d'utilisation, pour parler franchement, cela signifie faire une combinaison complète de toutes les valeurs de chaque paramètre avec les valeurs. ​d'autres paramètres. Il est implémenté avec un script Python, qui est la méthode produit (également connue sous le nom de flûte) dans le module itertools (méthode produit Karl).

L'avantage de la méthode d'analyse orthogonale est que le taux de couverture des cas de test est de 100 %. L'inconvénient est que le nombre de cas de test est énorme et la consommation de main-d'œuvre pour l'exécution des cas d'utilisation est énorme.

L'algorithme par paires est dérivé de l'optimisation des méthodes d'analyse orthogonales traditionnelles, et sa théorie vient des statistiques mathématiques. Pour être honnête, je ne comprends pas les articles universitaires sur les statistiques mathématiques, je ne peux donc trouver que quelques explications simples et populaires sur Internet pour comprendre leur signification fondamentale.

De nombreuses personnes sur Internet utilisent [système d'exploitation, navigateur, environnement linguistique] comme exemples. J'utilise également le même exemple :

Système d'exploitation : W (Windows), L (Linux), Mac (Mac) ; Navigateur : M (Firefox), O (Opera), IE ; Environnement linguistique : C (chinois), E (anglais)

Selon la méthode d'analyse orthogonale : 3x3x2 sera généré =18. méthodes de combinaison, couverture des cas de test à 100 %.

La méthode d'organisation des cas de test par paires peut être compressée en 9 combinaisons. Par conséquent, l'inconvénient est que le nombre de cas de test est faible et l'inconvénient est qu'il y aura certainement des tests manqués.

Introduction :

Le concept de base de l'algorithme Pairwise

1. Un ensemble de cas de test (chaque cas d'utilisation se compose de 3 valeurs de paramètres, telles que [W, M, C]). Chaque 2 éléments est combiné, et lorsqu'il est combiné par paires, il existe 3 combinaisons (positionnées) [W,). M][W,C][M,C]);

2. Si cette première série de tests utilise trois combinaisons de deux par deux, le principe de comparaison est : [W,M] Ce sera seulement par rapport au premier élément des autres groupes, et [W, C] ne sera comparé qu'au deuxième élément des autres groupes. . . . ;

[W,M][W,C][M,C] Ces trois éléments apparaissent dans les éléments ayant la même position dans les groupes valides restants, ce groupe de Cas peut donc être considéré comme des Cas redondants. , et à supprimer.

Explication du nom : [Groupe effectif] désigne un groupe qui n'a pas été supprimé et un groupe qui n'a pas été comparé. Par exemple : Si les groupes 1 et 3 sont supprimés, les groupes effectifs à comparer avec le groupe 4 sont les groupes 2, 5, 6, 7...18. Le groupe effectif a franchi la fosse ici%>_<%

3. Le cas de test est finalement obtenu, qui est l'ensemble optimal de cas de test calculé par l'algorithme d'appariement.

Une preuve académique brillante

Pairwise a été proposée pour la première fois par L. L. Thurstone (29 mai 1887 – 30 septembre 1955) en 1927. C'est un psychostatisticien américain. Pairwise est également un produit basé sur des statistiques mathématiques et l'optimisation des méthodes d'analyse orthogonales traditionnelles.

Pairwise est basé sur les deux hypothèses suivantes :

(1) Chaque dimension est orthogonale, c'est-à-dire que chaque dimension est indépendante de chacune autre carrefour.

(2) Selon l'analyse statistique mathématique, 73 % des défauts (35 % pour un seul facteur et 38 % pour deux facteurs) sont causés par un seul facteur ou par l'interaction de 2 facteurs. 19 % des défauts sont causés par l’interaction de 3 facteurs.

Par conséquent, par paire est généré sur la base de l'ensemble de cas d'utilisation le plus rentable généré par l'interaction des 2 facteurs.

Texte

1. Idées

Un scénario de test Comment pour commencer depuis la saisie des conditions testées jusqu'à la production de cas de test Pairwise, les idées de programmation Python sont les suivantes :

1 Définissez allparams=[['M','O','P'],[' W. ','L','I'],['C','E']] effectue un traitement de combinaison complète de produits cartésiens pour générer un tableau unidimensionnel (len=N) de l'ensemble complet de cas de test générés par l'application régulière. méthode d'analyse ;

2. Chaque cas de test de l'ensemble complet des cas de test est décomposé en deux combinaisons pour générer un tableau bidimensionnel de la même longueur que l'ensemble complet des cas de test (len= unidimensionnel). N);

3. Utiliser la version Python de l'algorithme Pairwise pour éliminer les cas de test invalides, et enfin obtenir un ensemble de cas de test appariés efficaces

Les 1ère et 2ème fonctions du code ; sont écrits à l'aide de la propre bibliothèque de calcul mathématique de Python, itertools, et du 3ème code. La fonction est le code que j'ai proposé.

2. Téléchargez directement le code


# -*- coding: utf-8 -*-
from datetime import *
import random,os,copy,time
import logging
import itertools
&#39;&#39;&#39;
#Author:Kuzaman
#Time:2017-07-18
&#39;&#39;&#39;
class utils2 :
 #1、笛卡尔积 对参数分组全排列
 def product(self,tuple1):
  newlist=[]
  for x in eval(&#39;itertools.product&#39;+str(tuple(tuple1))):
   newlist.append(x)
  return newlist 
 
 #2、对笛卡尔积处理后的二维原始数据进行N配对处理,得到Pairwise计算之前的数据
 def get_pairslist(self,lista):
  pwlist = []
  for i in lista:
   subtemplist = []
   for sublista in itertools.combinations(i, 2):
    subtemplist.append(sublista)
   pwlist.append(subtemplist)
  return pwlist
 
 #3、进行Pirwise算法计算
 def pairwise(self,listb):
  sublistlen = len(listb[1])
  flag = [0]*sublistlen
  templistb = copy.deepcopy(listb)
  delmenu = []
  holdmenu=[]
  self.pprint (listb)
  print (&#39;--&#39;*25)
  for lb in listb:
   for sublb in lb: 
    for k in templistb:
     Xa = lb.index(sublb)
     Ya = listb.index(lb)
     if k != lb and sublb == k[Xa]:
      # print (sublb,&#39;===>&#39; ,k[Xa],&#39;相等了。。。&#39;)
      flag[Xa] = 1
      break
     else:
      # print (sublb,&#39;===>&#39; ,k[Xa],&#39;不不不等了。。。&#39;)
      flag[Xa] = 0
   # print (&#39;下标%d,子元素 %s 双匹配对比结果flag:%s&#39;%(listb.index(lb),lb,flag))
   if 0 not in flag:
    num = listb.index(lb)
    delmenu.append(num)
    templistb.remove(lb)
    # print (&#39;下标为%d行应删除,内容=%s,&#39;%(num,lb))
    # print (&#39;delmenu:&#39;,delmenu)
   else:
    num2 = listb.index(lb)
    holdmenu.append(num2)
    # print (&#39;下标为%d行应保留,内容=%s,&#39;%(num2,lb))
    # print(&#39;holdmenu=&#39;,holdmenu)
   # print (&#39;***&#39;*20)
  print (&#39;保留元素列表:%s \n匹配重复元素列表:%s&#39;%(holdmenu,delmenu))
  return templistb

 def pwresult(self,slist,delmenu):
  for x in delmenu:
   slist.remove(slist[x])
  return slist

 def pprint(self,list):
  for i in list:
   print (&#39;line %d:&#39;%(list.index(i)+1),i)  

if __name__ == &#39;__main__&#39;:
 u2 = utils2()
 allparams=[[&#39;M&#39;,&#39;O&#39;,&#39;P&#39;],[&#39;W&#39;,&#39;L&#39;,&#39;I&#39;],[&#39;C&#39;,&#39;E&#39;]]#,&#39;K&#39;],[1,2,3],[&#39;Yes&#39;,&#39;No&#39;]]
 str = u2.product(allparams)
 strpc = u2.get_pairslist(str)
 finallist = u2.pairwise(strpc)
 print(&#39;最终保留测试用例个数:%d 个&#39;%(len(finallist)))
 u2.pprint(finallist)

Interprétation du code :

La troisième ligne de code de boucle for 39~48 sert principalement à déterminer verticalement si l'élément à détecter et l'élément à la même position ont la même valeur

Le deuxième code de boucle for 38 ~ Lignes 48, associez deux paires de cas de test dans un groupe et comparez-les avec des éléments à la même position de gauche à droite

Le premier code de boucle for, lignes 37 ~ 48 , parcourt chaque groupe de cas de test.

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

执行结果:


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

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

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


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

二维列表 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%的理。如果像基础在差点,逻辑在乱点,就只能用时间堆了。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn