2010-08-09 20 views
29

Me gustaría saber cuáles son las desventajas de usar valores aleatorios en algunas de las pruebas unitarias.¿Cuáles son las desventajas al usar valores aleatorios en Pruebas unitarias?


Estoy hablando de un sistema de gran escala, con muchos servidores y entrada no determinista en alta capacidad. cuando digo no determinista, estoy hablando de mensajes que se envían y captas lo que puedes y haces lo mejor que puedes. Hay muchos tipos de mensajes, por lo que la entrada puede ser muy complicada. No me puedo imaginar escribiendo el código para tantos escenarios y un generador de mensajes simples no aleatorios (determinísticos) no es lo suficientemente bueno. Es por eso que quiero tener una prueba unitaria aleatorizada o una prueba de servidor que en caso de falla podría escribir un registro. Y prefiero la prueba unitaria en lugar de un inyector aleatorio porque quiero que se ejecute como parte de las pruebas automáticas de compilación nocturna.

+1

¿Podría decirnos cuál sería la ventaja? –

+0

Aquí, edité la pregunta. Tnx! – Adibe7

+1

Tenga en cuenta que si se siembra la entrada de un generador de números aleatorios (y solo se accede a ella en una sola cadena), la salida es reproducible y no aleatoria. Si la preocupación es solo la generación de un gran conjunto de datos representativos, aún puede usar un generador de números aleatorios sin que la prueba sea aleatoria ... – Kendrick

Respuesta

37

Desventajas

En primer lugar, se hace la prueba más complicado y un poco más difícil de depurar, ya que no puede ver directamente todos los valores que se alimentan en (aunque siempre existe la opción de generar casos de prueba como código o datos, también). Si está haciendo una lógica semi-complicada para generar sus datos de prueba aleatorios, también existe la posibilidad de que este código tenga un error. Los errores en el código de prueba pueden ser un problema, especialmente si los desarrolladores asumen inmediatamente que el error es el código de producción.

En segundo lugar, a menudo es imposible ser específico sobre la respuesta prevista. Si conoce la respuesta basada en la entrada, entonces hay una posibilidad decente de que solo esté aplicando la lógica bajo prueba (piénselo, si la entrada es aleatoria, ¿cómo conoce la salida esperada?) Como resultado, usted puede tener que negociar aseveraciones muy específicas (el valor debe ser x) para afirmaciones más generales de control de cordura (el valor debe estar entre y y z).

En tercer lugar, a menos que haya una amplia gama de entradas y salidas, a menudo puede cubrir el mismo rango utilizando valores bien elegidos en una unidad estándar de pruebas con menos complejidad. P.ej. elige los números -max, (-max + 1), -2, -1, 0, 1, 2, max-1, máx. (o lo que sea interesante para el algoritmo).

Upsides

Cuando se hace bien con el objetivo correcto, estas pruebas pueden proporcionar una muy valiosa pase las pruebas complementarias. He visto bastantes bits de código que, cuando son martillados por entradas de prueba generadas al azar, se abrochan debido a casos de bordes imprevistos. A veces agrego un pase de prueba de integración adicional que genera una carga de casos de prueba.

trucos adicionales

Si uno de sus pruebas al azar falla, aislar el valor 'interesante' y promover en una unidad de prueba independiente para asegurar que se puede corregir el error y nunca lo hará retroceder antes de registrar .

+0

Si vas a vengarme, di por qué. Utilicé estas técnicas con buenos resultados para encontrar y corregir errores. –

+0

lo siento, fue un error. :) – Adibe7

+0

gracias por responder :) –

8

Son aleatorios.

(Usted podría funcionar prueba al azar, incluso si su código está roto.)

+0

estoy hablando de pruebas adicionales a las pruebas no aleatorias – Adibe7

+4

Su prueba de unidad está destinada a demostrar , de una manera reproducible, si su unidad funciona o no. Si lo hace en sus otras pruebas, no necesitará una prueba aleatoria adicional. Puede usar valores aleatorios para escanear su software en busca de problemas de seguridad desconocidos mediante la entrada aleatoria. Sin embargo, con el resultado de eso, debería volver a escribir una prueba de unidad reproducible. – relet

+0

Tnx por su respuesta, ¿puede echar otro vistazo ahora, después de que agregué algunas explenaciones más? – Adibe7

7

Además, usted no será capaz de reproducir las pruebas muchas veces. Una prueba de unidad debe ejecutarse exactamente igual con los parámetros dados.

+0

Eso no siempre es cierto, las entradas aleatorias pueden aumentar la cobertura del código en algunos casos. –

+3

@NIckLarsen: Es posible que * sucedan * para aumentar la cobertura del código, para una ejecución de prueba en particular ... Sin embargo, no puede * confiar * en que cubra ese código. Tienes que abrir la caja para saber si el gato está muerto o no. – Pete

+1

@Nick - Entonces debería promocionar el valor que aumenta la cobertura del código. –

3

Los resultados no son repetibles, y dependiendo de sus pruebas, es posible que no conozca las condiciones específicas que causaron el error del código (lo que dificulta su depuración).

+2

Eso depende del marco de prueba de la unidad.Un marco de prueba decente generará los valores (y qué afirmación) causó la falla de la prueba. Esta salida se puede usar para construir un nuevo caso de prueba codificado. –

+0

Corregido. Gracias. – Kendrick

3

Es mucho mejor tener pruebas unitarias que sean 100% repetibles e incluyan todos los casos extremos. Por ejemplo, prueba cero, negativos, positivos, números demasiado grandes, números demasiado pequeños, etc. Si deseas incluir pruebas con valores aleatorios además de todos los casos extremos y casos normales, estaría bien. Sin embargo, no estoy seguro de que obtendría un gran beneficio del tiempo invertido. Tener todos los casos normales y casos extremos debe manejar todo. El resto es "salsa".

+0

Esta respuesta es simplista. En el caso de las cadenas, por ejemplo, es posible que no pueda representar todo el rango (cadena de longitud 0, cadenas con caracteres no válidos, cadenas realmente largas). Algún aleatorización eventualmente descubrirá algún caso de borde imprevisto. –

1

Como han sugerido otros, hace que su prueba no sea confiable porque no sabe lo que sucede dentro de ella. Eso significa que podría funcionar en algunos casos, y no en otros.

Si ya tiene una idea del rango de valores que desea probar, entonces debe (1) crear una prueba diferente para cada valor en el rango, o (2) repetir el conjunto de valores y hacer una afirmación en cada iteración. Un ejemplo rápido, bastante tonto ...

for($i = 0; $i < 10; $i++) 
    $this->assertEquals($i + 1, Math::addOne($i)); 

Podría hacer algo similar con las codificaciones de caracteres. Por ejemplo, recorra el conjunto de caracteres ASCII y pruebe todos esos caracteres locos contra una de las funciones de manipulación de texto.

0

Debe recordar qué números aleatorios generó durante la verificación.

Ejemplo.

Username= "username".rand(); 
Save_in_DB("user",Username); // To save it in DB 
Verify_if_Saved("user",Username); 
0

Creo que la generación de valores de entrada aleatorios puede ser una técnica de prueba confiable cuando se usa junto con la partición de equivalencia. Esto significa que, si particiona su espacio de entrada y luego selecciona al azar los valores de una clase de equivalencia, entonces está bien: la misma cobertura (cualquiera de ellos, incluida la declaración, la rama, todos los usos, etc.). Esto bajo la suposición de que su procedimiento de partición de equivalencia es correcto. Además, recomendaría el análisis del valor límite para emparejarlo con la partición de equivalencia y las entradas generadas aleatoriamente.

Finalmente, también recomendaría considerar el TIPO de defectos que desea detectar: ​​algunas técnicas de prueba abordan tipos específicos de defectos, que pueden ser difíciles de detectar (y por casualidad) por otras técnicas. Un ejemplo: condiciones de punto muerto.

En conclusión, creo que generar valores aleatorios no es una mala práctica, en particular en algunos sistemas (por ejemplo, aplicaciones web), pero solo aborda un subconjunto de defectos existentes (como cualquier otra técnica) y uno debe saber de eso, para complementar su proceso de garantía de calidad con el conjunto adecuado de actividades.

1

Las pruebas de unidades aleatorias utilizan un destornillador para clavar un clavo. El problema no es que los destornilladores sean malos; el problema es que estás usando la herramienta incorrecta para el trabajo. El objetivo de las pruebas unitarias es proporcionar retroalimentación inmediata cuando rompes algo, para que puedas arreglarlo allí mismo.

Digamos que compromete un cambio, que llamaremos BadChange. BadChange presenta un error, que algunas veces tus pruebas aleatorias detectarán y otras no. Esta vez, las pruebas no lo atrapan. BadChange se le da todo claro y entra en la base de código.

Más tarde, alguien comete otro cambio, GoodChange. GoodChange está cien por ciento bien. Pero esta vez, tus pruebas aleatorias captan el error introducido por BadChange. Ahora GoodChange está marcado como un problema, y ​​el desarrollador que lo escribió irá en círculos tratando de descubrir por qué este cambio inocuo está causando problemas.

Las pruebas aleatorias son útiles para examinar constantemente toda la aplicación en busca de problemas, no para validar cambios individuales. Debería vivir en una suite separada, y las ejecuciones no deberían estar vinculadas a cambios de código; incluso si nadie ha hecho un cambio, existe la posibilidad de que las pruebas aleatorias se topen con algún error exótico que fallaron las corridas anteriores.

0

Upsides: revelan cuando sus otras pruebas tienen no cubrieron todas las invariantes. Si desea que su servidor de CI ejecute pruebas no determinantes es otro problema. Dado lo increíblemente útil que he encontrado https://www.artima.com/shop/scalacheck, no pretendo prescindir de él a partir de ahora. Supongamos que está implementando un algoritmo de coincidencia de patrones. ¿Conoces realmente todos los diferentes casos de esquina? Yo no. Las entradas aleatorias pueden expulsarlos.

0

Adicional DownsideDownside Adicional que no ha sido mencionado aún es que sus pruebas pueden fallar intermitentemente al azar, especialmente cuando genera aleatoriamente varias variables de prueba para que formen unas dependencias intrincadas y, a veces, imposibles de eludir. Vea el ejemplo here.

Depuración estos es un dolor en la parte trasera y a veces es (al lado de) imposible.

Además, a menudo es difícil decir lo que realmente prueba su prueba (y si prueba algo en absoluto).

Históricamente en mi compañía usamos pruebas aleatorias en múltiples niveles (Unidad, Integración, Pruebas de servicio único), y eso pareció una gran idea inicialmente: le ahorra código, espacio y tiempo permitiendo probar múltiples escenarios en una prueba.

Pero cada vez más eso llega a ser un punto pegajoso en nuestro desarrollo, cuando nuestra prueba (incluso histórica y fiable en el pasado) comienza a fallar al azar, y la fijación de estos es mucho trabajo.

Cuestiones relacionadas