El primer tester es el programador

En mi noble (y seguramente ilusa) intención de construir software de calidad, últimamente he estado pensando bastante sobre el tema de las pruebas. No me refiero en este caso a los tests automáticos, ya sean unitarios, de aceptación, de aprobación, etc. Estoy pensando en las pruebas manuales. Sí, manuales a mano, de las de arrancar la aplicación y empezar a comprobar si funciona como debe.

Al final, y especialmente en aplicaciones que tienen algún tipo de interfaz de usuario, es inevitable y fundamental realizar pruebas manuales. Hay cosas que son imposibles muy difíciles de detectar con pruebas automáticas, como etiquetas mal alineadas, textos mal redactados, interacciones «extrañas»… prácticamente todo lo que afecta a la experiencia de usuario.

Además, hay que tener en cuenta que las pruebas automáticas sólo cubren aquello en lo que hemos pensado a priori, durante la creación de las pruebas (o el diseño del sistema, si estás usando TDD), pero en cualquier caso es posible (y hasta frecuente) que en ese momento estemos pasando cosas por alto.

Mi opinión es que los primeros que deben realizar estas pruebas manuales son los propios desarrolladores.

Pero, ¿para eso están los testers, no?

Pues sí y no. La realidad es que la mayoría de las veces, y más en España donde el número de pequeñas empresas es muy elevado, eso de contar con un equipo independiente de testers es pura fantasía.

Por otra parte, los testers no tienen el mismo conocimiento sobre el código de la aplicación que quien lo está creado o modificando, por lo que tienen mucho más difícil evaluar algunos riesgos estructurales como los que mencionaba al hablar de planificación y riesgos.

También hay que tener en cuenta que, cuando implementamos algo, sabemos mejor que nadie los puntos flojos de la implementación, los casos que podemos considerar límites y las partes que remotamente se podrían ver afectadas por los cambios.

Muchas veces el tester se centra en las cosas nuevas que se han implementado, en lo que aparece en el changelog de la versión, y es lógico y correcto, pero eso puede provocar que pasen desapercibidos bugs de regresión que hemos introducido en otras partes del sistema que teóricamente no se han modificado, pero cuya implementación se ha podido ver afectada por las nuevas funcionalidades.

Sí, ya sé que con un montón de test automatizados se supone que evitamos estos riesgos, pero seamos realistas y admitamos que muchas veces no es viable escribir tests automáticos para ciertas cosas (sigo pensando en el interfaz de usuario). Además los tests tampoco son infalibles (no dejan de ser código escrito por nosotros) y seguramente sea más complicado escribir buenos tests que escribir buen código.

Donald Knuth decía:

Cuidado con los errores en el código anterior; sólo he demostrado que es correcto, no lo he probado.

Él hablaba de verificación formal, pero parafraseándole:

Cuidado con los errores en el código anterior; sólo he comprobado que pasa los tests, no lo he probado.

Suele ser más productivo probar las cosas justo cuando las hemos acabado de implementar, sin dejar pasar mucho tiempo, para tener todavía frescos los cambios que hemos hecho, han pasado los tests, pero no estamos muy seguros de que vayan a funcionar realmente.

Entonces, ¿pasamos de los testers y lo hacemos todo nosotros?

Ni por asomo. Si tienes la suerte de contar con gente dedicada a probar la aplicación, aprovéchalo.

La gente que está acostumbrada a probar aplicaciones, sabe mejor que tú cómo romper una aplicación y qué cosas suelen fallar o se te suelen pasar por alto (casos típicos: teclas rápidas en los diálogos, orden de tabulación, …).

Además, hay un factor muy importante: se trata de una persona distinta de la que ha implementado la funcionalidad que está probando. Eso hace que parta sin prejuicios y explore caminos que a ti seguramente se te hayan pasado por alto: combinaciones de teclas raras, errores en la entrada de datos, distintas formas de interactuación con el sistema, etc.

La estrategia que encuentro más efectiva es combinar pruebas manuales exhaustivas durante el desarrollo realizadas por el propio equipo de desarrollo, con una fase posterior de pruebas por parte de los testers. De esta forma se consiguen detectar más errores antes de que la aplicación llegue a los usuarios y se obtiene un software de mejor calidad.

Habrá quien piense que tener al equipo de desarrollo probando aplicaciones es un mal uso de recursos porque, en general, las horas de programador son más caras que las horas de probador, pero no hay que olvidar que también los fallos detectados en producción son más caros de corregir que los detectados en desarrollo, así que seguramente emplear parte del tiempo de desarrollo en asegurarse de que las cosas funcionan, no sea tan mala idea.

9 comentarios en “El primer tester es el programador

  1. Estoy de acuerdo en que es muy importante en que el desarrollador realice pruebas y que ciertamente el disponer de testers representa una gran ventaja, pues su mente está más acostumbrada a encontrar fallos.

    Me parece que lo que está fallando o faltando en el ciclo, de implementación y pruebas que describes, es la parte de definición de especificaciones. Antes de ponerse a implementar algo, cliente (analista de negocios, usuario o el que corresponda de su lado), desarrollador y tester deberían reunirse a definir cómo los requerimientos se pueden traducir a pruebas (o mejor especificaciones) automatizadas que queden como referencia para lo que (funcionalidades) debe implementar el desarrollador, lo que debe verificar o probar el tester y aceptará el cliente.

    El tester no debería depender de cómo el desarrollador implemente las cosas en un bajo nivel, no es necesario que conozca el código siquiera, ni el desarrollador debería reinventarse las funcionalidades yendo más allá de lo acordado, de tal modo que afecte al tester. Además, la mente de este último no está solo para encontrar errores, también es muy buena para formular las pruebas (escenarios y criterios de aceptación) antes de comenzar la implementación.

    También me parece que realizar «pruebas manuales exhaustivas durante el desarrollo realizadas por el propio equipo de desarrollo» puede conllevar redundancia (entre desarrolladores y testers) en ese tipo de pruebas, por lo que más bien cada grupo puede concentrarse más bien en hacer cada uno el tipo de pruebas en que son buenos cada uno.

  2. @Jorge, muchas gracias por rehacer tu comentario después de que te lo rompiera con mi plugin antispam.

    Estoy de acuerdo en prácticamente todo lo que comentas, sólo alguna puntualización:

    La fase de especificaciones es muy importante, pero a veces se corre el riesgo de sobreespecificar algo demasiado temprano. También tengo que reconocer que estaba pensando más en desarrollos de aplicaciones estándar, donde no hay un cliente real que firme un criterio de aceptación.

    No es que el tester deba conocer la forma en que el desarrollador implemente las cosas, de hecho no lo conoce y por eso creo que son importantes las pruebas del desarrollador. El problema no viene porque el desarrollador haga cosas «que no estaban acordadas», sino porque al hacer las cosas acordadas, se pueden introducir bugs en otras áreas (por ejemplo, al refactorizar código para eliminar duplicidad).

    En cuanto a las pruebas exhaustivas, sí, tienes razón, «exhaustivas» suena muy fuerte, pero lo que quería decir es justo lo que tú dices en tu comentario. Cada uno que se centre en la pruebas en las que más puede aportar.

  3. Hay días que uno se lleva una agradable sorpresa, y la de hoy ha sido descubrir este blog. Felicidades.
    Creo que a veces sobreespecificar es poco ágil y puede hacer muy lento encaminar el sw a lo que el cliente quiere; en este sentido lecturas como ‘the lean startup’ de Eric Ries son muy instructivas.
    Para mí los ciclos cortos y test exhaustivos es lo que mejor me funciona en mis proyectos. Sin embargo discrepo en una cosa con este post: el que programa algo no lo sabe testear. Creo que todos tenemos un modelo mental que trasciende a los patrones. Cuando programamos algo estamos sujetos al modelo mental, y también testeamos siguiendo dicho modelo, y por tanto nuestros test sólo garantizan que alguien que interactúe con el programa como lo haríamos nosotros no encuentre errores. Lo que yo acostumbro a ver es que la mayoría de desarrolladores somos muy malos testers…seguramente solucionaríamos muchos más bugs si los desarrollos los testeara el vecino de enfrente, que de programar ni idea.
    Una vez más, excelente blog.

  4. Muchas gracias Ernesto.

    Estoy de acuerdo con lo que dices con respecto a la sobreespecificación, creo que suele ser una pérdida de tiempo (durante el diseño) y oportunidad de mejora (durante el desarrollo).

    En cuanto a que el progamador no sabe testear, es cierto que muchas veces nos falta «maldad» a la hora de probar la aplicación y nos ceñimos siempre al caso de uso para el que hemos diseñado, sin introducir valores erróneos o hacer cosas extrañas, pero también es verdad que sabemos qué partes «no visibles» podemos haber roto al tocar algo.

    Por eso digo que la mejor solución me parece mezclar las pruebas por parte del desarrollador para pillar ese tipo de errores y las pruebas del tester para pillar errores más «funcionales».

  5. Hola!
    Me gustó mucho este post, es muy realista de las situaciones que acontecen en los proyectos.
    Muy cierta es la necesidad de que el equipo de desarrollo también realice testing y no solo nosotros los testers, ayudandole al desarrollador a tener una mentalidad de encontrar errores al momento de desarrollar.

  6. Todo un tema, los programadores son saturados de pedidos y deben cumplir con fechas. Tambien el programador esta en una nube de codigo que no le deja ver la aplicacion desde afuera con facilidad. El tester es alguien que viene con la mente limpia y su objetivo es quebrar el sistema, ademas con el tiempo toma experiencia de cuales son nuestras deficiencias. El programador no solo vive en una nube de codigo, sino que tiene exigencias como estar aprendiendo cosas nuevas todos los dias y eso lo satura mentalmente. En mi empresa el testing es la puesta en marcha en el cliente, esto estresa demasiado ya que te obliga a ser «perfecto» en cada una de tus acciones. Ayer actualice un store, toque una linea que parecia inofensiva y lo guarde, jamas imagine que iba a fallar por tocar una palabra. Mi compañero me quiere matar literalmente. Ese es el precio de no tener alguien que se especialice en testing.

  7. Roberto Miguel Garcia Aguirre dijo:

    Yo pienso que además la gente de test debe tener conocimientos de programación. De esa manera puede efectuar mejor las pruebas y detectar de una manera más exacta que está fallando.

  8. Hay que ser bien tonto para pensar en hacer algo y no verificar que lo que se hizo quedo correctamente. El simple hecho de señalar que debemos verificar lo que hacemos denota mediocridad en la forma en la que estamos acostumbrados a hacer las cosas. Si la empresa tiene Testing, la responsabilidad de que no lleguen errores al usuario final es de Testing.

Comentarios cerrados.