Mis Practicas Profesionales - Acerca de las Pruebas

 Recientemente, mis prácticas profesionales han sido puestas a análisis por mis pares y siento que deberia ofrecer un contexto y los criterios que me han guiado hasta aquí. Voy a comenzar tratando las pruebas. Aquí va:

Creo que la evolución actúa como una fuerza natural sobre todo lo que hacemos. De ahí que mi práctica profesional ha evolucionado con el tiempo. Lo que voy a describir puede que deje de hacerlo o que lo adapte en un futuro.

En mi experiencia pasada los productos se han desarrollado o modificado para alcanzar objetivos económicos: ya sea la realización de una ganancia o la eliminación de un gasto. Este para mí es el vector de selección natural de mis prácticas profesionales. Es el lente a través del cual me analizo en retrospectiva continuamente.

Hablemos en términos simples. Hablemos de implementar una nueva funcionalidad en un producto existente. Esta nueva funcionalidad responde a una necesidad del cliente objetivo del producto. Para mí esto requiere que antes de entregar esta nueva funcionalidad, sea probada para de esta forma verificar que el producto exhibe esta nueva funcionalidad.

¿Por qué digo que es necesario probar la nueva funcionalidad? Pues porque de no hacerse se puede incurrir en un costo de producción en forma de varios gastos de inversión para una misma funcionalidad (hacer el trabajo más de una vez, pues la primera salió mal). O se puede incurrir en perdidas por una necesidad no realizada del cliente.

¿Que tan lejos es necesario llegar en el proceso de prueba de esta nueva funcionalidad? La respuesta depende de las condiciones alrededor de la nueva funcionalidad: Que tan fácil es probar que se ha implementado correctamente. Que tan riesgoso (o caro) sería que quedara mal implementada, etc. En lo personal mi práctica actual se inclina por defecto a probar el mínimo indispensable (de acuerdo al contexto) para garantizar que la nueva funcionalidad está ahí. ¿Por qué el mínimo indispensable? La razón es meramente de eficiencia económica.

Aquí no me estoy refiriendo específicamente a probar usando métodos automatizados o manual. Tampoco de qué nivel de granularidad tiene la prueba (unidad, subsistema, extremo a extremo). De eso hablaré más adelante. Solo que es necesario probar la nueva funcionalidad.

 Probar la nueva funcionalidad tiene otra función económica: sirve como señal para el desarrollador de cuando detenerse en el proceso de desarrollo de la nueva funcionalidad. De esta forma también minimiza el costo de producción. En general, esto convierte el probar, la nueva funcionalidad en algo prácticamente requerido (el costo de algo que nunca se termina de desarrollar siempre es superior al costo de probar esa funcionalidad).

En adición a probar la nueva funcionalidad, en mi experiencia, antes de entregar el producto, es necesario probar que no se han perdido ninguna de las funcionalidades preexistentes. Las razones son las mismas de por qué se prueba la nueva funcionalidad en primer lugar: económicas. Esto es algo que muchos dejan de lado. Me ha pasado: he agregado una nueva funcionalidad y he dañado otra en el mismo proceso.

Resumiendo hasta aquí mi experiencia actual: el proceso de desarrollo de nuevas funcionalidades requiere se acompañe de la realización de un número de pruebas cada vez mayor (n+1) con el objetivo que todas las funcionalidades del producto (incluida la nueva) están ahí.

Ahora que he dejado claro lo que pienso respecto a lo anterior, tratemos el tema de automatización vs. manual. En mi experiencia personal el costo total de pruebas manuales siempre ha sido mayor respecto al costo de las pruebas automatizadas. En materia de publicaciones científicas, de lo que he visto la data coincide en esto, pero aquí solo estoy exponiendo mi experiencia personal. Esto no es necesariamente intuitivo a primera vista.  Pues generalmente el costo de desarrollar el test automatizado en mano de obra es mayor que el costo de realizar la prueba de forma manual una vez. Pero en el largo plazo el costo computacional de repetirlo muchas veces de forma automatizada es menor que repetirlo la misma cantidad de veces de forma manual.

Respecto a esto, último les dejo una anécdota. En un producto en el que trabaje primero se implementaban todas las nuevas funcionalidades en un periodo de 15 días y luego todo el equipo se dedicaba a hacer las pruebas de foma manual. Las pruebas eran documentadas en un documento para poder repetirlas lo más precisamente posible. En este caso, probar el producto llevaba más tiempo que desarrollar las nuevas funcionalidades, al punto que llegamos a una situación en que realizar todas las pruebas llevaba más de 15 días en sí mismo.

Otro dato curioso respecto a esto mismo: En mi experiencia personal lo que me toma mínimo 1- 2 minutos para probar manual, un test automatizado se desarrolla en 3 - 4 veces ese tiempo y se ejecuta en menos de 1 segundo. Aquí estamos hablando de un test. Después de ejecutar el test automatizado más de 5 veces, el costo de desarrollo se ha compensado. Seguramente 5 es un número irrisorio para la cantidad de veces que ejecuta el mismo test a lo largo del proceso de desarrollo del producto. Con esto en mente piense cuantas veces necesita ejecutar el mismo test a lo largo del desarrollo de un producto para que el que su desarrollo demore 30 minutos sea económicamente factible. Multiplique esto por mil y empiece a darle a la calculadora de costos. En esto, mi conclusión es que en la mayoría de los proyectos un test que demore 30 minutos en desarrollar para ejecutarse automáticamente es económicamente factible y deseable cuando se le compara a un test realizado de forma manual.

Existe otro factor en contra de las pruebas manuales en mi experiencia: nosotros los seres humanos somos inherentemente malos en realizar de forma perfecta una tarea aburrida y repetitiva. Por eso a lo largo de la historia hemos delegado este trabajo a máquinas en forma general. Con el beneficio añadido de que las máquinas lo hacen siempre más barato.

Respecto a la granularidad (unidad, integración, extremo a extremo, etc), este es uno de esos temas que he visto en mi práctica profesional, que siempre existe una curva. En esa curva, los ejes son costo de realización de las pruebas y granularidad. A mayor granularidad menor costo. La granularidad de la prueba tiene otro factor económico asociado: en adición al costo de producción/realización de la prueba, existe el costo de modificar el producto. Una mayor granularidad incide en un mayor costo de modificación del producto (es más posible que sea necesario modificar las pruebas en sí mismas como parte de la modificación del producto). O sea que tanta granularidad es algo a balancear.

En términos prácticos, en este sentido me inclino por hacer la mayor cantidad posible de pruebas de una granularidad de pruebas de unidad (alta granularidad). Pero la definición de que considero una unidad se inclina hacia lo más grande posible. Por ejemplo, en el contexto de programación orientada a objetos, la unidad para mí idealmente es la clase o un conjunto de clases. En el contexto particular de OOP tratar de probar los métodos independientes de la clase tiene la desventaja agregada de que es necesario romper el encapsulamiento para probar los métodos que se desean ocultar del consumidor del objeto.

Hasta aquí quería hablar de las pruebas. Las implicaciones son profundas en otros aspectos de desarrollo de software. Por mencionar una: la perspectiva de un bug como una funcionalidad que se consideró de bajo riesgo el no probarla al momento del desarrollo. Otra: la importancia de no probar el comportamiento de presentación de un componente visual. Otra mas: el momento adecuado para definir la prueba a realizar considerando que el test es el mecanismo para determinar cuando detener el proceso de desarrollo.

Comments

Popular posts from this blog

Mi aproximación al diseño de APIs RESTful

Revision de Código