tiobe programming programación programacion lenguaje languages indice bcpl apple programming-languages tdd

programming-languages - programming - tiobe ranking



Un lenguaje de programación diseñado para ser comprobado (14)

¿Qué lenguajes de programación son verificables por diseño?

Estoy teniendo problemas con esta pregunta, porque no estoy seguro de lo que significa que un idioma sea comprobable por diseño. Las pruebas generalmente tratan sobre herramientas y análisis estáticos, no sobre el diseño del lenguaje.

Pero en la medida en que un idioma puede ser probado, voy a suponer que esto significa que el lenguaje incluye algún tipo de especificación independiente que puede probarse contra el código y, además, que estas especificaciones han sido diseñadas teniendo en cuenta las pruebas, o al menos no solo para la demostración de teoremas.

Según estos criterios, conozco tres:

  • Eiffel , donde el "diseño por contrato" lo alienta a poner condiciones previas y posteriores en su código, y se prueban. Considero Eiffel un lenguaje implementado con éxito.

  • Racket (anteriormente PLT Scheme), donde se realizan investigaciones interesantes en contratos y pruebas; Los aspectos interesantes son que cuando falla una prueba, el lenguaje no solo te dice que se violó un contrato, sino que también identifica qué parte del código se debe culpar. Para obtener más información, busque a Robby Findler en Google y a "culpar". Racket es un lenguaje de investigación, pero es una extensión de Scheme, que se usa ampliamente para un lenguaje de nicho.

  • Ana , una extensión de Ada hecha por David Luckham y sus estudiantes, que apoyó algunas pruebas. Por lo que sé, Ana nunca pasó de la etapa de investigación.

Además de estos idiomas, hay innumerables idiomas que han tenido afirmaciones para fines de demostración de teoremas. Muchos de estos lenguajes tenían afirmaciones que no eran comprobables de ninguna manera eficiente (los cuantificadores existenciales y universales te lo harán).

¿Hay un lenguaje de programación que pueda probarse por diseño o que al menos muestre muy buenas propiedades en términos de capacidad de prueba?

Por ejemplo, un lenguaje de programación diseñado para que la prueba unitaria sea una parte no opcional del proceso de codificación o, mejor aún, un lenguaje de programación donde el programa se deduce más o menos de las pruebas unitarias.

O si prefiere cambiar la pregunta un poco, ¿qué programación imperativa es mala práctica o innecesaria para garantizar la capacidad de prueba?

¿Qué hay de la programación orientada a objetos? Cosas como la inyección de dependencia y las bibliotecas burlonas realmente ayudaron a TDD , ¿no beneficiarían estas prácticas de formar parte del diseño del lenguaje? He estado mirando alrededor y los lenguajes con modelos meta enriquecidos tienden a permitir que se escriban API similares a DSL en el idioma de destino. Estas bibliotecas se están construyendo además de eso, ¿por qué no incluir estas cosas en el lenguaje en sí?

Encuentro que esa publicación de blog a la que hace referencia James Black tiene un muy buen punto.

No hace mucho tiempo, reflexioné sobre mis hábitos de prueba durante los últimos diez años, e hice un par de observaciones interesantes:

  • Siento la necesidad de escribir pruebas para el código que escribo muy a menudo.
  • Con la misma frecuencia, esa necesidad se ve frustrada por las limitaciones medioambientales, así que termino no escribiendo estas pruebas.

¿Está de acuerdo con la afirmación de que los lenguajes de programación dinámicos facilitan las pruebas de escritura?


Creo que Ruby está donde está.

Herramientas como el cucumber : cuando escribes historias de usuarios en un lenguaje casi natural que la gente de negocios puede entender y luego, en realidad, obtener su aprobación es increíble como una ''herramienta TDD''.

No se trata tanto de escribir ''pruebas'' sino más bien de comenzar con lo que el cliente quiere y de tener herramientas que lo usen como especificación para construir.

Además de rspec , shoula, maquinista, impostor y el resto hacen de Ruby una verdadera consideración si es allí donde te interesan las mentiras.

También diría que la capacidad de crear su propia DSL pone a los idiomas dinámicos al frente en este ámbito.


Google está trabajando en noop como un lenguaje (OOP, basado en Java) creado para producir código que siempre es comprobable.

Noop es un nuevo lenguaje que se ejecutará en la Máquina Virtual de Java, y en su forma original se verá similar a Java. El objetivo es construir la inyección de dependencia y la capacidad de prueba en el lenguaje desde el principio, en lugar de depender de bibliotecas de terceros como lo hacen otros lenguajes.

El lenguaje también prohíbe explícitamente ciertas construcciones que dificultan la prueba del código, como por ejemplo la estática.


La respuesta aceptada para Noop ahora es un lenguaje muerto. Wake es un nuevo lenguaje con muchos de los mismos objetivos (como la capacidad de prueba), que todavía está en desarrollo pero que es una mejor respuesta a la pregunta actual.


Los lenguajes de tipo dinámico (Python, Ruby, etc.) han tenido algunas de las suites de pruebas más grandes y mejores que he visto en mi vida. Tengo más experiencia con Python, así que me concentraré en ello, pero casi todos los atributos de Python y Ruby son equivalentes con respecto a su capacidad de prueba, y la propensión de los proyectos de código abierto que la usan para incluir suites de prueba.

Hay muchos ejemplos concretos de proyectos del mundo real que son grandes y que utilizan mucha gente, que tienen grandes conjuntos de pruebas grandes, son ejemplos prácticos de buenos resultados en el software de prueba y están escritos los que me son más familiares. en Python. Sin embargo, quizás la gente de SQLite (C / C ++) merezca un poco de crédito por construir una de las suites de prueba más completas en todo el mundo de código abierto, también.

Los paquetes de prueba de Python son (como todos los códigos de aplicaciones Python) generalmente más cortos, más fáciles de escribir y más fáciles de leer que cualquier otro idioma que haya utilizado. Y, sin embargo, aunque no creo que C / C ++ en particular sea un lenguaje muy fácil para escribir pruebas, y que era más probable la pasión y habilidad técnica de los desarrolladores en el proyecto SQLite, y la necesidad de poder confiar su trabajo, que lleva a escribir un conjunto de pruebas amplio, minucioso y efectivo en C ++, y nada que ver con el lenguaje C ++ en sí mismo.

Entonces, Python te ayuda al hacer que escribir tus aplicaciones sea más fácil, dándote tiempo para escribir pruebas, eso es todo. Pero donde C ++ carece de características que lo ayuden a escribir pruebas, y le lleva más tiempo construir lo mismo en C ++, algunos desarrolladores aún ofrecen la habilidad y la dedicación y lo hacen posible de todos modos, a cualquier costo de tiempo y esfuerzo.

Si bien ciertas características en un idioma aseguran formalmente la cobertura del código en los lenguajes populares compilados y dinámicos, de alcance muy limitado, creo que el camino correcto es corregir sus formalismos, no cambiar su idioma. El problema no es que el mundo real no cumpla con mis requisitos formales de prueba, sino que los límites de lo alcanzable en el mundo real deben abordarse cambiando la forma en que construimos nuestra definición formal de qué tan probado está el código (cobertura del código , por ejemplo). En otras palabras, las abstracciones con fugas en nuestros formalismos de prueba son lo que nos falla, no la tecnología real existente (C / C ++).

Las pruebas son definitivamente una parte OPCIONAL del proceso, como todo en Python, se impone muy poco sobre ti. Sin embargo, yo diría que cualquier lenguaje que encuentre la forma de FORZARLE a escribir pruebas en lugar de FOMENTAR ese buen comportamiento es, de hecho, un ejemplo de tratar de legislar las prácticas de codificación, que está destinado a ser contraproducente.

Francamente, no entiendo cómo se puede diseñar un idioma de una manera que te obligue a poner a prueba, sin convertir el lenguaje en un trivet académico completamente inútil. Al igual que muchos otros, considero que la usabilidad de un idioma para hacer un trabajo real en un trabajo real es mucho más importante que las nociones de formalismo marfil y la corrección demostrable.

Por otro lado, considero que la mejor manera de liberar a un desarrollador para que escriba muchas pruebas, y poder probar su código de forma efectiva, es eliminar la complejidad accidental del desarrollo. Creo que Python y Delphi, que son los dos idiomas en los que soy más competente, hacen más para aliviar esta carga que otros lenguajes ampliamente utilizados en el desarrollo comercial y de código abierto. Debido al tiempo extra que no tuve que gastar para descubrir cuántas páginas de murmullo demorarían en escribir el código de mi aplicación principal, ahora encuentro que tengo medio día para probar la corrección, escalabilidad e incluso hacer algunas pruebas multiplataforma

No preguntes qué puedes hacer por tus formalismos, sino lo que tus formalismos pueden hacer para volver a la tierra.


Mientras jugaba con el concepto de Zero Button Testing , un lenguaje de prueba forzada / IDE surgió de forma natural. Es solo un lenguaje de juguete, pero la idea está ahí dentro: cualquier línea que no esté cubierta por pruebas aparece en amarillo, y cualquier función con líneas no probadas podría considerarse no ejecutable (aunque el proyecto nunca llegó tan lejos) .

La idea aquí es que las pruebas se integran directamente en el procedimiento que están probando; funciona en este tipo de escala, pero tengo dudas sobre la escalabilidad final del enfoque.


No es que yo sepa, pero lo más cerca que he llegado a esto es probablemente Eiffel . También funciona bien con .NET


Nunca he visto nada donde las pruebas no sean opcionales, integradas o inferidas, pero el lenguaje más "irritable" que he visto es Ruby : viene con herramientas de prueba de unidades listas para usar, es fácil de probar y simular porque los tipos son dinámicos y, en general, la comunidad está muy avanzada en las prácticas de prueba (con muchas herramientas TDD y BDD disponibles). Aunque noto una extraña falta de herramientas de cobertura de código.


También Erlang a Erlang en el anillo, y sigo muchos de los comentarios en torno a los lenguajes funcionales. Las extensiones de especificación permiten la validación en tiempo de compilación de los contratos, y EUnit es excelente.

Además, las estrategias, como los patrones de guardia, son construcciones de lenguaje integrales que expresan la intención de tu máquina de estado y afirman cuando violas esa intención.


The Spring Framework se centra en la inyección de dependencias y la creación de Objetos simples antiguos de Java (POJO) fácilmente comprobables.


Un lenguaje puramente funcional como Haskell podría ser un buen candidato, ya que en tales funciones de lenguaje no tienen efectos secundarios y siempre producirán los mismos resultados con la misma entrada.


Un lenguaje que tenga un diseño por contrato como Eiffel (o iContract en Java) podría ser una buena idea. De esta forma, puede probar las condiciones previas y posteriores, así como las invariantes de clase con bastante facilidad.

Además de eso, TDD es en gran parte neutral en cuanto al lenguaje.


Maude es probablemente un ejemplo extremo: cada programa es una teoría en lógica de reescritura algebraica, y puede estar directamente sujeto a pruebas constructivas.


Fortress parece estar diseñado para tener más características de pruebas unitarias incorporadas, pero, de acuerdo con este blog, D también puede diseñarse para que las pruebas unitarias puedan ser parte de tu clase.

http://beust.com/weblog2/archives/000522.html

ACTUALIZAR:

El blog al que se hace referencia anteriormente trata la pregunta para esta publicación, ya que el título es:

¿Deben los lenguajes de programación soportar la prueba unitaria de forma nativa?

Entonces hay comentarios sobre otros idiomas con respecto a las pruebas.