¿Qué puede hacer con respecto a la calidad de la integración existente y las pruebas unitarias mientras es el nuevo integrante de un equipo?

21

Un tema recurrente que encontré en mi carrera es ser el nuevo desarrollador en llegar a un equipo y tener rápidamente una desconfianza inherente de la unidad existente y las suites de pruebas de integración.

Durante la entrevista, la gerencia le dice que "apoyan firmemente las pruebas unitarias" y que lo alientan abiertamente. Lo hacen, pero todo lo relacionado con las pruebas en sí es simplemente incorrecto. Como el hecho de que reclaman una cobertura del 100% cuando hay una cobertura de prueba de integración del 100% pero menos del 10% de cobertura de prueba de unidad repetible. Algunos otros problemas que he encontrado:

  1. No hay una indicación clara entre qué es una prueba unitaria y qué es una prueba de integración. Las pruebas unitarias y de integración se mezclan en la misma clase.

  2. Pruebas de integración que tienen dependencias explícitas no declaradas de datos dinámicos muy específicos en la base de datos de un entorno específico.

  3. Las pruebas de integración no transaccionales, básicamente pruebas que pueden o no molestarse en limpiar después de sí mismas, a veces requieren "depuración" manual de la base de datos para que la prueba sea repetible.

  4. Sin burlarse en absoluto, y el código de la aplicación requiere una revisión importante solo para que la burla sea posible. En otras palabras, diseñe sin tener en cuenta las pruebas.

  5. No hay convenciones de nomenclatura claras para ver rápidamente el nombre de una prueba y determinar aproximadamente qué pruebas se están realizando.

Todo esto no quiere decir que TODAS las pruebas sean inútiles o malas, muchas de ellas son bastante buenas y vale la pena mantenerlas, pero a veces parece una búsqueda de oro. A propósito, evitaría ejecutar pruebas solo porque tenía miedo de arruinar la base de datos para mis casos de prueba de caja negra.

Esto esencialmente me ha dado una desconfianza inherente a las pruebas de unidad e integración que no he escrito o revisado personalmente de alguna manera. En algún nivel, si no tiene fe en la calidad de su conjunto de pruebas, realmente no aporta ningún valor al equipo o al proyecto.

¿Qué haces cuando te encuentras en esta situación? ¿Cuál crees que sería el mejor plan de ataque para abordar algo como esto?

¿Deberían refactorizarse todas las pruebas en un esfuerzo monumental que abarque todas las versiones? ¿Debería abandonar la idea de que este proyecto heredado puede tener un día de cobertura de prueba de unidad sólida?

árbol de arce
fuente
66
Bienvenido al mundo real, amigo.
tdammers
20
Sé feliz de tener pruebas.
Joel Etherton
3
¿Por qué trabaja para empresas que están claramente por debajo de su nivel de competencia?
TrojanName
3
@Brian, aprecio el golpe de ego, pero sin más personas que piensen como yo, estas compañías nunca se levantarán. Esta es la primera vez que estoy en una posición de poder real, ya que desarrollé una modesta cantidad de importancia política por una vez. Aquí tengo una oportunidad real de dirigir recursos para mejorar las cosas. Todavía no he encontrado una empresa que sea perfecta sin necesidad de trabajar. Es como el marido perfecto o la mujer, que no sólo vienen a lo largo de, una buena persona lo suficientemente viene y entonces ellos se transforman en lo que queremos que sean;)
maple_shaft
1
Creo que podríamos trabajar para el mismo equipo. Ahora usted (y yo) sabemos cómo hacer preguntas durante nuestras próximas entrevistas. (En realidad, mi entorno no tiene una cobertura de prueba de integración del 100% o incluso del 10% [¿pruebas unitarias verdaderas? ¡Eso es una locura!], Pero has aclarado todos los otros puntos con los que estoy tratando).
Anthony Pegram,

Respuestas:

6

En primer lugar, como otros carteles ya han escrito, debe estar contento de que se entiendan las pruebas de unidad / integración (no de una manera técnica, quiero decir, se entiende la razón por la que se debe hacer) y la administración la impulsa.

Antes de comenzar a hacer todo, debe exponer los problemas a la gerencia, por qué se debe hacer algo y de manera muy diplomática para que no piensen que usted cree que es el mejor programador del mundo (¡incluso si lo es! :-). Tal vez le dirán que la aplicación será reemplazada por algo completamente nuevo, y si es así, ¿por qué molestarse? Y tal vez se darán cuenta de que sería bueno y acelerarían la fase de prueba antes de cada lanzamiento. Y sea ​​diplomático con sus compañeros de equipo , puede haber millones de razones por las que es así y simplemente no hay razón para buscar un culpable.

Una mejor idea sería tratar de hablar con ellos para que puedan participar en el esfuerzo, y tendrá menos posibilidades de aparecer como un astuto, sería más "nosotros" que "yo".

Ahora, ponga prioridades en lo que quiere hacer. Priorice las tareas, siempre sabiendo que su primera prioridad siempre será su asignación de proyecto actual ... En cuanto a su problema de prueba, esto es lo que haría, en tres fases:

  1. ¿Cómo marcar la diferencia entre las pruebas unitarias y de integración? Las siguientes soluciones pueden aplicarse y no son exclusivas:

    • Refactorice el nombre de los métodos de caso de prueba (no las clases ya que el comportamiento correcto es hacer que el caso de prueba comparta el mismo nombre que la clase probada)
    • Cree dos anotaciones, una denominada "UnitTest" y la otra "IntegrationTest". Estas anotaciones se pueden usar en clases y métodos. Si una clase completa se compone de pruebas unitarias o de integración, puede marcar la clase con la anotación correcta. Si no, puede marcar cada método con la anotación correcta. Además, estas anotaciones podrían ser útiles para inyectar accesorios dinámicamente antes de iniciar las pruebas (fase 3)
  2. Para cada prueba de integración, enumere cuál es el "conjunto de datos" que se espera que esté en la base de datos al comienzo de cada prueba, y qué debe eliminarse al final de la misma (por ejemplo, la tabla X, necesita un registro con "id" establecido en "1" y "nombre" establecido en "foo", etc.). Tenga en cuenta que lo que elimine puede ser más grande / más pequeño que lo que tenía al principio, ya que el código mismo puede agregar / eliminar objetos de la capa de persistencia respectivamente. Probablemente notará rápidamente que varios de estos casos de prueba necesitan el mismo conjunto de datos o parte del mismo conjunto de datos.

  3. Las primeras dos fases se pueden hacer relativamente rápido ... en comparación con el resto. Ahora que tiene su conjunto de datos, puede usar los accesorios de conjuntos de datos para cada caso de prueba que lo necesite. Pero eso costará un poco de tiempo ... Así que podrías hacer uno, ver cuánto tiempo te costó y estimar cuánto más tiempo necesitas para hacer todo. Además, podría usar esa prueba para demostrar a sus colegas lo que hizo y por qué la vida es mucho más fácil cuando no necesita tener una base de datos en un estado específico para realizar las pruebas.

Puede observar que las fases 1, 2 y 3 pueden realizarse en una sola clase de prueba, si desea mostrar rápidamente a sus colegas / gerencia cómo se puede hacer. Esto también sería útil, como escribió Péter Török, para mostrar de inmediato el "buen camino" a sus compañeros de equipo para que dejen de producir códigos incorrectos. Sin embargo, creo que el resto de la fase 2, que identifica el conjunto de datos de prueba completo, se realiza mejor en un gran paso.

En cuanto a la API / tecnología detrás de todo eso, parece saber el tema.

Espero que haya ayudado un poco.

Nota: para mi propuesta, supongo que codifique en Java / C # donde conozco anotaciones y es posible AOP. Estoy seguro de que esto también es posible en otros idiomas, pero no escribiré sobre algo que no sé.

Jalayn
fuente
1
Gracias ... consideré usar anotaciones como etiquetas para identificar qué es una prueba de integración y qué es una prueba unitaria ... ¿Sabe si es posible configurar un servidor CI como CruiseControl para excluir ciertas pruebas basadas en anotaciones? Tal vez esa es una pregunta separada.
maple_shaft
Lo siento, no sé usar CruiseControl, así que no sé sobre eso. Busqué en la configuración del complemento Surefire de Maven solo por curiosidad y no parece posible, sin embargo, es muy posible omitir las pruebas basadas en los nombres, por supuesto.
Jalayn
14

No podrá arreglar todas las pruebas juntas. Creo que debería enfocarse en la palabra mejora versus revisión . Ni la gerencia ni los desarrolladores estarán de acuerdo en una revisión, pero si demuestras que hay una manera de mejorar las cosas sin afectar negativamente el proyecto, será más probable que escuchen.

Primero, no puede 'arreglar' o refactorizar el código existente a menos que tenga una cobertura de prueba de calidad, por lo que me centraría en arreglar su infraestructura de prueba primero.

Haga una lista de cosas que necesitan mejorar e intente priorizarlas. Creo que la capacidad de ejecutar pruebas de forma independiente y por separado (para que no se afecten entre sí) y la separación de las pruebas de unidad e integración son algunas de las primeras cosas en las que trabajar. Debe facilitarle a usted y a los demás hacer lo correcto.

En lo que respecta al código de la aplicación ... No podrá realizar la revisión completa de la arquitectura de la aplicación solo para que pueda probarse mejor la unidad. En cambio, cuando ingrese un nuevo código, intente aplicar principios que faciliten la prueba unitaria (como la inyección de dependencia). Puede pensar que esto no es un cambio lo suficientemente grande, pero es sorprendente lo rápido que los desarrolladores se dan cuenta si ven el beneficio. Solo tiene que haber alguien que comience a hacer un cambio para mejor.

Hable con su equipo y haga que compren. Una de las cosas más importantes que puede hacer es seguir la ' Regla de Boy Scout ' y hacer pequeñas mejoras para dejar una clase o examen en una mejor forma que la que encontró . Si todo el equipo aplica esta regla, las cosas mejorarán mucho más rápido.

Después de un tiempo, tendrá una gran cantidad de código que sigue buenos principios y áreas de la aplicación que están en mal estado. En este punto, tiene una línea de base de lo que es bueno y el equipo puede decidir si es beneficioso hacer un refactorizador más grande para las cosas heredadas más antiguas o si puede seguir viviendo tal como está.

c_maker
fuente
8
+1, y agregaré "comenzar por liderar con el ejemplo". Nadie aprecia al tipo que entra y dice "lo estás haciendo mal", pero si muestras mejoras, es más probable que lo sigan.
StevenV
2
+1 para la Regla de Boy Scout , es mucho más fácil de usar y vender que cualquier enfoque de revisión.
Matthieu M.
10

Debo admitir que lo tomaría como un raro regalo llegar a un proyecto en el que ya tienen un número significativo de pruebas de unidad / integración; nunca he tenido esa suerte en mi vida hasta ahora. Incluso si no todos están trabajando como deberían, ya hay un gran esfuerzo puesto en ello, e incluso si el equipo y la gerencia no siempre siguen las mejores prácticas, todavía están comprometidos con la causa, por lo que no necesita gastar su tiempo discutiendo sobre por qué vale la pena escribir las pruebas unitarias.

Sin embargo, las pruebas tal como las describe pueden mejorar. Pero debe tener cuidado con su tono cuando discuta los problemas con sus compañeros de equipo . Si comienza diciendo "todo lo relacionado con las pruebas en sí mismas es simplemente incorrecto" , puede terminar rápidamente enajenando al resto del equipo. En cambio, debería centrarse en cómo mejorar el estado actual de las cosas, lo cual, debo repetir, sigue siendo significativamente mejor que el promedio según mi experiencia hasta ahora.

OMI, su primer objetivo debe ser evitar que el equipo produzca más pruebas malas . Comience demostrando el beneficio de cada mejora específica a sus compañeros de equipo. Si ven la utilidad de una determinada técnica, ya sea cortando dependencias externas, restaurando el estado original después de cada prueba, o separando las pruebas de unidad e integración, comenzarán a aplicarlas. Esto en sí mismo mejorará lenta pero seguramente la calidad general de la base de prueba a largo plazo (si tiene 1000 casos de prueba malos ahora, y el equipo produce 1000 pruebas buenas para el próximo año, habrá reducido la proporción de pruebas malas) del 100% al 50%). Una vez que esté asegurado, puede decidir refactorizar las pruebas existentes caso por caso. Nuevamente, pequeñas mejoras se sumarán a grandes cambios con el tiempo.

Como nota al margen, por el tono de su publicación, siento que también podría estar en un lugar donde yo solía estar: no confiar en el trabajo realizado por otros, incapaz de delegar tareas a nadie por temor a que su trabajo no dependa de usted. Normas de calidad propias. En mi experiencia, este no es un buen lugar para estar, porque a la larga, puede conducir fácilmente a conflictos personales y agotamiento. No puedes hacer todo solo, debes trabajar junto con el resto del equipo. Solo pueden tener éxito juntos.

Péter Török
fuente
6

Trabajar para probar la independencia. Si la prueba X modifica la base de datos de prueba de tal manera que la prueba Y falla, entonces cambie la prueba Y. En este pequeño escenario, lo que debe enfocarse no es que X haya estropeado la base de datos, sino que Y tiene dependencias inapropiadas. Elimine esas dependencias (apagando la base de datos, reestructurando la prueba o inicializando la base de datos a un estado donde Y pasará) y ahora tiene una prueba de trabajo independiente más. Ese es el progreso (podría decirse que "arreglar" X para no estropear la base de datos no lo sería).

Sea paciente y respetuoso, lo mejor que pueda, con las personas con las que está trabajando, a pesar del desorden que han creado. Están tratando de hacer lo correcto, con toda probabilidad; tenlo en cuenta y ayúdalos a hacerlo.

Carl Manaster
fuente
2
Debería haber mencionado que ninguno de los creadores del desastre original está aquí. No tenían ganas de lidiar con la deuda técnica que crearon y continuaron.
maple_shaft
44
@maple_shaft: Es bueno que se hayan ido ... puedes mejorar las cosas sin que nadie pierda la cara.
Kevin Cline
2

Lo bueno de ser nuevo en el equipo es que tienes un enfoque "fresco" de las cosas. Lo malo puede ser que otros tengan dificultades para creerte.

No haga una larga lista de cosas por hacer. Pero elija UNA cosa que parezca urgente, y que otros tengan más probabilidades de responder, y sugiera una solución. Si funciona, genial, entonces sugiera otra solución a otro problema, en base a su primer éxito.

Pero tómelo con calma, uno por uno, y espere que sus ideas lentamente "entren" en el nuevo grupo.

Tom Au
fuente
2

establezca el ejemplo que desea ver, pero aprecie la perspectiva de otro desarrollador en una prueba: un desarrollador puede evaluar los éxitos, mientras que otro puede evaluar los fracasos, un desarrollador escribió la clase mientras que otro pudo haberla usado la primera vez al escribir la prueba.

Las pruebas existentes (erm, la mayoría) todavía tienen un propósito, aunque puede no ser inmediatamente evidente. No recomiendo revisar y refactorizar todo de una vez (es tedioso y propenso a errores). las malas pruebas finalmente necesitan ser actualizadas, reescritas, o simplemente pueden quedar obsoletas a medida que el software evoluciona.

Si su enfoque para las pruebas es superior en algunos aspectos, las personas aprenderán de ese modelo o le pedirán su ayuda. habrá un equilibrio de recursos, pero puede ampliarlo según sea necesario para respaldar sus pruebas.

en última instancia, desea aumentar la calidad de los programas mediante pruebas y mejorar la cobertura. puede hacer esto poniendo más énfasis en las pruebas y dando un buen ejemplo, pero aprecia las perspectivas de los demás.

al enfatizar la importancia, puede hacer que el entorno operativo de sus pruebas sea diferente: un ejemplo obvio es ejecutar pruebas en paralelo; Si no es reentrante, ha localizado un error en su programa o prueba (ganar / ganar). un entorno de prueba más riguroso obligará a corregir y / o reescribir las malas pruebas (con suerte, la forma correcta la segunda vez). introduzca lentamente tales cambios (no rompa la mitad de las pruebas de una vez, eso es un problema real), forzándolos a aprender lo que hace una buena prueba y, en última instancia, un buen programa. luego, cuando usted y otras personas entren y modifiquen / reparen / extiendan las pruebas, apliquen lo que han aprendido: es incremental y tienen una mejor comprensión del contexto / programa en ese momento.

justin
fuente
2

Arreglarlos con el tiempo

He estado en la misma situación. Acabo de pasar una hora todas las mañanas haciendo pruebas y reparándolas hasta que se arreglen. Era una base de código de tamaño mediano y creo que terminé en 1,5 meses. También tuve mucha más confianza en nuestras pruebas.

Personalmente, no me importa si una prueba es una prueba unitaria o una prueba de integración, siempre que sea una buena prueba. Por buena prueba quiero decir que:

  • limpia después de sí mismo
  • es repetible
  • minimiza las interacciones ambientales
  • es consistente

En el camino evangelicé una mejor construcción de prueba (es decir, molesté mucho a la gente).

dietbuddha
fuente