Código de prueba de envío. ¿Por qué no lo harías?

17

Me gustaría enviar el código de prueba junto con un producto. Específicamente, brinde una opción para que cualquier persona que tenga una copia de nuestro programa pueda presionar un botón de "autocomprobación" o pasar una autoevaluación en la línea de comandos y ejecutar el conjunto completo de unidades | pruebas de integración.

Principalmente quiero hacer esto para ayudar a los problemas de depuración descubiertos en el campo, por lo que cuando un informe de error llega de un usuario final, existe la posibilidad de que sea compatible con "y también, estas tres pruebas fallaron en mi máquina". Me gustaría que los probadores manuales puedan ejecutar la unidad | pruebas de integración también.

Sin embargo, la prueba del equipo cree que el código de prueba no es un código de producción y, por lo tanto, no se enviará. Realmente no entiendo este argumento, ya que la mayoría de los proyectos de código abierto incluyen un conjunto de pruebas. Parece ser inusual en software cerrado.

Me gustaría respaldar evidencia o anécdotas para cada lado del argumento. He adivinado cuál es el sitio de intercambio de pila más apropiado, pero avíseme si esto está fuera de lugar.

Jon Chesterfield
fuente
8
¿Por qué falla una prueba unitaria en un programa de código cerrado (o un programa de código abierto que no ha sido modificado)? Si su producto requiere una buena cantidad de problemas de configuración y configuración a menudo son la fuente de errores, podría tener sentido enviar algún tipo de aplicación "validar mi configuración" que haga cosas como validar la conexión de la base de datos, validar las conexiones a cualquier otro servicio externo sin embargo, su código depende de, etc. No tendría sentido que una prueba unitaria falle, ya que ya ha validado que el código funciona.
Justin Cave
15
¿Por qué una prueba unitaria falla en el campo? Fuera de mi cabeza: programa corrupto. Dodgy hardware. Condiciones de carrera que no vimos localmente. Vinculado a una biblioteca dinámica diferente. Conflictos con antivirus u OS. Se utiliza con una versión sorprendente de software relacionado debido a una actualización incompleta. Interacción con otros procesos que no se comportan como se esperaba. Hay muchas razones por las que los errores aparecen en el campo, y muchos de ellos podrían ser afectados por una prueba de unidad (para una definición dada de unidad)
Jon Chesterfield
77
@ JonChesterfield: crear una función de autocomprobación en su programa probablemente sea algo bueno. Y si esa función de autocomprobación puede reutilizar parcialmente el código de las pruebas de su unidad, ¿por qué no? Pero tal característica, así como las partes reutilizables, deben desarrollarse con el punto de vista "es código de producción".
Doc Brown
2
@ JonChesterfield Me cuesta imaginarme que una prueba unitaria falla en la mayoría de esas causas. Sin embargo, las pruebas de integración son otro asunto: puedo ver el mérito de enviarlas si se puede hacer sin demasiadas cosas adicionales.
Loren Pechtel el

Respuestas:

19

A veces, el código de prueba contiene fragmentos de código de terceros, tanto externos como internos de su empresa. Esto sucede cuando los usuarios presentan errores; sus pruebas (como las pruebas de regresión) luego incorporan el código suministrado por ellas para reproducirse. A menudo, la licencia de dichos fragmentos de código para reproducir errores no está clara. Por lo tanto, debe tener en cuenta los problemas de propiedad intelectual. No desea enviar código de prueba que revele accidentalmente algunos secretos comerciales o propiedad intelectual de un departamento diferente de su empresa, o de sus socios externos tampoco.

En otra nota, el código de prueba rara vez se ajusta a los estándares del código de producción: las revisiones de código no necesariamente se realizan; los estándares de codificación no se aplican, etc. Esto es desafortunado, pero común, y no necesariamente debe reflejar mal en el equipo de prueba si no tenían ese objetivo en el momento en que se desarrollaron estas pruebas.

Por otro lado, muchas pruebas son simplemente vergonzosamente malas, y ni siquiera prueban lo que algunos piensan que se está probando. Ese es un tema diferente ...

En última instancia, debido a todos estos factores, es posible que desee clasificar sus pruebas como aquellas que pueden enviarse como código abierto y aquellas que simplemente no pueden. (Es posible que desee escribir algunas pruebas personalizadas con el envío en mente, migrando lentamente las otras a ese conjunto).

Erik Eidt
fuente
El problema de terceros es un muy buen punto. Agrupar el código de prueba en "externamente visible" y "quizás confidencial" sería propenso a errores y una sobrecarga considerable. Eso es prácticamente un factor decisivo por sí solo, gracias.
Jon Chesterfield
Sí, difícil de hacer después del hecho. Creo que tendrías más suerte con un esfuerzo dedicado para desarrollar pruebas de envío.
Erik Eidt
@ErikEidt: Me tomé la libertad de hacer una sugerencia para eliminar "como código abierto", porque eso probablemente no es lo que el OP tenía en mente: creo que quiere enviar las pruebas como código cerrado.
Doc Brown
@DocBrown, entiendo tu punto. Probablemente sea una cuestión de interpretación, ya que el OP mencionó "código abierto" en algún lugar de la publicación. En cualquier caso, su edición generaliza muy bien el punto.
Erik Eidt
18

Pruebas de envío? Si. Pruebas de la unidad de envío? No.

Como dice en el comentario, el problema que puede enfrentar al ejecutar el producto en una computadora cliente incluirá problemas como la vinculación con el dll incorrecto, generalmente esto no es algo que una prueba unitaria detectará (que sin duda habrá burlado el dll para probar el código).

Ahora, enviando un paquete de prueba de integración, que llama a la UI que llama a la lógica que llama al dll ... eso funcionará mucho mejor. Las pruebas de integración pueden mostrar otros aspectos de las instalaciones fallidas que las pruebas unitarias no mostrarían. (por ejemplo, mi producto actual requiere una instalación de códecs k-lite, que no podemos agrupar debido a la licencia. Las pruebas unitarias pueden mostrar que nuestro código funciona bien, pero aún no funciona para la satisfacción de los clientes. Del mismo modo, nuestra configuración de los códecs puede no haber funcionado correctamente, las pruebas unitarias tampoco lo mostrarían).

Por lo tanto, envíe algunas de sus pruebas de integración, que serían exactamente lo que desea para un producto instalado e integrado.

gbjbaanb
fuente
2

Podría entender esta preocupación con fuerza en las áreas en las que está cubriendo cada pulgada del hardware, como un motor de juegos AAA multiproceso de próxima generación que utiliza cada núcleo de CPU, SIMD intrínseco, GPU, GPGPU, etc. mientras ofrece una plataforma cruzada producto.

En esos casos, su peor pesadilla a menudo serán aquellos en los que sus pruebas (unidad e integración) pasarán por las primeras 5.000 máquinas / plataformas dispares probadas, pero fallarán en la 5.001 debido a un error de controlador para un modelo de GPU oscuro. sobre esto me da escalofríos; no es posible probarlos ni preverlos con anticipación.

Especialmente si escribe sombreadores de GPU, puede terminar jugando una lotería inversa donde la mitad del código que escriba invocará un comportamiento indefinido, ya que hay pocas garantías estándar portátiles aplicadas por todos los modelos / controladores de GPU involucrados. Si bien se está volviendo cada vez menos como jugar al buscaminas en estos días, esto debería darles a las personas una idea: http://theorangeduck.com/page/writing-portable-opengl . Probar esto a fines de los 90 y principios de los 2000 fue realmente horrible, y fue un buscaminas todo el tiempo.

Para este tipo de casos, a menudo necesita equipos de más de 10,000 probadores con una gama muy amplia de hardware y sistemas operativos para solidificar realmente el producto y sentirse seguro de ello antes de un lanzamiento estable. No todas las empresas pueden permitirse el lujo de tener una base de pruebas tan amplia, y no todas tienen la disciplina para hacerlo bien (todas las cuestiones ampliamente notables deben solucionarse antes de tener tantos evaluadores en alguna etapa interna pre-alfa / alfa o de lo contrario la avalancha de informes redundantes puede llevar a los desarrolladores a un pánico de parche y oración).

Lo que recomiendo en este caso es lo que otros sugirieron, enfóquese en un conjunto distribuido de pruebas de integración. Puede agruparlo con el instalador, lo que requiere que los usuarios pasen una verificación de diagnóstico básica con atención cuidadosa para proporcionar detalles sobre por qué falló la instalación que pueden pasarles a ustedes, los desarrolladores.

Otra cosa (si puede convencer al jefe) es tener una amplia gama de hardware disponible para realizar una integración contigua. A mayor variedad en combinaciones de hardware / SO, mejor. Desea incluso una variedad de hardware basura que modele los requisitos mínimos de hardware mínimos para sus servidores CI: nunca se sabe.

Pero hay una cosa más que sugeriría:

Inicio sesión

Si está lidiando con algo como el escenario que describí anteriormente, entonces a menudo no puede probar estas cosas que tienden a ser las más problemáticas (esas peores trampas posibles que aparecen en el peor momento posible y no pueden aparecer incluso en el conjunto de pruebas más exhaustivo ya que es un problema limitado a un combo de hardware / sistema operativo muy específico).

Sin embargo, la mayoría de esos tipos de problemas, como las incompatibilidades oscuras del hardware o los fallos directos del controlador o la vinculación contra el dylib incorrecto (nunca he enfrentado esta preocupación) no lo llevarán lejos de iniciar el software. Por lo general, se estrellará y arderá muy pronto, hablando groseramente.

Recomiendo, por el bien de la cordura, abrazar lo inevitable. No puede hacer nada sobre estas cosas que no puede probar exhaustivamente. No intentes evitar el huracán (imposible), pero cierra esas ventanas.

Por lo general, aquí, lo mejor que podemos hacer es descubrir el problema lo antes posible, donde se produce lo más detallado posible (para reducir nuestra lista de sospechosos), y solucionar el problema lo antes posible después de que se informe.

En este caso, el registro puede ser un salvavidas. Para este tipo de campos, puede crear estos registros técnicos de spam que nadie leería nunca. A menudo relevante es solo la última línea registrada en el registro antes de que el usuario se enfrentara a un bloqueo debido a una falla del controlador, por ejemplo, puede escribir un proceso externo o enganchar que supervisa los bloqueos y luego muestra la última línea del registro que los usuarios pueden copiar y pegarle, por ejemplo, además de un volcado por caída.

Dado que esto a menudo necesita información granular y muchas de las áreas más susceptibles en el código a estos problemas de hardware / plataforma / controlador son críticos para el rendimiento, existe este problema incómodo en el que el registro puede estar ocurriendo a una frecuencia tan frecuente que en realidad se ralentizará abajo el software

Un truco útil en este caso es confiar en el supuesto de que algo ejecutado una vez se ejecutará con éxito la segunda, tercera vez, etc. Esta no es la suposición más sólida, pero a menudo es "lo suficientemente buena" (e infinitamente mejor que nada) . Con eso, puede usar un poco de estado externo para realizar un seguimiento de cuándo ya se ha registrado algo y omitir los intentos posteriores de registro para aquellos casos realmente granulares en los que el código se invocará repetidamente en un bucle.

De todos modos, espero que esto ayude. Me he encontrado con este tipo de tentación en el pasado y tengo un poco de paranoia en torno a la codificación de GPU (GPGPU y sombreadores) como resultado de algunas experiencias pasadas entre mí y mi equipo (a veces solo ver a otros miembros del equipo lidiar con esto realmente tarde y después del lanzamiento me dieron escalofríos, como algunos problemas técnicos de ATI en un modelo específico de Radeon que se bloqueaba al generar líneas antialias, que luego se informaron y se marcaron como un problema conocido con solo una solución alternativa disponible).

El registro fue lo que nos salvó el trasero allí, permitiéndonos ver a menudo el problema en esa máquina prototipo oscura 10,001 con una GPU incorporada de la que nunca habíamos oído hablar, con la última línea de código que inmediatamente nos permitió detectar exactamente dónde estaba la falla a 2 o 3 líneas de código como sospechosas, por ejemplo, si está dentro de un sombreador elaborado, somos una especie de SOL ya que no podemos iniciar sesión dentro de un sombreador GPU, pero al menos podemos usar el registro para ver qué sombreador tuvo el problema de inmediato para comenzar la investigación.

marstato
fuente
2
El código de registro de memorización es inteligente. Actualmente no producimos registros, en gran parte debido a problemas de rendimiento, por lo que la depuración implica un volcado del núcleo. Incorporar pruebas de diagnóstico con el instalador también es una buena idea. Gracias por la respuesta detallada.
Jon Chesterfield