Todos los programas, excepto los más triviales, están llenos de errores, por lo que todo lo que promete eliminarlos es extremadamente atractivo. Por el momento, las pruebas de corrección son código es extremadamente esotérico, principalmente debido a la dificultad de aprender esto y el esfuerzo adicional que se requiere para probar que un programa es correcto. ¿Crees que la prueba de código despegará?
programming-practices
Casebash
fuente
fuente
no se puede probar que sea correcto con un esfuerzo razonable. Para cualquier prueba formal de corrección, necesita al menos una especificación formal, y esa especificación debe ser completa y correcta. Normalmente, esto no es nada que pueda crear fácilmente para la mayoría de los programas del mundo real. Por ejemplo, intente escribir tal especificación para algo como la interfaz de usuario de este sitio de discusión, y ya sabe a qué me refiero.
Aquí encontré un buen artículo sobre el tema:
http://www.encyclopedia.com/doc/1O11-procorcornessnessproof.html
fuente
printf("1")
es correcto o no (por ejemplo, porque el requisito era "imprimir un número aleatorio igualmente distribuido de 1 a 6") no puede decidirse con un analizador estático de este tipo.El problema con las pruebas formales es que solo mueve el problema un paso atrás.
Decir que un programa es correcto es equivalente a decir que un programa hace lo que debería hacer. ¿Cómo define lo que debe hacer el programa? Usted lo especifica ¿Y cómo define lo que debe hacer el programa en casos extremos que la especificación no cubre? Bueno, entonces tienes que hacer la especificación más detallada.
Entonces, digamos que su especificación finalmente se vuelve lo suficientemente detallada como para describir el comportamiento correcto de cada aspecto de todo el programa. Ahora necesita una manera de hacer que sus herramientas de prueba lo entiendan. Así que tienes que traducir la especificación a algún tipo de lenguaje formal que la herramienta de prueba pueda entender ... ¡oye, espera un minuto!
fuente
La verificación formal ha recorrido un largo camino, pero generalmente las herramientas de la industria / ampliamente utilizadas van a la zaga de las últimas investigaciones. Aquí hay algunos esfuerzos recientes en esta dirección:
Spec # http://research.microsoft.com/en-us/projects/specsharp/ Esta es una extensión de C # que admite contratos de código (condiciones previas / posteriores e invariantes) y puede usar estos contratos para hacer varios tipos de análisis estático .
Existen proyectos similares a este para otros idiomas, como JML para Java, y Eiffel tiene esto bastante integrado.
Yendo aún más lejos, los proyectos como slam y blast se pueden usar para verificar ciertas propiedades de comportamiento con una mínima anotación / intervención del programador, pero aún no se pueden tratar con la generalidad completa de los lenguajes modernos (cosas como el desbordamiento de enteros / aritmética de puntero no se modelan).
Creo que veremos muchas más de estas técnicas utilizadas en la práctica en el futuro. La barrera principal es que los invariantes del programa son difíciles de inferir sin anotaciones manuales, y los programadores generalmente no están dispuestos a proporcionar estas anotaciones porque hacerlo es demasiado tedioso / lento.
fuente
No, a menos que surja un método para probar automáticamente el código sin un extenso trabajo del desarrollador.
fuente
Algunas herramientas de métodos formales (como, por ejemplo, Frama-C para software C incrustado crítico) se pueden ver como (una especie de) que proporcionan, o al menos comprueban, una prueba (correcta) de un software dado. (Frama-C verifica que un programa obedezca su especificación formalizada, en cierto sentido, y respete invariablemente las anotaciones anotadas en el programa).
En algunos sectores, tales métodos formales son posibles, por ejemplo, como DO-178C para software crítico en aeronaves civiles. Entonces, en algunos casos, tales enfoques son posibles y útiles.
Por supuesto, desarrollar software con menos errores es muy costoso. Pero el enfoque del método formal tiene sentido para algún tipo de software. Si es pesimista, puede pensar que el error se mueve del código a su especificación formal (que puede tener algunos "errores", porque formalizar el comportamiento previsto de un software es difícil y propenso a errores).
fuente
Me topé con esta pregunta y creo que este enlace podría ser interesante:
Aplicaciones industriales de Astrée
Probar la ausencia de RTE en un sistema utilizado por Airbus con más de 130,000 líneas de código en 2003 no parece ser malo, y me pregunto si habrá alguien que diga que este no es el mundo real.
fuente
No. El proverbio común para esto es: "En teoría, la teoría y la práctica son lo mismo. En la práctica, no".
Un ejemplo muy simple: errores tipográficos.
En realidad, ejecutar el código a través de pruebas unitarias encuentra tales cosas casi de inmediato, y un conjunto coherente de pruebas negará la necesidad de pruebas formales. Todos los casos de uso (buenos, malos, errores y casos extremos) deben enumerarse en las pruebas unitarias, que terminan como una mejor prueba de que el código es correcto que cualquier prueba que esté separada del código.
Especialmente si los requisitos cambian o el algoritmo se actualiza para corregir un error: es más probable que la prueba formal termine desactualizada, al igual que los comentarios de código a menudo.
fuente
Creo que los límites impuestos a las pruebas de corrección debido al problema de detención podrían ser la mayor barrera para que las pruebas de corrección se generalicen.
fuente
Ya lo usan todos. Cada vez que utiliza la verificación de tipo de su lenguaje de programación, básicamente está haciendo una prueba matemática de la exactitud de su programa. Esto ya funciona muy bien, solo requiere que elija los tipos correctos para cada función y estructura de datos que utiliza. Cuanto más preciso sea el tipo, mejor será la comprobación que obtendrá. Los tipos existentes disponibles en lenguajes de programación ya tienen herramientas lo suficientemente potentes como para describir casi cualquier comportamiento posible. Esto funciona en todos los idiomas disponibles. C ++ y los lenguajes estáticos solo están haciendo las comprobaciones en tiempo de compilación, mientras que los lenguajes más dinámicos como python lo hacen cuando se ejecuta el programa. El cheque todavía existe en todos estos idiomas. (por ejemplo, c ++ ya admite la comprobación de efectos secundarios de la misma manera que lo hace haskell,
fuente
mutable
oconst_cast
. Ciertamente veo la conexión que trazas allí, pero el sabor de dos enfoques me parece bastante diferente.