Question

Je voudrais tester une fonction avec un tuple à partir d'un ensemble de cas marginaux et de valeurs normales.Par exemple, lors du test d'une fonction qui renvoie true à chaque fois que l'on me donne trois longueurs qui forment un triangle valide, j'aurais des cas spécifiques, des nombres négatifs/petits/grands, des valeurs sur le point d'être dépassées, etc.de plus, l'objectif principal est de générer des combinaisons de ces valeurs, avec ou sans répétition, afin d'obtenir un ensemble de données de test.

(inf,0,-1), (5,10,1000), (10,5,5), (0,-1,5), (1000,inf,inf),
...

À titre de remarque :En fait, je connais la réponse à cette question, mais cela pourrait être utile pour d’autres et constituer un défi pour les gens d’ici !--je publierai ma réponse plus tard.

Était-ce utile?

La solution

Absolument, surtout face à beaucoup de ces permutations/combinaisons, je peux certainement voir que le premier passage serait un problème.

Implémentation intéressante en python, même si j'en ai écrit une belle en C et Ocaml basée sur "Algorithm 515" (voir ci-dessous).Il a écrit le sien en Fortran comme c'était courant à l'époque pour tous les articles "Algorithm XX", eh bien, cette assemblée ou c.J'ai dû le réécrire et apporter quelques petites améliorations pour travailler avec des tableaux et non des plages de nombres.Celui-ci fait un accès aléatoire, je travaille toujours sur de belles implémentations de celles mentionnées dans le fascicule 2 du 4ème volume de Knuth.Je vais expliquer comment cela fonctionne au lecteur.Mais si quelqu'un est curieux, je ne m'opposerais pas à écrire quelque chose.

/** [combination c n p x]
 * get the [x]th lexicographically ordered set of [p] elements in [n]
 * output is in [c], and should be sizeof(int)*[p] */
void combination(int* c,int n,int p, int x){
    int i,r,k = 0;
    for(i=0;i<p-1;i++){
        c[i] = (i != 0) ? c[i-1] : 0;
        do {
            c[i]++;
            r = choose(n-c[i],p-(i+1));
            k = k + r;
        } while(k < x);
        k = k - r;
    }
    c[p-1] = c[p-2] + x - k;
}

~"Algorithme 515 :Génération d'un vecteur à partir de l'index lexicographique" ;Boucles, B.P., et Lebanon, M.Transactions ACM sur les logiciels mathématiques, Vol.3, non.2 juin 1977.

Autres conseils

Avec le tout nouveau Python 2.6, vous disposez d'une solution standard avec le module itertools qui renvoie le produit cartésien des itérables :

import itertools

print list(itertools.product([1,2,3], [4,5,6]))
   [(1, 4), (1, 5), (1, 6),
   (2, 4), (2, 5), (2, 6),
   (3, 4), (3, 5), (3, 6)]

Vous pouvez fournir un argument « répéter » pour exécuter le produit avec un itérable et lui-même :

print list(itertools.product([1,2], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]

Vous pouvez également modifier quelque chose avec des combinaisons :

print list(itertools.combinations('123', 2))
[('1', '2'), ('1', '3'), ('2', '3')]

Et si l’ordre compte, il existe des permutations :

print list(itertools.permutations([1,2,3,4], 2))
[(1, 2), (1, 3), (1, 4),
   (2, 1), (2, 3), (2, 4),
   (3, 1), (3, 2), (3, 4),
   (4, 1), (4, 2), (4, 3)]

Bien sûr, tous ces trucs sympas ne font pas exactement la même chose, mais vous pouvez les utiliser d'une manière ou d'une autre pour résoudre votre problème.

N'oubliez pas que vous pouvez convertir un tuple ou une liste en un ensemble et vice versa en utilisant list(), tuple() et set().

Question interessante!

Je ferais cela en choisissant des combinaisons, quelque chose comme ce qui suit en python.La partie la plus difficile est probablement la vérification du premier passage, c'est-à-dire if f(1,2,3) returns true, est-ce un résultat correct ?Une fois que vous avez vérifié cela, cela constitue une bonne base pour les tests de régression.

C'est probablement une bonne idée de créer un ensemble de cas de test dont vous savez qu'ils seront tous vrais (par ex.3,4,5 pour ce cas triangulaire), et un ensemble de cas de test dont vous savez qu'ils seront tous faux (par ex.0,1,inf).Vous pourrez alors vérifier plus facilement que les tests sont corrects.

# xpermutations from http://code.activestate.com/recipes/190465
from xpermutations import *

lengths=[-1,0,1,5,10,0,1000,'inf']
for c in xselections(lengths,3):        # or xuniqueselections
    print c
(-1,-1,-1);
(-1,-1,0);
(-1,-1,1);
(-1,-1,5);
(-1,-1,10);
(-1,-1,0);
(-1,-1,1000);
(-1,-1,inf);
(-1,0,-1);
(-1,0,0);
...

Je pense que tu peux le faire avec le Attribut de test de ligne (disponible dans MbUnit et les versions ultérieures de NUnit) où vous pouvez spécifier plusieurs ensembles pour remplir un test unitaire.

Bien qu'il soit possible de créer de nombreuses données de test et de voir ce qui se passe, il est plus efficace d'essayer de minimiser les données utilisées.

Du point de vue typique de l'assurance qualité, vous souhaiterez identifier différentes classifications d'entrées.Produisez un ensemble de valeurs d’entrée pour chaque classification et déterminez les sorties appropriées.

Voici un échantillon de classes de valeurs d'entrée

  • triangles valides avec de petits nombres tels que (1 milliard, 2, milliards, 2 milliards)
  • triangles valides avec de grands nombres tels que (0,000001, 0,00002, 0,00003)
  • triangles obtus valides qui sont « presque » plats tels que (10, 10, 19,9999)
  • triangles aigus valides qui sont « presque » plats tels que (10, 10, 0000001)
  • triangles invalides avec au moins une valeur négative
  • triangles invalides où la somme de deux côtés est égale au troisième
  • triangles invalides où la somme de deux côtés est supérieure au troisième
  • valeurs d'entrée non numériques

...

Une fois que vous êtes satisfait de la liste des classifications d'entrée pour cette fonction, vous pouvez créer les données de test réelles.Il serait probablement utile de tester toutes les permutations de chaque élément.(par exemple.(2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) Généralement, vous constaterez que certaines classifications vous ont échappé (comme le concept d'inf en tant que paramètre d'entrée).

Des données aléatoires sur une certaine période de temps peuvent également être utiles, car elles peuvent détecter d'étranges bugs dans le code, mais ne sont généralement pas productives.

Il est plus probable que cette fonction soit utilisée dans un contexte spécifique où des règles supplémentaires sont appliquées (par ex.seules les valeurs entières ou les valeurs doivent être par incréments de 0,01, etc.) Ceux-ci s'ajoutent à la liste des classifications des paramètres d'entrée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top