¿Necesitamos iniciar sesión cuando hacemos TDD?

41

Al hacer el ciclo Rojo, Verde y Refactor, siempre debemos escribir el código mínimo para pasar la prueba. Esta es la forma en que me han enseñado sobre TDD y la forma en que casi todos los libros describen el proceso.

¿Pero qué pasa con la tala?

Honestamente, rara vez he usado el inicio de sesión en una aplicación a menos que haya algo realmente complicado que esté sucediendo, sin embargo, he visto numerosas publicaciones que hablan sobre la importancia de un registro adecuado.
Entonces, aparte de registrar una excepción, no podría justificar la importancia real de iniciar sesión en una aplicación probada adecuada (pruebas de unidad / integración / aceptación).

Entonces mis preguntas son:

  1. ¿Necesitamos iniciar sesión si estamos haciendo TDD? ¿No revelará una prueba que falla qué está mal con la aplicación?
  2. ¿Deberíamos agregar una prueba para el proceso de registro en cada método en cada clase?
  3. Si algunos niveles de registro están deshabilitados en el entorno de producción, por ejemplo, ¿eso no introducirá una dependencia entre las pruebas y el entorno?
  4. La gente habla sobre cómo los registros facilitan la depuración, pero una de las principales ventajas de TDD es que siempre sé lo que está mal debido a una prueba fallida.

¿Hay algo que me estoy perdiendo por ahí?

Songo
fuente
55
Creo que el registro es el caso especial de muchas reglas. Una clase / función debe hacer una cosa y solo una cosa ... excepto para el registro. Las funciones deben ser preferiblemente puras, excepto para el registro. Y así sucesivamente. El registro rompe las reglas.
Phoshi
1
¿El registro no es ortogonal a ninguna metodología de desarrollo de software utilizada? Entonces, tal vez debería limitarlo y preguntar: ¿Necesitamos casos de prueba para iniciar sesión cuando hacemos TDD?
hyde

Respuestas:

50

1) ¿Necesitamos iniciar sesión si estamos haciendo TDD? ¿No revelará una prueba que falla qué está mal con la aplicación?

Eso supone que tiene todas las pruebas posibles que su aplicación necesita, lo cual rara vez es cierto. Los registros lo ayudan a localizar errores para los que aún no escribió pruebas.

2) ¿Deberíamos agregar una prueba para el proceso de registro en cada método en cada clase?

Si se prueba el registrador en sí, no será necesario volver a probarlo en cada clase, de forma similar a otras dependencias.

3) Si algunos niveles de registro están deshabilitados en el entorno de producción, por ejemplo, ¿eso no introducirá una dependencia entre las pruebas y el entorno?

Los humanos (y los agregadores de registros) dependen de los registros, las pruebas no deberían depender de ellos. Por lo general, hay varios niveles de registro, y algunos se usan en producción, y algunos niveles adicionales se usan en desarrollo, de forma similar a:

"El nivel de registro de Rails es información en modo de producción y depuración en desarrollo y prueba" - http://guides.rubyonrails.org/debugging_rails_applications.html

Otras aplicaciones utilizan un enfoque similar.

4) La gente habla sobre cómo los registros facilitan la depuración, pero una de las principales ventajas de TDD es que siempre sé lo que está mal debido a una prueba fallida.

Los errores de producción habrán pasado todas las pruebas, por lo que es posible que necesite alguna otra referencia para investigar esos problemas.

FMJaguar
fuente
26
Incluso el TDD perfecto ejecutado rigurosamente no evitará problemas de producción con el rendimiento, la interacción del sistema, la interacción de terceros. Los problemas de concurrencia también son muy difíciles de cubrir completamente mediante una prueba. Una cobertura de prueba del 100% "solo" significa que se ha ejecutado el 100% de su código, lo que no es correcto en todos los estados o entornos.
Holstebroe
34

El registro es útil para explicar el comportamiento no excepcional de una aplicación:

Los registros de eventos registran los eventos que tienen lugar en la ejecución de un sistema para proporcionar una pista de auditoría que se puede utilizar para comprender la actividad del sistema y diagnosticar problemas. Son esenciales para comprender las actividades de los sistemas complejos, particularmente en el caso de aplicaciones con poca interacción del usuario (como las aplicaciones de servidor ) ...

No importa cómo se haya probado la aplicación y no importa qué tan bien se registren las excepciones, sus usuarios pueden preguntar,

la salida de su programa es 0 mientras esperábamos que fuera 1, ¿por qué es eso?

Necesita iniciar sesión para verificar qué era la configuración de la aplicación, los parámetros y otros detalles de tiempo de ejecución para explicar su comportamiento (no excepcional).

Desde la perspectiva anterior, el registro está más orientado al soporte que al desarrollo. Después de que la aplicación se active, es deseable dejar que otra persona maneje las preguntas de los usuarios, para permitir que los programadores se centren en un mayor desarrollo.

El registro de lo que hace la aplicación permite que otra persona entienda el comportamiento del programa sin profundizar en el código y sin distraer a los desarrolladores con solicitudes para explicar qué está sucediendo.

mosquito
fuente
55
+1 para "el registro está más orientado al soporte". Realmente golpeó el clavo en la cabeza.
Tibos
1
+1 para "comportamiento no excepcional" y también para "el registro está más orientado al soporte". Pero, ¿podría editar su respuesta para enumerar la fuente del párrafo que cita?
logc
La fuente @logc de la cita se refiere por el enlace en la primera palabra aquí, "Registro": si hace clic en él, lo llevará al artículo de Wikipedia: en.wikipedia.org/wiki/Logfile
gnat
16

La mayoría de las respuestas aquí se centran en el aspecto de la corrección. Pero el registro también tiene un propósito diferente: el registro puede ser una forma de recopilar datos relevantes de rendimiento. Entonces, incluso cuando el sistema funciona sin errores, un registro puede decir por qué es lento. Incluso con una cobertura de prueba completa de todos los aspectos, un conjunto de pruebas no lo dirá.

Por supuesto, un sistema crítico de rendimiento puede / debe proporcionar métricas clave de rendimiento a algunos paneles operativos, pero el registro "clásico" puede proporcionar un nivel de detalle diferente.

johannes
fuente
2
Tampoco se olvide de iniciar sesión con fines de seguimiento de auditoría. O facturación. O varios tipos de estadísticas. O registro de eventos para emparejar con otros tipos de estadísticas de otros sistemas.
PlasmaHH
¿No es el perfil algo que harías sin iniciar sesión? ¿O simplemente quiere decir que puede registrar continuamente los resultados del perfil?
Bergi
@ Bergi: depende completamente de cómo funcione su aplicación. Si es, por ejemplo, una aplicación web, registrar el tiempo de servicio de cada solicitud y luego tratar de agrupar esos eventos para "malos ejecutantes" también podría funcionar.
PlasmaHH
La creación de perfiles de @Bergi ocurre en el desarrollo, pero hay efectos en los sistemas en vivo que se deben tener en cuenta, el uso de discos puede volverse lento, la CPU puede estar más cargada, los servicios pueden no responder a tiempo, los hilos paralelos pueden tener problemas de bloqueo ...
johannes
La auditoría de @PlasmaHH es parte de los requisitos básicos y debe ser cubierta por pruebas. En la mayoría de los casos, no lo ejecuto sobre rutas de registro "normales". El registro normal puede fallar, la auditoría no. "varias estadísticas" reuní bajo rendimiento;)
johannes
8
  1. A menos que tenga una cobertura de prueba del 100%, que generalmente no es el caso, no puede saber que su software nunca se bloqueará (EDITAR: y, como se dice en los comentarios, incluso si lo hace, algo independiente de su software podría causar un choque); es lo mismo que pensar que puedes hacer un software que no tiene absolutamente ningún error (ni siquiera la NASA puede hacer esto). Por lo menos, debe registrar posibles fallas en caso de que su programa se bloquee para que pueda saber por qué.

  2. El registro debe realizarlo una biblioteca externa o un marco interno, según la tecnología que esté utilizando. Lo que quiero decir con eso es que debería ser algo que ya se haya probado antes y que no es necesario que te hagas la prueba. Es excesivo probar que cada método registra las cosas que se supone que debe hacer.

  3. Los registros no están destinados a pruebas, no debería haber dependencia alguna. Dicho esto, no necesita deshabilitar el registro para las pruebas si le parece una limitación, aunque los registros deben mantenerse en un archivo correspondiente al entorno (debe tener un archivo diferente para el entorno de prueba, desarrollo y producción). por lo menos).

  4. Un error puede ser muy poco claro y no siempre es obvio qué salió mal cuando falló una prueba TDD. Los registros deberían ser más precisos. Por ejemplo, si está haciendo un algoritmo de clasificación y falla todo el caso de prueba, debe tener registros para cada prueba del algoritmo que lo ayuden a detectar dónde se encuentra realmente el problema.

Pierre Arlaud
fuente
44
Incluso si tiene una cobertura del 100%, ¿la tiene para cada cosa posible que pueda suceder? ¿Qué pasa si la conexión de red a su base de datos se cae? ¿Tus pruebas te dirán eso?
Zachary K
Nunca puede saber que su software nunca se bloqueará INCLUSO si tiene una cobertura del 100%. La cobertura del 100%, aunque deseable, brinda mucha menos información sobre la corrección de lo que parece.
Andres F.
Sí, tienes razón sobre eso también. El punto es que no tener posibilidad de choque no es factible. Lo editaré
Pierre Arlaud
1
La edición sigue siendo incorrecta. Incluso si tiene una cobertura de prueba del 100%, puede haber un error en su código (no es necesario culpar a las causas externas). Las pruebas NO implican que su código funcione; lo único que implican con certeza es que no pudo escribir una prueba que encuentra un error :) La cobertura de la prueba es una métrica importante, pero no está directamente relacionada con la ausencia de errores.
Andres F.
44
Es trivial demostrar que "¡100% de cobertura de prueba que pasa! = Libre de errores". Contraejemplo: add(x, y) = 2(siempre devuelve 2). La siguiente prueba se supera y ofrece una cobertura completa: assert(2 == add(1,1)). 100% de cobertura de prueba para una función con errores :)
Andres F.
8

La respuesta corta a su pregunta principal es: como regla general, los errores en su código NO serán expuestos por TDD. Algunos podrían, idealmente muchos, pero la ausencia de pruebas fallidas no implica la ausencia de errores. Esta es una máxima muy importante en las pruebas de software.

Dado que no puede saber si tendrá un comportamiento incorrecto en su sistema, tal vez en condiciones excepcionales, el registro es una herramienta útil que podría ayudar a comprender qué está mal cuando las cosas inevitablemente salen mal.

El registro y TDD abordan diferentes preocupaciones.

Andres F.
fuente
5

Sí, en el caso general, necesita iniciar sesión.

El registro no se trata de depuración. Bueno, está bien, una parte del registro a veces se trata de depuración, y puede omitir esa parte si no la necesita durante el desarrollo.

Pero la parte más importante del registro es la mantenibilidad. El registro bien diseñado puede responder las siguientes preguntas:

  • ¿La aplicación sigue viva y coleando? (Al registrar un latido cada 1000 segundos).
  • ¿Cambió el rendimiento de la aplicación en los últimos 10 meses? (Al registrar estadísticas del rendimiento de los casos de uso).
  • ¿Cambió la carga de la aplicación en los últimos 10 meses? (Al registrar el número de solicitudes por tipo de solicitud).
  • ¿Alguna de nuestras interfaces cambió sus características de rendimiento?
  • ¿La nueva versión causa una característica de uso diferente hacia algunos de los subsistemas?
  • ¿Estamos bajo un ataque DoS ?
  • ¿Qué tipo de errores están sucediendo?

Todo esto se puede lograr mediante el inicio de sesión. Y sí, debe planificarse, diseñarse y probarse, preferiblemente de forma automática.

El registro es una característica que merece tratamiento, al igual que otras características.

Jens Schauder
fuente
4

TL; DR: el registro y TDD son ortogonales. Tener uno no tiene relación con la necesidad del otro

¿Necesitamos iniciar sesión si estamos haciendo TDD? ¿No revelará una prueba que falla qué está mal con la aplicación?

En general, la mayoría de los registros que he implementado y que he visto implementados han sido para la resolución de problemas operativos, no para la depuración del desarrollo (aunque puede ayudar). La audiencia principal para este registro son los administradores y las operaciones que ejecutan sus servidores, apoyan a las personas que tienen registros enviados para su análisis, y los clientes que desean ver los registros e intentar averiguar qué está sucediendo.

Estos registros están ahí para ayudar a solucionar problemas que afectan en gran medida a los puntos de integración. Esto puede incluir servicios de red (base de datos, jabones, etc.), recursos locales (disco, memoria, etc.), datos incorrectos (entrada del cliente, fuentes de datos defectuosas / corruptas, etc.), etc. Capturando excepciones, registrando fallas e incluso realizando registros informativos. (configuraciones, configuraciones, etc.) pueden ayudar con la resolución de problemas.

¿Deberíamos agregar una prueba para el proceso de registro en cada método en cada clase?

Agregue pruebas donde sea necesario para probar el registro. Si tiene llamadas ad hoc para cerrar la información, entonces deben probarse. Aunque si implementa el registro y las pruebas de registro utilizando la Programación Orientada a Aspectos o la meta programación, eso puede reducir la carga de las pruebas.

Si algunos niveles de registro están deshabilitados en el entorno de producción, por ejemplo, ¿eso no introducirá una dependencia entre las pruebas y el entorno?

Si está escribiendo su código utilizando IoC y utiliza simulacros, debería poder probar de manera efectiva todos sus registros sin depender de una configuración ambiental particular.

dietbuddha
fuente
3

TDD generalmente ayuda a reducir errores de codificación. Ayuda mucho menos con errores con la especificación o simplemente malentendidos sobre cómo funcionan las cosas.

"¿Oh? ¿Puedes recibir un mensaje de datos antes de obtener la confirmación de que el inicio de sesión se realizó correctamente? ¡Nunca lo supe, bueno, eso no lo manejará!" ... Ese tipo de cosas. El registro es muy útil para decirle lo que el software intentó hacer para que pueda detectar lo que hizo mal.

JohnB
fuente
2

En mi experiencia, se agrega un gran nivel de registro a la aplicación cuando no hacemos TDD. Luego, el nivel de incertidumbre se vuelve alto, por lo tanto, agregamos registros para ver qué está pasando.

Mientras que cuando hago TDD (o tal vez prueba cuando sea) me encuentro agregando muchas menos declaraciones de registro. Esto a su vez significa menos LOC y puede (no siempre) afectar el rendimiento.

Pero en la mayoría de los casos, agregamos registros de entrada y salida para funciones de forma semiautomática en mi empresa, independientemente del método de desarrollo. Como sé, esto se consideró obligatorio para el análisis de problemas de producción.

Los ejemplos podrían ser métodos de un bean de servicio EJB que están presentes en la interfaz pública. Otro podría ser un caso cuando una función realiza cálculos complejos. Puede ser de gran ayuda tener cifras que ingresen al método (por ejemplo, puede escribir una prueba unitaria para volver al tema general en cuestión).

dbalakirev
fuente
¿podría ampliar las razones por las que agrega registros de entrada y salida para las funciones? ¿Por qué se requiere esto en su empresa?
mosquito
si, absolutamente. Espero que sea mejor ahora.
dbalakirev