Como nos estamos volviendo cada vez más dependientes de la informática, incluidas las tareas muy críticas de la vida cotidiana, me preguntaba cómo se prueban esos componentes vitales.
Más técnicamente, ¿cómo se prueban los compiladores y ensambladores? (¡Supongo que esto se relaciona con el problema de detención !)
programming-practices
compiler
theory
Sudip Bhandari
fuente
fuente
Respuestas:
No puedes estar seguro, pero solo asumes que lo son, hasta que descubres que no lo son. Ha habido muchos errores en compiladores y hardware a lo largo de los años.
La forma en que se prueban, por ejemplo, un compilador, es que se definen de forma muy estrecha y rígida, se escriben cuidadosamente y luego se prueban con un enorme conjunto de pruebas para verificar la corrección. Agregue a eso la amplia base de usuarios de un compilador, y se detectarán e informarán más errores. Una aplicación de programación de citas con el dentista, comparativamente, tiene muchos menos usuarios y aún menos capaces de detectar defectos.
SQLite consta de aproximadamente 73k líneas de código, mientras que su conjunto de pruebas consta de aproximadamente 91378k líneas de código, más de 1250 veces más que el propio SQLite. Espero que los compiladores y otras herramientas centrales tengan proporciones similares. Los procesadores de hoy están diseñados esencialmente con software, utilizando lenguajes de descripción de hardware como Verilog o VHDL, y también tienen pruebas de software ejecutadas en ellos, así como pines de E / S especializados para ejecutar autocomprobaciones en el punto de fabricación.
En última instancia, es un juego de probabilidad, y las pruebas repetidas y de cobertura amplia le permiten reducir la probabilidad de defectos a un nivel aceptablemente bajo, lo mismo que otro proyecto de software.
fuente
En términos simples:
Línea de fondo:
Yo diría que vaya a OOP ( O ld, O pen y P opular). Acabo de inventar ese acrónimo.
fuente
Son tortugas hasta el fondo.
Nada es seguro. No tiene más remedio que conformarse con las calificaciones de confianza.
Puede pensarlo como una pila: Matemáticas> Física> Hardware> Firmware> Sistema operativo> Ensamblador / Compilador / etc.
En cada nivel tiene pruebas que puede realizar para mejorar sus índices de confianza. Algunas de estas pruebas tienen la calidad de pruebas formales, algunas se basan en la observación, la mayoría son una combinación de ambas.
La parte difícil es desentrañar la recursividad en algunas de estas pruebas porque usamos programas para hacer pruebas y análisis de observación ahora donde se ha vuelto demasiado difícil hacerlo a mano.
Finalmente, la respuesta es que intentas todo lo que se te ocurre. Análisis estático, fuzzing, simulación, ejecución con entradas extremas seleccionadas a propósito o entradas aleatorias, ejecución / mapeo de cada ruta de control, pruebas formales, etc. Básicamente, su objetivo en las pruebas siempre debe ser hacer todo lo posible para demostrar que su producto (por ejemplo, teoría / chip / programa) no funciona según lo previsto. Si hace un esfuerzo genuino y aún falla, puede mejorar su índice de confianza en la corrección de su producto.
Las pruebas son, en el mejor de los casos, un proceso de semidecisión, lo que significa que dado que hay un error, eventualmente lo encontrará, pero nunca puede estar seguro de haberlo encontrado a todos. Incluso con el software verificado formalmente, usted sigue confiando en la física, las herramientas utilizadas para hacer las pruebas formales, y que lo que probó es necesario y suficiente para que su programa haga lo que (a menudo subjetivamente) está "previsto". Eso sin mencionar todos los otros componentes que está utilizando que no tienen pruebas formales.
fuente
Esta es una pregunta "peligrosa" para los nuevos desarrolladores, ya que comenzarán a culpar a sus herramientas en lugar de su código (estado allí, hecho eso, visto que muchos lo hacen). Aunque hay errores en los compiladores, entornos de tiempo de ejecución, sistema operativo, etc., los desarrolladores deben ser realistas y recordar que, hasta que haya pruebas y pruebas unitarias que demuestren lo contrario, el error está en su código .
En más de 25 años de programación en su mayoría en C, C ++ y Java, he encontrado:
Todos los otros errores están directamente relacionados con un error o, más frecuentemente, con la falta de comprensión de cómo funciona una biblioteca. A veces, lo que parece ser un error se debe a una incompatibilidad, por ejemplo, cómo cambió la estructura de clases de Java que rompió algunas bibliotecas AOP.
fuente
Creo que un punto interesante aquí es que la gran mayoría de las licencias de software comercial (y de hecho software de código abierto) especifican específicamente que no puede confiar en el software.
Del acuerdo de licencia de Microsoft Word
En esencia, esta oración en la licencia de casi todos los programas que usa específicamente le dice que no puede confiar en el software y mucho menos en el compilador utilizado.
El software es como una teoría científica, se considera que funciona como se especifica hasta que no funciona.
fuente
Como escritor compilador de un lenguaje matemático *, desde mi experiencia puedo decir en teoría que tú no puedes. Y algunos de los errores solo dan resultados incorrectos como (de mi lista de vergüenza) calcular
6/3*2
desde la derecha6/(3*2)
y generar 1 sin fallar ni dar errores de compilación sin sentido.Pero en mi humilde opinión, muchos compiladores no tienen tantos errores como otro software porque:
test_unit("2+(-2)*(-2+1)*3+1",9);
Para ensambladores, instrucciones de máquina, etc., lo anterior también es válido; Por otro lado, la verificación y validación en el diseño y la producción de chips tienen procesos mucho más estrictos, ya que es un gran negocio: la automatización del diseño electrónico .
Antes de pasar a producción, cada CPU debe probarse rigurosamente porque cada error cuesta casi un par de millones de dólares: existen enormes costos de producción no recurrentes en la producción de chips. Por lo tanto, las empresas gastan mucho dinero y escriben mucho código de simulación para su diseño antes de comenzar la producción, aunque esto no ofrece una garantía del 100%, por ejemplo: el error Pentium FDIV.
En resumen, es muy poco probable que tenga errores graves en los compiladores, códigos de máquina, etc.
Mi humilde lenguaje matemático *
fuente
¿Perfecto? Ellos no están. Recientemente instalé algunas "actualizaciones", y pasaron meses (y varias secciones de código reprogramadas) más tarde antes de que mi sitio ASP.NET volviera a funcionar correctamente, debido a cambios inexplicables en cómo funcionaban o fallaban varias cosas básicas.
Sin embargo, son probados y luego utilizados por muchas personas muy inteligentes orientadas a los detalles, que tienden a notar, informar y corregir la mayoría de las cosas. Stack Exchange es un gran ejemplo (y mejora) de cómo todas las personas que usan esas herramientas ayudan a probar y analizar cómo funcionan estas herramientas increíblemente complejas y de bajo nivel, al menos en lo que respecta al uso práctico.
Pero perfecto, no. Aunque también puede ver a las personas en Stack Exchange obteniendo una visión impresionante de los detalles de rendimiento y el cumplimiento de estándares y peculiaridades, siempre hay fallas e imperfecciones, especialmente cuando diferentes personas tienen diferentes opiniones sobre lo que es una falla.
fuente
Para demostrar que los sistemas subyacentes son perfectos
a) Necesidad de probar que son impecables
b) Hacer una prueba exhaustiva
En las pruebas de software, la prueba exhaustiva solo se usa en pruebas unitarias de algunas funciones simples.
Ejemplo: si desea probar una entrada utf-8 de 8 caracteres en algún campo, elige cortar la entrada a 8 veces la longitud máxima 6 de utf-8 en bytes, lo que da 8 * 6 = 48 bytes para tener realmente un cantidades finitas de posibilidades.
Ahora podría pensar que solo necesita probar los 1.112.064 puntos de código válidos de cada uno de los 8 caracteres, es decir. 1,112,064 ^ 8 (digamos 10 ^ 48) pruebas (que ya es poco probable que sea posible), pero en realidad tienes que probar cada valor de cada uno de los 48 bytes o 256 ^ 48, que es alrededor de 10 ^ 120, que es la misma complejidad que el ajedrez en comparación con el número total de átomos en el universo de aproximadamente 10 ^ 80.
En su lugar, puede usar, en orden creciente de esfuerzo, y cada prueba debe cubrir todo lo anterior:
a) pruebe una buena y una mala muestra.
b) cobertura de código, es decir. intente probar cada línea de código, que es relativamente simple para la mayoría de los códigos. Ahora puede preguntarse cuál es el último 1% del código que no puede probar ... errores, código muerto, excepciones de hardware, etc.
c) cobertura de ruta, se prueban todos los resultados de todas las ramas en todas las combinaciones. Ahora sabe por qué el departamento de pruebas lo odia cuando sus funciones contienen más de 10 condiciones. También te preguntas por qué no se puede probar el último 1% ... algunas ramas dependen de las ramas anteriores.
d) prueba de datos, prueba una cantidad de muestra con valor de borde, valores problemáticos comunes y números mágicos, cero, -1, 1, min +/- 1, max +/- 1, 42, valores rnd. Si esto no le brinda cobertura de ruta, sabe que no ha captado todos los valores en su análisis.
Si ya lo hace, debería estar listo para el examen básico de ISTQB.
fuente