Implementando pruebas unitarias en una compañía que no lo hace

19

El jefe de desarrollo de software de mi empresa acaba de "renunciar" (es decir, despedido) y ahora estamos buscando mejorar las prácticas de desarrollo en nuestra empresa. Queremos implementar pruebas unitarias en todo el software creado de aquí en adelante.

Los comentarios de los desarrolladores son los siguientes:

  • Sabemos que las pruebas son valiosas
  • Pero, siempre está cambiando las especificaciones, por lo que sería una pérdida de tiempo
  • Y, sus plazos son tan ajustados que de todos modos no tenemos suficiente tiempo para realizar la prueba

Los comentarios del CEO son los siguientes:

  • Me gustaría que nuestra empresa tuviera pruebas automatizadas, pero no sé cómo hacer que suceda
  • No tenemos tiempo para escribir documentos de grandes especificaciones.

¿Cómo obtienen los desarrolladores las especificaciones ahora? De boca en boca o diapositiva de PowerPoint. Obviamente, ese es un gran problema. Mi sugerencia es esta:

  • También demos a los desarrolladores un conjunto de datos de prueba y pruebas unitarias
  • Esa es la especificación. Depende de la gerencia ser claro y cuantitativo sobre lo que quiere.
  • Los desarrolladores pueden ponerlo como cualquier otra funcionalidad que consideren necesaria y no necesita ser cubierta por pruebas

Bueno, si alguna vez has estado en una empresa que estaba en esta situación, ¿cómo resolviste el problema? ¿Este enfoque parece razonable?

Pete SupportMonica
fuente
1
Me parece una causa perdida. Las pruebas unitarias demuestran que se ajusta a la especificación, pero cambia constantemente según los desarrolladores (por lo que no es realmente una especificación, sino más bien una lista de deseos) y su CEO no tiene ni idea.
James
@James: las empresas necesitan un cambio, por lo que tanto como cualquier ingeniería de software se trata de gestionar ese cambio. Para mí, lo que dijo el CEO es perfectamente razonable.
Mark Booth
@ MarkBooth Hay cambios y hay un estado constante de flujo. Vuelve a leer la pregunta. Esta compañía lo está inventando a medida que avanza.
James
@ James Estás haciendo un juicio de valor sin ninguna base real para hacerlo. El hecho de que los desarrolladores se quejen no significa que la empresa lo esté inventando a medida que avanza . Algunos de nosotros no trabajamos en agradables entornos programados y fáciles de especificar. Tengo nuevos usuarios cada semana, todos los cuales quieren hacer algo ligeramente diferente a los usuarios anteriores. A menudo descubren, a mitad de su tiempo asignado, que el software no hace lo que necesita. Puede que no me guste que me llamen un sábado para implementar algo que nunca supieron que necesitaban, pero eso a menudo es parte de trabajar en un lugar ágil.
Mark Booth

Respuestas:

17

Parece que está mezclando dos tipos diferentes de pruebas: pruebas unitarias y pruebas de sistema / aceptación . Los primeros operan en un nivel inferior, probando pequeñas piezas de código (generalmente métodos individuales), que generalmente residen en el interior del programa, no directamente visibles para los usuarios. Este último prueba todo el programa como lo ven sus usuarios, en un nivel de granularidad mucho más alto. Por lo tanto, solo este último puede basarse en cualquier forma de especificación del sistema.

La separación de los dos problemas hace que sea más fácil comenzar a avanzar hacia un proceso de desarrollo mejorado. Comience a escribir pruebas unitarias lo antes posible , independientemente de cómo se especifique (no) el software a alto nivel. Cada vez que un desarrollador crea o cambia un método, hace algo concreto, que puede (y debe) probarse de forma unitaria. En mi experiencia, incluso los requisitos cambiantes de alto nivel no suelen afectar drásticamente estos bloques de código de nivel inferior: el código en su mayoría necesita ser reorganizado, en lugar de desecharse o reescribirse por completo. En consecuencia, la mayoría de las pruebas unitarias existentes seguirán funcionando bien.

Una condición importante para habilitar las pruebas unitarias es: los plazos no deben ser decididos por la administración por adelantado, sino que deben basarse en las estimaciones de trabajo de los desarrolladores (quienes a su vez deben incluir en su estimación el tiempo necesario para escribir las pruebas unitarias adecuadas). O, si la fecha límite es fija, el alcance de la entrega debe ser negociable. Ninguna cantidad de (mala) gestión puede cambiar la verdad fundamental de que un número determinado de desarrolladores solo puede entregar una cierta cantidad de trabajo de calidad en un período de tiempo determinado.

Paralelo a esto, comience a discutir la mejor manera de aclarar y documentar los requisitos y convertirlos en pruebas de aceptación de alto nivel. Este es un proceso más largo de refinamiento sucesivo, que fácilmente puede llevar años llegar a un estado mejor y estable en toda una organización. Una cosa parece bastante segura a partir de su descripción: tratar de arreglar los requisitos constantemente cambiantes escribiendo documentos de especificaciones grandes por adelantado simplemente no va a funcionar . En cambio, se recomienda avanzar hacia un enfoque más ágil, con frecuentes lanzamientos de software y demostraciones a los usuarios, y muchas discusiones sobre lo que realmente quieren. El usuario tiene derecho a cambiar de opinión sobre los requisitos en cualquier momento; sin embargo, cada cambio tiene su costo (en tiempo y dinero). Los desarrolladores pueden estimar el costo de cada solicitud de cambio, lo que a su vez permite al usuario / propietario del producto tomar decisiones informadas. "Seguramente, este cambio de características sería bueno ... pero si retrasa el lanzamiento de esta otra característica crucial, y cuesta tanto, vamos a ponerlo en la cartera por ahora".

Lograr que los usuarios definan casos de prueba de aceptación y creen datos de prueba es una excelente manera de involucrarlos más y generar confianza mutua entre usuarios y desarrolladores. Esto obliga a ambas partes a centrarse en criterios de aceptación concretos, medibles y comprobables, y a considerar los casos de uso con mucho más detalle de lo habitual. Como resultado, los usuarios pueden verificar el estado actual del desarrollo de primera mano con cada lanzamiento, y los desarrolladores obtienen comentarios de medición más concretos y tangibles sobre el estado del proyecto. Sin embargo, tenga en cuenta que esto requiere un mayor compromiso de los usuarios y nuevas formas de operación, que pueden ser difíciles de aceptar y aprender.

Péter Török
fuente
1
¿Y la razón del voto negativo es ...?
Péter Török
1
+1 para "avanzar hacia un enfoque más ágil", me recuerda a "Caminar sobre el agua y desarrollar software a partir de una especificación son fáciles si ambos están congelados". - Edward V Berard
Mark Booth
@ Peter Torok Gracias ... ¿tiene algún enlace a información relevante sobre las pruebas de aceptación?
Pete SupportMonica
@Pete, es difícil ser más específico sin saber más acerca de sus proyectos, tipos de aplicaciones, etc. Sin embargo, la búsqueda rápida en Google muestra algunos enlaces prometedores.
Péter Török
8

Mi experiencia al hacer la transición.

Durante muchos años tuve la idea errónea de que no tenía tiempo suficiente para escribir pruebas unitarias para mi código. Cuando escribí las pruebas, estaban hinchadas, cosas pesadas que solo me animaron a pensar que solo debería escribir pruebas unitarias cuando sabía que eran necesarias.

Recientemente me animaron a usar Test Driven Development y descubrí que es una revelación completa. Ahora estoy firmemente convencido de que no tengo tiempo para no escribir pruebas unitarias .

En mi experiencia, al desarrollar teniendo en cuenta las pruebas, termina con interfaces más limpias, clases y módulos más enfocados y, en general , un código más SÓLIDO y comprobable.

Cada vez que trabajo con código heredado que no tiene pruebas unitarias y tengo que probar algo manualmente, sigo pensando "esto sería mucho más rápido si este código ya tuviera pruebas unitarias". Cada vez que tengo que probar y agregar funcionalidad de prueba unitaria al código con alto acoplamiento, sigo pensando "esto sería mucho más fácil si se hubiera escrito de forma desacoplada".

Comparando y contrastando las dos estaciones experimentales que apoyo. Uno ha existido por un tiempo y tiene una gran cantidad de código heredado, mientras que el otro es relativamente nuevo.

Cuando se agrega funcionalidad al antiguo laboratorio, a menudo se trata de ir al laboratorio y pasar muchas horas trabajando sobre las implicaciones de la funcionalidad que necesitan y cómo puedo agregar esa funcionalidad sin afectar ninguna de las otras funciones. El código simplemente no está configurado para permitir pruebas fuera de línea, por lo que casi todo tiene que ser desarrollado en línea. Si intentara desarrollar fuera de línea, terminaría con más objetos simulados de lo que sería razonable.

En el laboratorio más nuevo, generalmente puedo agregar funcionalidad desarrollándola fuera de línea en mi escritorio, burlándome solo de las cosas que se requieren de inmediato y luego solo pasando un corto tiempo en el laboratorio, solucionando los problemas restantes que no se solucionaron -línea.

Mi consejo

Parece que ha comenzado bien, cada vez que vaya a hacer grandes cambios en su flujo de trabajo de desarrollo, debe asegurarse de que todos participen en la toma de esa decisión, y lo ideal es que la mayoría de la gente lo haya aceptado. Según su pregunta, parece que lo ha entendido bien. Si la gente no tiene entusiasmo por la idea, está condenada al fracaso o a generar mala voluntad.

A menos que pueda presentar un caso comercial convincente, no recomendaría una implementación completa de pruebas unitarias y especificaciones para todo su sistema. Como mencioné anteriormente, si un sistema no está diseñado teniendo en cuenta las pruebas, puede ser muy difícil escribir pruebas automatizadas para él.

En cambio, recomendaría comenzar de a poco y usar la Regla de Boy Scout :

Siempre deje el campamento más limpio de lo que lo encontró.

Si mientras implementa algo en esta base de código, puede identificar las pruebas específicas requeridas para probar el comportamiento existente y la transición del comportamiento antiguo al nuevo, entonces ha documentado el cambio en las especificaciones y ha comenzado a implementar pruebas de unidades para tu sistema.

Los módulos que no toca no reciben pruebas unitarias, pero si no los toca, probablemente se deba a que ya se probaron exhaustivamente y no necesitan cambios, o nunca se usan.

Lo que desea evitar es desperdiciar una gran cantidad de esfuerzo del desarrollador escribiendo pruebas que nunca serán necesarias ( YAGNI funciona tan bien para el código de prueba como para el código de producción * 8 '), nunca volverá a usarse y desmoralizará a las personas pensando que las pruebas son inútiles después de todo.

Resumen

Comience de a poco, cree confianza en las pruebas de forma incremental y gane valor comercial al desarrollar pruebas cuando y donde beneficien más a su equipo.

Mark Booth
fuente
2

Lo primero que debe hacer es concentrarse no en las pruebas, sino en lograr el proceso general correcto. ¡No tiene sentido probar nada si no comprende completamente lo que se supone que debe hacer!

Entonces ... las especificaciones primero, y las especificaciones documentadas que no cambian (bueno, no inmediatamente). Debes buscar hacerlos. Recomiendo un sitio web donde los usuarios puedan subir las especificaciones o escribirlas directamente. También puede vincular eso a un rastreador de errores y una guía sobre el progreso del proyecto.

Lo más probable es que eso sea todo lo que realmente necesita. Puede agregar pruebas unitarias a eso internamente y la administración nunca necesita saber que los desarrolladores están haciendo pruebas unitarias. En cierto modo, así es como se supone que debe ser.

Todavía tendrá que hacer pruebas del sistema, pero eso también se puede vincular al sitio web de gestión de proyectos, una vez lanzado, el equipo de prueba (incluso si ese es otro desarrollador afortunado en rotación) puede actualizarlo con las pruebas que han usado para ver si Todo se mantiene unido.

Honestamente, no creo que esto vaya a cambiar de la noche a la mañana, si estás acostumbrado a obtener especificaciones de 'boca a boca', entonces la batalla va a cambiar casi por completo este comportamiento, y obtendrás resistencia a esto. Un usuario (o BA o PM o quien sea) que está acostumbrado a decir "solo haz que haga x" y ahora necesita escribirlo todo no responderá bien, es probable que escriba documentos de especificaciones vagas y luego los aclare con actualizaciones de boca en boca. Así que olvide las pruebas unitarias y comience con el gran problema que tiene con el ciclo de vida del desarrollo.

gbjbaanb
fuente
1

Primer problema: para "dar a los desarrolladores un conjunto de datos de prueba y pruebas unitarias", primero debe escribir esas pruebas unitarias, que es un trabajo de los desarrolladores. Las pruebas unitarias tampoco reemplazan la especificación: la especificación está destinada a tener un nivel de abstracción más alto que las pruebas unitarias.

Segundo problema: parece que desea la máxima cobertura de prueba unitaria. En este caso, sí, costará demasiado tiempo y dinero escribir tanto las pruebas como el código en un contexto donde los requisitos cambian constantemente. En su lugar, decida qué partes del código son críticas y pruebe la unidad solo con esas partes. En muchos casos, los requisitos que cambian no afectan las partes críticas del producto. Un cliente (o CEO, o lo que sea) generalmente solicita mover este panel a la derecha, o cambiar el color de este título de rojo a verde: cosas que a nadie le importan y que no requieren pruebas intensivas. Por otro lado, un cliente nunca solicitará cambiar el algoritmo hash de SHA512 a SHA256 o cambiar la forma en que almacena las sesiones, mientras que son esas partes las que requerirán más pruebas.

Arseni Mourzenko
fuente