unit-testing - intégration - test unitaire php




Comment utiliser des combinaisons de jeux en tant que données de test (4)

Je voudrais tester une fonction avec un tuple d'un ensemble de cas de frange et de valeurs normales. Par exemple, en testant une fonction qui retourne true chaque fois que trois longueurs forment un triangle valide, j'aurais des cas spécifiques, des nombres négatifs / petits / grands, des valeurs proches d'un débordement, etc .; de plus, le but 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),
...

En note: je connais la réponse à cette question, mais cela pourrait être utile pour d'autres, et un défi pour les gens ici! - posterai ma réponse plus tard.


Absolument, surtout en traitant beaucoup de ces permutations / combinaisons, je peux définitivement voir que le premier passage serait un problème.

Implémentation intéressante en python, bien que j'en ai écrit un joli en C et Ocaml basé sur "Algorithm 515" (voir plus bas). Il a écrit son dans Fortran comme c'était commun à l'époque pour tous les papiers "Algorithme XX", eh bien, cette assemblée ou c. J'ai dû le réécrire et faire quelques petites améliorations pour travailler avec des tableaux pas des plages de nombres. Celui-ci fait un accès aléatoire, je suis encore en train de travailler sur quelques implémentations sympas de celles mentionnées dans Knuth 4th volume fascicule 2. Je vais expliquer comment cela fonctionne pour le lecteur. Bien que 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"; Buckles, BP, et Lybanon, M. Transactions ACM sur le logiciel mathématique, vol. 3, n ° 2, juin 1977.


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


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

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 "repeat" 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 y a 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, tout ce truc cool ne fait 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 le ferais en choisissant des combinaisons, quelque chose comme ce qui suit en python. La partie la plus difficile est probablement la première passe, c'est-à if f(1,2,3) returns true dire if f(1,2,3) returns true , est-ce un résultat correct? Une fois que vous avez vérifié cela, alors c'est une bonne base pour les tests de régression.

Probablement c'est une bonne idée de faire un ensemble de cas de test que vous savez seront tous vrais (par exemple 3,4,5 pour ce cas de triangle), et un ensemble de cas de test que vous savez seront tous faux (par exemple 0,1 , inf). Ensuite, vous pouvez vérifier plus facilement 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);
...






testing