2008-11-20 23 views
10

Estoy empezando a realizar pruebas unitarias y he escrito algunas pruebas cortas para verificar si la función llamada isPrime() funciona correctamente.¿Cómo decidir casos de prueba para pruebas unitarias?

Tengo una prueba que comprueba que la función funciona, y tengo algunos datos de prueba en forma de algunos números y el valor de retorno esperado.

¿Cuántas debo probar? ¿Cómo decido sobre qué evaluar? ¿Cuáles son las mejores prácticas aquí?

Un enfoque sería generar 1000 primos, luego recorrerlos todos, otro sería simplemente seleccionar 4 o 5 y probarlos. ¿Qué es lo correcto para hacer?

Respuesta

8

Lo que quiere comprobar casos extremos. ¿Cuán grande se supone que es capaz de manejar su número principal? Esto dependerá de qué representación (tipo) utilizó. Si solo está interesado en números primos pequeños (realmente relativos cuando se usan en teoría de números), probablemente esté utilizando int o long. Pruebe algunos de los primos más grandes que pueda en la representación que haya elegido. Asegúrate también de verificar algunos números no primos. (Estos son mucho más fáciles de verificar independientemente.)

Naturalmente, también querrá probar algunos números pequeños (primos y no primos) y algunos en el medio del rango. Un puñado de cada uno debería ser suficiente. También asegúrese de lanzar una excepción (o devolver un código de error, cualquiera sea su preferencia) para números que estén fuera del alcance de sus entradas válidas.

+0

¿por qué probarías primero los casos de borde? ¿Qué hay de todos estos controles innumerables e inútiles para cosas nulas y otras cosas que hacen juntos el 80% de su código de prueba, y luego es hora de irse a casa antes de incluso escribir la "prueba real"? Él quiere que el functino trabaje para números "normales". ¿Cómo probarías los bordes? – badbadboy

+0

Digamos que la función funciona para 125 y se bloquea para 12234235345. ¿Pasaría tiempo asegurándose de que arroje ArgumentException en lugar de colgarse? Sin embargo, estoy de acuerdo, es bueno probar los casos extremos si ha terminado con todo lo demás y cree que es útil. – badbadboy

+2

@badbadboy La razón para probar los casos extremos es muy a menudo que es donde se encuentran los errores - y el propósito de las pruebas es exponer los errores. – ChrisN

1

Pregúntese. ¿Qué EXACTAMENTE quiero probar? Y prueba lo más importante. Prueba para asegurarte de que básicamente hace lo que esperas que haga en los casos esperados.

Probando todos esos nulos y casos extremos: ¡no creo que sea real, consuma demasiado tiempo y alguien tenga que mantenerlo más tarde! Y ... ¡su código de prueba debe ser lo suficientemente simple para que no tenga que probar el código de prueba!

Si desea comprobar que su función aplicó correctamente el algoritmo y funciona en general, probablemente sea suficiente con algunos primos.

Si desea probar que el método para encontrar números primos es CORRECTO - 100000 primos no serán suficientes :) Pero no quieren probar la última (probablemente) ...

sólo usted sabe lo ¡quieres probar! :)

PD I thnik utilizando bucles en pruebas unitarias no siempre es incorrecto, pero lo pensaría dos veces antes de hacerlo. El código de prueba debe ser MUY simple. ¿Qué sucede si algo sale mal y hay un error en tu prueba? :) Sin embargo, debe intentar evitar la duplicación del código de prueba como una duplicación de código normal. Alguien tiene que mantener el código de prueba.

PERSONAS POR FAVOR comentario ¿Por qué usted piensa que esto valió la pena :) DOS downvotes

+0

No te voté de mala gana, pero supongo que la gente no estuvo de acuerdo con lo que dijiste sobre que no era necesario para probar casos extremos. Esos son exactamente los casos que necesitan más pruebas. Aparte de eso, pensé que tenías buenos puntos, esp. sobre errores en la prueba. – Clayton

+0

@Clayton - Ok, pero no entiendo estos casos "extremos" ... Es decir ... lo sé, esto es lo que lees en tu primer libro de pruebas de unidades, pero ¿cuál es el "caso límite" para esto? ¿ejemplo? ¿Alguien me puede decir? Asegurándose de que 2^32 funciona? ¿O eso -3 no? De acuerdo, ahora dime, ¿qué es 2^32? – badbadboy

+0

@Clayton - ¿Qué sé acerca de 2^32 en mi DOMINIO? Si sé que este es un caso específico importante para mí, lo probaré, pero ¿por qué llamarlo una prueba de vanguardia? Si su programa falla debido a una mala entrada del usuario, eso es un error en el manejo de su GUI, no en su clase de dominio. Sin embargo, acepto que – badbadboy

0

Algunas preguntas, las respuestas pueden informar a su decisión:

  • ¿Qué tan importante es el correcto funcionamiento de este código?
  • ¿Es probable que la implementación de este código se modifique en el futuro? (de ser así, pruebe más para respaldar el cambio futuro)
  • ¿Es probable que el contrato público de este código cambie en el futuro?(en caso afirmativo, pruebe menos; para reducir la cantidad de código de prueba descartable)
  • ¿Cómo es la cobertura del código? ¿Se visitan todas las sucursales?
  • Incluso si el código no se bifurca, ¿se evalúan las consideraciones de límites?
  • ¿Las pruebas se ejecutan rápidamente?

Editar: Hmm, para que te asesore en tu caso específico. Desde que comenzó a escribir pruebas unitarias ayer, es posible que no tenga la experiencia para decidir entre todos estos factores. Deja que te ayude:

  • Este código no es probablemente demasiado importante (nadie muere, nadie va a la guerra, nadie es demandado), por lo que un puñado de pruebas va a estar bien.
  • La implementación probablemente no cambie (las técnicas de números primos son bien conocidas), por lo que no necesitamos pruebas para respaldar esto. Si la implementación cambia, es probable que se deba a un valor de falla observado. Eso se puede agregar como una nueva prueba en el momento del cambio.
  • El contrato público de esto no cambiará.
  • Obtenga una cobertura de código del 100% sobre esto. No hay ninguna razón para escribir código que una prueba no visita en esta circunstancia. Debería poder hacer esto con un pequeño número de pruebas.
  • Si le importa lo que hace el código cuando se llama a cero, pruébelo.
  • El pequeño número de pruebas debe ejecutarse rápidamente. Esto les permitirá correr con frecuencia (tanto por los desarrolladores como por la automatización).

pondría a prueba 1, 2, 3, 21, 23, un "grande" prime (5 dígitos), un "grande" no prime y 0 si te importa lo que esto hace a 0.

+0

esto me pareció un poco engañoso para el tipo que comenzó las pruebas unitarias hoy o ayer. – badbadboy

+0

Quizás no sea la mejor respuesta de la OMI, pero ciertamente no vale la pena un voto negativo. Probadores experimentados en proyectos del mundo real tienen que considerar estos problemas, así que lo votaré nuevamente. – Cybis

+0

Siempre es difícil responder a la pregunta general o específica. Los votos negativos probablemente fueron merecidos y gracias por animarme a mejorar la respuesta. –

1

en general, la prueba más casos de los que necesita para sentirse cómodo/confianza

también, en general, prueba de la base/caja cero, el caso máximo, y al menos un medio/carrura

también prueba esperados -excepción de casos, si corresponde

si y no está seguro de su algoritmo principal, entonces sin dudas pruebe con los primeros 1000 números primos, para ganar confianza

+0

¿Qué quieres decir con esto? pruebe la base/cero caso, el caso máximo, y al menos una mediana/medio – badbadboy

+0

@badbadboy: suponga que su función toma un valor de entrada X con rango 0..N; el caso base/cero sería X = 0, el máximo sería X = N, y la mediana sería X = N/2. También probaría -1 y N + 1 para asegurarme de que fallaron como se esperaba. –

1

"Tenga cuidado con los errores. He comprobado que el algoritmo anterior es correcto, pero aún no lo he probado. "

Algunas personas no entienden la cita anterior (¿paráfrasis?), Pero tiene mucho sentido cuando lo piensas. Las pruebas nunca serán una prueba Algoritmo correcto, solo ayudan a indicar si lo ha codificado correctamente. Escriba pruebas para los errores que espera que puedan aparecer y para las condiciones de contorno para lograr una buena cobertura del código. No solo seleccione valores de la nada para ver si funcionan. , porque eso podría dar lugar a una gran cantidad de ensayos que todas las pruebas exactamente lo mismo.

para su ejemplo, simplemente a mano seleccionar algunos primos y no primos para poner a prueba las condiciones específicas de la aplicación.

+0

Aquí hay un punto realmente bueno pero sutil en el sentido de que desea tener en cuenta tanto la implementación como la especificación de su función al diseñar las pruebas. –

10

También me han informado que cada vez que se encuentra un error, debe escribir una prueba para verificar que esté solucionado. Me parece razonable, de todos modos.

+0

Excelente punto. Esto evita que vuelva a descubrir el error manualmente cuando cambie el código. –

+0

Este es, de hecho, el tipo de prueba más útil para proyectos de larga duración, en mi experiencia. Si se comete un error una vez, es probable que se vuelva a hacer más tarde, –

0

Para estar realmente seguro, tendrá que probarlos todos.:-)

Hablando en serio, para este tipo de función probablemente estés usando un algoritmo establecido y comprobado. Lo principal que debe hacer es verificar que su código implemente correctamente el algoritmo.

La otra cosa es asegurarse de que comprende los límites de la representación de su número, sea lo que sea. Por lo menos, esto pondrá un límite superior en el tamaño del número que puede probar. Por ejemplo, si usa una int sin signo de 32 bits, nunca podrá probar valores mayores a 4G. Posiblemente su límite será más bajo que eso, dependiendo de los detalles de su implementación.

Solo como un ejemplo de algo que podría salir mal con una implementación: Un algoritmo simple para probar los números primos es intentar dividir el candidato entre todas las primos conocidas hasta la raíz cuadrada del candidato. La función de raíz cuadrada no dará necesariamente un resultado exacto, por lo que para estar seguro debería ir un poco más allá. Hasta qué punto el pasado dependerá específicamente de cómo se implementa la función de raíz cuadrada y cuánto podría estar apagado.

Otra nota sobre las pruebas: además de probar los números primos conocidos para ver si su función los identifica correctamente como primos, también pruebe los números compuestos conocidos para asegurarse de que no obtiene "falsos positivos". Para asegurarte de que obtienes la función de raíz cuadrada correcta, elige algunos números compuestos que tengan un factor primo lo más cercano posible a su raíz cuadrada.

Además, considere cómo va a "generar" su lista de primos para la prueba. ¿Puedes confiar en que la lista sea correcta? ¿Cómo fueron probados esos números y por quién?

Puede considerar codificar dos funciones y probarlas una contra la otra. Uno podría ser un algoritmo simple pero lento que puede estar más seguro de haber codificado correctamente, y el otro uno más rápido pero más complejo que realmente desea usar en su aplicación, pero es más probable que tenga un error de codificación.

0

"Si vale la pena construirlo, vale la pena probarlo"
"Si no vale la pena probarlo, ¿por qué pierdes el tiempo trabajando en él?"

Supongo que no se suscribió para hacer una prueba primero, ¿dónde escribe la prueba antes de escribir el código?
No se preocupe, estoy seguro de que no está solo.
Como se ha dicho anteriormente, pruebe los bordes, excelente lugar para comenzar. También debe probar los casos malos, si solo prueba lo que sabe que funciona, puede estar seguro de que se producirá un caso negativo en la producción en el peor momento.

Oh y "Acabo de encontrar el último error" - HA HA.

Cuestiones relacionadas