Digamos que tenemos nuestro algoritmo de búsqueda de ruta:
def myHeuristicTSP(graph):
/*implementation*/
return route
Ahora queremos hacer una prueba unitaria de esto:
class TestMyHeuristicTSP:
def testNullGraphRaiseValueError(self):
self.assertRaises(ValueError, myHueristicTSP(None))
def testSimpleTwoNodeGraphReturnsRoute:
self.assertEquals(expectedResult, myHeuristicTSP(input))
La pregunta es, para un algoritmo TSP no heurístico, podemos dar una variedad de gráficos y verificar que siempre devuelvan absolutamente la ruta más corta.
Pero debido a que un algoritmo heurtístico, aunque todavía es determinista, es menos predecible, ¿simplemente tiene la intención de comprender cómo debe funcionar el algoritmo y encontrar esos casos límite?
unit-testing
heuristics
dwjohnston
fuente
fuente
Respuestas:
Para un algoritmo heurístico que se supone que no devuelve la solución ideal sino una solución "suficientemente buena", tendría varios casos de prueba y comprobaría
fuente
La mayoría de los algoritmos de optimización (incluidas las heurísticas) funcionan en algunas configuraciones (en su ejemplo, una ruta) mediante la aplicación de operaciones en ellas. Las operaciones por sí mismas deben garantizar que entreguen solo configuraciones válidas, por lo que primero debe haber pruebas unitarias para cada una de ellas. Cuando sepa con certeza que el algoritmo de optimización usa solo esas operaciones, normalmente no debería ser necesario realizar una prueba de validez del resultado del algoritmo.
Para crear buenas pruebas unitarias para cualquier tipo de algoritmo más complejo, uno tiene que conocer el algoritmo en detalle . Para heurísticas simples como "escalar montañas", generalmente puede predecir el resultado para entradas pequeñas. Por ejemplo, para rutas iniciales de 3 a 5 puntos, cuando se dan en un cierto orden, puede predecir lo que sucederá. Esto seguirá siendo cierto para la mayoría de los algoritmos heurísticos deterministas que conozco, por lo que probablemente sea un buen lugar para comenzar.
Para algoritmos más complejos y un mayor tamaño de la entrada, cuando solo ingresa la entrada en el algoritmo e intenta verificar la salida, en realidad ya no está haciendo una prueba unitaria, está haciendo una prueba de aceptación o integración. La razón por la que tiene problemas para "probar unitariamente" este tipo de algoritmo es porque generalmente consiste en un puñado de partes más pequeñas (unidades individuales). Entonces, para probar realmente un algoritmo de este tipo, tendrá que identificar esas partes y probarlas individualmente. Además, puede usar la cobertura de código o las técnicas de cobertura de sucursal para asegurarse de tener suficientes casos de prueba.
Si no está buscando pruebas unitarias, sino pruebas de aceptación o integración automatizadas, puede probar lo que @Phillip sugirió en (2) o (3) .
fuente