Cómo usar combinaciones de conjuntos como datos de prueba

votos
18

Me gustaría probar una función con una tupla de un conjunto de mayúsculas y valores normales. Por ejemplo, mientras pruebo una función que retorna truesiempre que tenga tres longitudes que forman un triángulo válido, tendría casos específicos, números negativos / pequeños / grandes, valores cercanos a desbordarse, etc .; Además, el objetivo principal es generar combinaciones de estos valores, con o sin repetición, para obtener un conjunto de datos de prueba.

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

Como nota: ¡En verdad conozco la respuesta a esto, pero podría ser útil para otros y un desafío para la gente aquí! - Publicaré mi respuesta más tarde.

Publicado el 02/08/2008 a las 22:34
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
4

¡Interesante pregunta!

Haría esto seleccionando combinaciones, algo como lo siguiente en Python. La parte más difícil es probablemente la verificación del primer paso, es decir if f(1,2,3) returns true, ¿es un resultado correcto? Una vez que haya verificado eso, esta es una buena base para las pruebas de regresión.

Probablemente sea una buena idea crear un conjunto de casos de prueba que sepa que serán verdaderos (p. Ej., 3,4,5 para este caso triangular) y un conjunto de casos de prueba que sepa que serán todos falsos (p. Ej., 0,1 , inf). Entonces puede verificar más fácilmente que las pruebas son correctas.

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

longitudes = [- 1,0,1,5,10,0,1000, 'inf']
para c en xselections (longitudes, 3): # o xuniqueselections
    imprimir 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);
...
Respondida el 03/08/2008 a las 01:04
fuente por usuario

votos
14

Absolutamente, especialmente lidiando con muchas de estas permutaciones / combinaciones definitivamente puedo ver que el primer pase sería un problema.

Implementación interesante en Python, aunque escribí uno bueno en C y Ocaml basado en "Algorithm 515" (ver abajo). Escribió el suyo en Fortran ya que era común en aquel entonces para todos los documentos del "Algoritmo XX", bueno, esa asamblea o c. Tuve que volver a escribirlo y hacer algunas pequeñas mejoras para trabajar con matrices, no con rangos de números. Éste tiene acceso aleatorio, todavía estoy trabajando en obtener algunas implementaciones agradables de las mencionadas en el fascículo 2 del 4to volumen de Knuth. Explicaré cómo funciona esto para el lector. Aunque si alguien tiene curiosidad, no me opondría a escribir algo.

/** [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;
}

~ "Algoritmo 515: Generación de un vector del índice lexicográfico"; Buckles, BP y Lybanon, M. ACM Transactions on Mathematical Software, vol. 3, No. 2, junio de 1977.

Respondida el 03/08/2008 a las 20:06
fuente por usuario

votos
2

Creo que puede hacer esto con el atributo de prueba de fila (disponible en MbUnit y versiones posteriores de NUnit) donde puede especificar varios conjuntos para rellenar una prueba de unidad.

Respondida el 16/08/2008 a las 14:31
fuente por usuario

votos
0

Si bien es posible crear muchos datos de prueba y ver qué sucede, es más eficiente intentar minimizar los datos que se usan.

Desde una perspectiva de control de calidad típica, le conviene identificar diferentes clasificaciones de entradas. Produzca un conjunto de valores de entrada para cada clasificación y determine las salidas apropiadas.

Aquí hay una muestra de clases de valores de entrada

  • triángulos válidos con números pequeños como (1 billón, 2, billón, 2 billones)
  • triángulos válidos con números grandes como (0.000001, 0.00002, 0.00003)
  • triángulos obtusos válidos que son "casi" planos como (10, 10, 19.9999)
  • triángulos agudos válidos que son "casi" planos, como (10, 10, 0000001)
  • triángulos inválidos con al menos un valor negativo
  • triángulos inválidos donde la suma de dos lados es igual a la tercera
  • triángulos inválidos donde la suma de dos lados es mayor que la tercera
  • valores de entrada que no son numéricos

...

Una vez que esté satisfecho con la lista de clasificaciones de entrada para esta función, puede crear los datos de prueba reales. Probablemente, sería útil probar todas las permutaciones de cada elemento. (ej. (2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) Normalmente, encontrará que hay algunas clasificaciones que omitió (como el concepto de inf como parámetro de entrada).

Los datos aleatorios durante un período de tiempo también pueden ser útiles, ya que pueden encontrar errores extraños en el código, pero generalmente no son productivos.

Es más probable que esta función se utilice en un contexto específico donde se aplican reglas adicionales (por ejemplo, solo valores enteros o valores deben estar en incrementos de 0,01, etc.). Estos se agregan a la lista de clasificaciones de los parámetros de entrada.

Respondida el 17/09/2008 a las 04:15
fuente por usuario

votos
4

Con el nuevo Python 2.6, tiene una solución estándar con el módulo itertools que devuelve el producto cartesiano de los 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)]

Puede proporcionar un argumento de "repetición" para realizar el producto con un iterable y sí mismo:

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)]

También puede modificar algo con combinaciones:

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

Y si el orden es importante, hay permutaciones:

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)]

Por supuesto, todas esas cosas interesantes no hacen exactamente lo mismo, pero puedes usarlas de una forma u otra para resolver tu problema.

Solo recuerde que puede convertir una tupla o una lista en un conjunto y viceversa usando list (), tuple () y set ().

Respondida el 04/10/2008 a las 09:52
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more