¿Existen marcos de prueba para el desarrollo de software numérico?

10

Descubrí que gran parte de mi programación de ciencias computacionales tiene requisitos de prueba que no están cubiertos por los marcos de prueba estándar:

  1. Prueba de tiempo de computación

    • Para asegurarse de que los algoritmos no sean más lentos. Podría hacer algo como, assureSmallerEqual(RuntimeWrapper(algorithm),53)pero me gustaría que el umbral de 53 segundos se reduzca continuamente mientras estoy trabajando en el algoritmo, es decir, algo comoassureSmallerEqual(RuntimeWrapper(algorithm),'previousbest+noisetolerance')
  2. Pruebas de rendimiento

    • Para asegurarse de que un algoritmo que previamente encontró una buena aproximación a una solución analítica todavía encuentre una solución que sea al menos tan buena o mejor. Nuevamente, esto podría ser emulado por una prueba de integración estándar, pero me gustaría que la tolerancia se reduzca continuamente a medida que el algoritmo mejora y mejora. Piense en reemplazar assureAlmostEqual(foo(),1,places=3)porassureAlmostEqual(foo(),1,places='previousbest')
  3. Pruebas de requisitos físicos.

    • Para asegurarse de que los algoritmos no necesiten repentinamente más memoria / espacio en el disco duro. Muy similar a 1.
  4. Prueba de requisitos abstractos

    • Para asegurarse de que un algoritmo que funcionó bien con aproximaciones cuadráticas no necesita repentinamente aproximaciones cúbicas, o que un algoritmo que funcionó bien con el paso de tiempo 0.1 no necesita repentinamente 0.01 para estabilidad. Una vez más, estos podrían ser emulados por pruebas de integración estándar, pero el objetivo es recordar cuál fue el parámetro de requisito más pequeño que logró cierto objetivo, por lo que esto requeriría una gran cantidad de actualización manual. Por ejemplo, si foo(10)anteriormente no arrojaba excepciones, me gustaría que el marco se asegurara de que foo(10)aún funcionara y también probar si foo(9)ahora funciona (en cuyo caso todas las pruebas futuras garantizarían que foo(9)todavía funcione).

Se podría argumentar que lo que estoy pidiendo no describe las pruebas en el sentido de pruebas de unidad / integración, ya que el aumento de los tiempos de ejecución, por ejemplo, podría ser aceptable a cambio de otras mejoras.
Sin embargo, en la práctica, sé que habría ahorrado mucho tiempo de depuración si tuviera la funcionalidad de prueba anterior, porque en el 95% de los casos los requisitos y el rendimiento no funcionaron debido a los errores que introduje. De hecho, sé con certeza que muchos errores que encontré (después de perder mucho tiempo comprobando mi propio código) con bibliotecas externas de software numérico podrían haberse evitado trivialmente si las pruebas anteriores se hubieran aplicado rigurosamente.

PD

La pregunta con el mismo nombre /programming/34982863/framework-for-regression-testing-of-numerical-code no es un duplicado, ya que describe la funcionalidad que es más fácil de lograr con los marcos de prueba de regresión estándar.

La pregunta Estrategias para pruebas unitarias y desarrollo basado en pruebas pide estrategias en lugar de un marco que ayuda a implementarlas (y las estrategias que solicita / que se proporcionan en las respuestas son diferentes de lo que describo aquí, en mi opinión).

Bananach
fuente
1
¿Es el software numérico para simulación o para análisis de datos experimentales?
Matthew Gunther
1
@mathewgunther Análisis numérico / Álgebra numérica. Sin análisis de datos
Bananach
1
Sé que muchas grandes empresas de simulación usan marcos que crearon por su cuenta. Básicamente en python. Necesita tener casos de prueba iniciados por los scripts de Python y escribir algunos resultados. Posteriormente, los resultados se pueden comparar con algún tipo de referencia y generar un informe. La prueba se puede automized una carrera diaria o semanal o mensual, etc. No es seguro si hay algún tipo de marco generel como software de simulación siempre es una especie de especial en la aplicación, etc.
vydesaster

Respuestas:

4

1. Este tipo de prueba me parece mal definida porque su condición de prueba está vinculada a la máquina en particular en la que realizó las pruebas en desarrollo. Uno de los puntos de prueba es que ejecutar sus pruebas en mi computadora portátil me dice si hay algo mal con el código o el entorno que he configurado. Los 53 segundos son específicos para su máquina de desarrollo, y el tiempo de ejecución también aumentará si la máquina de prueba está bajo carga de otras cargas de trabajo o usuarios. No esperaría que los marcos de prueba aborden esto: "la función se ejecuta en la entrada en menos de 53 segundos" no es una muy buena especificación de corrección.

2. Creo que esto es ambiguo e indeseable desde el punto de vista de las pruebas de software por las mismas razones 1 , pierde la justificación de aprobar o reprobar las pruebas de software.

3. Esto es bastante común, permítanme describir una solución. No es exactamente el trabajo de un marco de prueba, pero puede usar una herramienta separada como se describe en la pregunta de Unix SE Limite el uso de memoria para un solo proceso de Linux . Una herramienta estándar para probar primero es el ulimitcomando bash, que le permite ejecutar un proceso y asegurarse de que se bloquea si intenta, por ejemplo, asignar demasiada memoria. Entonces, si ejecuta el runtestsscript con un límite de memoria, se bloqueará y el marco de prueba debería ser capaz de manejarlo como una falla de prueba regular.

4. La mayoría de las infraestructuras de prueba no piensa en la unidad de pruebas de esta manera en absoluto . El conjunto de pruebas se ejecuta (p. Ej., Antes de confirmar el código al maestro o antes de la implementación), y el resultado es un sí o un no que indica si funciona. Los marcos de prueba no consideran que sea parte de su trabajo, por ejemplo, rastrear el progreso de las características, y eso no es lo que generalmente es la prueba. Lo que harías aquí es escribir dos pruebas expect_succeeds(foo(10)); expect_fails(foo(9)). Cada vez, se ejecutan ambas pruebas y pasan los éxitos y las fallas esperadas. Cuando implementa foo(9)y tiene éxito, la prueba de falla esperada ahora falla, por lo que volvería a escribirexpect_succeeds(foo(9)), y esta es una característica absolutamente estándar de todos los marcos. Pero debe ser explícito sobre el comportamiento que espera, porque de lo contrario simplemente va en contra de las ideas básicas de las pruebas de software.

AAABperforms_better(foo_A(), foo_B())BAB, y (b) ya no hay ningún sentido de comparar el código con lo que solía ser, todo el código y las pruebas ahora son inmutables y sin ambigüedades. Esto es similar en espíritu a cómo uno podría manejar las reescrituras del sistema.

Kirill
fuente