Sabemos que escribir pruebas JUnit demuestra una ruta particular a través de su código.
Uno de mis asociados comentó:
La escritura manual de pruebas unitarias es prueba por ejemplo .
Provenía de Haskell, que tiene herramientas como Quickcheck y la capacidad de razonar sobre el comportamiento del programa con los tipos .
Su implicación fue que hay muchas otras combinaciones de entradas que no se prueban con este método para las cuales su código no se prueba.
Mi pregunta es: ¿están escribiendo manualmente pruebas unitarias de prueba por ejemplo?
unit-testing
junit
ojo de halcón
fuente
fuente
Respuestas:
Si elige aleatoriamente entradas para la prueba, entonces supongo que es posible que esté ejerciendo una falacia lógica de Prueba por ejemplo.
Pero las buenas pruebas unitarias nunca hacen eso. En cambio, tratan en rangos y casos extremos.
Por ejemplo, si escribiera pruebas unitarias para una función de valor absoluto que acepta un entero como entrada, no necesitaría probar todos los valores posibles de entrada para demostrar que el código funciona. Para obtener una prueba exhaustiva, necesitaría solo cinco valores: -1, 0, 1 y los valores máximo y mínimo para el entero de entrada.
Estos cinco valores prueban cada rango posible y caso límite de la función. No necesita probar cualquier otro valor de entrada posible (es decir, cada número que el tipo entero puede representar) para obtener un alto nivel de confianza de que la función funciona para todos los valores de entrada.
fuente
int foo(int x) { return 1234/(x - 100); }
. También tenga en cuenta que (dependiendo de lo que esté probando) es posible que deba asegurarse de que la entrada no válida ("fuera de rango") devuelva resultados correctos (por ejemplo, `` find_thing (thing) `devuelve correctamente algún tipo de estado" no encontrado " si la cosa no fue encontrada).-Inf
,Inf
,NaN
,1e-100
,-1e-100
,-0
,2e200
... prefiero no tengo que hacer todos los manualmente.Cualquier prueba de software es como "Prueba por ejemplo", no solo pruebas unitarias utilizando una herramienta como JUnit. Y eso no es nueva sabiduría, hay una cita de Dijkstra de 1960, que dice esencialmente lo mismo:
(solo reemplace las palabras "shows" por "pruebas"). Sin embargo, esto también es cierto para las herramientas que generan datos de prueba aleatorios. El número de posibles entradas para una función del mundo real suele ser mayor en órdenes de magnitud que el número de casos de prueba que uno puede producir y verificar contra un resultado esperado dentro de la edad del universo, independientemente del método de generación de esos casos, por lo que incluso si uno usa una herramienta generadora para producir muchos datos de prueba, no hay garantía de no perderse el único caso de prueba que podría haber detectado un determinado error.
Las pruebas aleatorias a veces pueden revelar un error que fue ignorado por los casos de prueba creados manualmente. Pero, en general, es más eficiente diseñar cuidadosamente las pruebas para la función que se va a probar, y asegurarse de que uno obtenga un código completo y una cobertura de ramificación con el menor número de casos de prueba posible. A veces es una estrategia factible combinar pruebas generadas manualmente y al azar. Además, cuando se usan pruebas aleatorias, uno debe tener cuidado para obtener los resultados de manera reproducible.
Por lo tanto, las pruebas creadas manualmente no son peores que las pruebas generadas al azar, a menudo todo lo contrario.
fuente
Escribir pruebas manualmente es "prueba con el ejemplo". Pero también lo es QuickCheck y, en cierta medida, los sistemas de tipos. Cualquier cosa que no sea una verificación formal directa estará limitada en lo que le dice sobre su código. En cambio, debe pensar en términos del mérito relativo de los enfoques.
Las pruebas generativas, como QuickCheck, son realmente buenas para barrer un amplio espacio de entradas. También es mucho mejor para abordar casos extremos que las pruebas manuales: las bibliotecas de pruebas generativas tendrán más experiencia con esto que usted. Por otro lado, solo le informan sobre invariantes, no resultados específicos. Entonces, para validar que su programa está obteniendo los resultados correctos, aún necesita algunas pruebas manuales para verificar que, de hecho
foo(bar) = baz
,.fuente