archivo

Archivo de la etiqueta: métricas

En el anterior artículo sobre CMMI vimos el área de proceso de seguimiento y control del proyecto como consecuencia lógica del área de proceso de planificación del proyecto, ya que si se establece un plan es para realizar un seguimiento del mismo y de las variables que define, de manera que se pueda dar respuesta a posibles desviaciones lo antes posible.

Este área de proceso va más allá de ese seguimiento y control, ya que el mismo está orientado al día a día del proyecto, sino que está más dirigido a la definición de una serie de objetivos del proyecto y de la organización (en los que influye los resultados del proyecto), donde el grado de cumplimiento de los mismos se verifica a través del análisis de las métricas definidas para cada uno de ellos (una o más), para las cuales se tiene que definir la forma en que vamos a recopilar los datos y obtener los últimos.

El fin último de este área de proceso es comunicar los resultados obtenidos a través del análisis de los datos, es decir, medir para tomar decisiones que permitan mejorar.

¿Qué objetivos se pueden definir para el proyecto?

Por ejemplo, conseguir un 70% de cobertura en pruebas unitarias, mejorar la satisfacción del usuario en cada iteración del producto, entregar los hitos en fecha, conseguir que el número de vueltas a atrás tras la entrega de hitos sea menor o igual a uno en el 90% de los casos, que el número de incidencias tras el paso a producción de una versión sea inferior a un umbral determinado, cumplir con determinado tiempo de respuesta ante incidencias, mejorar progresivamente el velocity del equipo de trabajo, acertar un determinado porcentaje de las estimaciones de esfuerzo realizadas, etc…

Hay que tener en cuenta que lo mismo el proyecto se desarrolla bajo un ANS, en estos casos debe condicionar los objetivos del proyecto los cuales deberán tener en cuenta las métricas definidas y como mínimo cumplirlas.

¿Qué objetivos se pueden definir para la organización?

Por ejemplo, incrementar el número de proyectos que se presentan en plazo, mejorar la productividad, mejorar los márgenes de beneficio del proyecto, reducir el número de errores en las entregas, conseguir una satisfacción media de los clientes tras el cierre de cada contrato igual o superior a un 7, etc…

A veces no se tiene claro que objetivos plantear (sobre todo si no hay ANS), no importa, lo importante es empezar tal vez con pocos objetivos pero que sean medibles y nos puedan proporcionar información de interés para el proyecto y para la organización. Siempre habrá tiempo, cuando ya se vaya implantando esta cultura, de incrementar los mismos.

Equivocar nos equivocamos todos y supone una oportunidad para adquirir conocimientos.

Para aprender de los errores tenemos que darnos cuenta de que hemos fallado (no siempre es fácil, entre otras cosas porque generalmente prescindimos de la autocrítica) y realizar un análisis de los motivos. Sin razonar las causas, probablemente estemos abriendo las puertas para volver a equivocarnos en lo mismo y así sucesivamente hasta que no sea amortizable tanto error (los errores y fracasos nos abren la puerta del éxito, pero no podemos estar equivocándonos indefinidamente).

En el desarrollo de software se puede fallar en muchos de sus aspectos pero tal vez uno de los puntos críticos sean las desviaciones tanto en tiempo como en coste (generalmente las primeras llevan a las segundas).

Cuanto antes se detecte una desviación, se analice y se le intente dar una solución, menor será su impacto en el proyecto. Si se detecta pero no se hace nada, pensando que el problema se va a arreglar solo o no se le da importancia, estaríamos ante el mismo caso que no detectarla. Por regla general las desviaciones tenderán a empeorar si no se hace nada para corregirlas (a veces no es así, pero solo en contadas ocasiones).

Ya que muchos proyectos van a sufrir desviaciones, ¿cómo podemos sacarle partido? Pues analizando las causas que han llevado al proyecto a esa situación y llevando un registro de las mismas.

Es importante desglosar las características del proyecto: presupuesto, tiempo de ejecución, hitos, tecnología, nuevo desarrollo o mantenimiento, complejidad, tamaño, sistemas con los que interopera, tipo de cliente, nombre del cliente, equipo de trabajo que ha participado, acciones que se han llevado a cabo para corregir las posibles desviaciones, qué desviaciones se han producido al final y así hasta el nivel de detalle que se quiera.

Con ese registro tan simple (y que sería interesante hacerlo en todos los proyectos, incluso en los que han ido bien) y una vez que se tenga un histórico lo suficientemente elaborado, podremos evaluar a priori el nivel de riesgo de un proyecto en función de una serie de variables, así como poder consultar qué resultado han dado determinadas decisiones en el mismo.

Es lo que siempre digo, hay que tomar métricas, hay que medir, es algo necesario. Está muy bien tener experiencia, intuición y/o capacidad de análisis, pero será mucho mejor cuando haya valores objetivos que respalden a esas cualidades.

Y lo peor de todo es que la mayoría de las empresas de desarrollo de software trabajan sin ellas, solo con algunas (y regular) o no les hacen caso. Este mal no solo afecta a proveedores, también afecta y mucho a los clientes.

Para medir se necesitan métricas, todo lo demás es subjetivo. No hablo de erradicar la subjetividad, pero es necesario que lo objetivo predomine. Lo objetivo siempre va a ser más justo y todas aquellas decisiones que se basen en eso tendrán más posibilidades de tener éxito y de ser mejor aceptadas.

Si tu empresa desarrolla software, se necesita un inventario de todas las peticiones de tareas y reporte de incidencias que desde clientes se realicen a la misma, asociándolas con su correspondiente contrato (si no hay contrato, pues con su correspondiente código de proyecto), planificarlas y hacer un seguimiento hasta que se cierran (habrá algunas, como es lógico que nunca lleguen, por algún motivo, a terminarse). Llegará el día, donde tengas que tirar de esto y si no lo tienes te acordarás, porque estarás a merced de la otra parte.

También es necesario llevar un inventario de las tareas internas que dan lugar a la realización de esas peticiones de tareas e incidencias (es posible que algunas sean de un tamaño lo suficientemente grande o tengan unas características concretas que requieran la participación de más personas), de esta forma tendremos no solo qué tareas se realizan y cuándo (lo que permite conocer además en cuáles se han producido desviaciones o incumplimientos), sino quiénes han participado en ellas. Todo esto además debe estar unido a un sistema donde se registre el tiempo que se imputa a cada tarea.

También serán necesarias tareas relacionadas con la medición de la calidad del software que se desarrolla y a ser posible identificando quiénes aportan codificación con calidad y quiénes no.

A nivel de negocio también se requieren métricas, es decir, qué ofertas se han realizado, a qué concursos se han presentado y cuál ha sido el porcentaje de éxito. A los responsables de cuenta, dado que también realizan tareas comerciales, no hay que pedirles responsabilidades exclusivamente por la rentabilidad de los proyectos, sino también por su capacidad de generar negocio.

De nada sirve tener una maquinaria que te permita obtener un juego rico y preciso de métricas si después no se analizan y no se utilizan como instrumento para la toma de decisiones, ¿por qué pasa esto muchas veces? pues porque las métricas duelen y dan mensajes que muchos no quieren escuchar. No siempre podemos guiarnos por instintos, ya que no siempre vamos a acertar de esa manera.

Si tenemos la posibilidad de tener un sistema de métricas, donde cada una de ellas se vayan consolidando poco a poco y vemos el impacto de las decisiones que se toman en base a ellas, probablemente los resultados que se obtengan con las mismas, mejoren sensiblemente a los que se obtenían antes de su utilización. Además, no solo es cuestión de que se utilicen para esto, ya que en muchos casos será necesario, como se ha comentado anteriormente, para tener una mejor organización en el día a día de trabajo y para conseguir una mejor operativa de funcionamiento.

Si los proyectos no varían de proveedor de servicios de desarrollo de software o de responsable del proyecto, la importancia de las métricas y de la documentación pueden pasar a un segundo plano, ya que de una u otra forma el sistema de información seguirá adelante. Es cierto que las métricas y la documentación pueden resultar también de gran utilidad en estos casos, sobre todo si se quiere ver cómo evoluciona la calidad de la herramienta y las incidencias que están teniendo los usuarios en el uso cotidiano de la aplicación.

En cualquier caso el problema está en que generalmente nos solemos acordar de la documentación y de conocer métricas cuando las necesitamos y precisamente por eso, cuando tenemos que echar mano de ellas no las tenemos.

Como es lógico, esa no son las únicas circunstancias que aconsejan que se documenten los proyectos y se obtengan métricas, ya que por encima de eso está la persistencia del conocimiento de la aplicación lo que permite que la adaptación a cambios en la gestión y en los proveedores resulte menos traumática. También permitirá tener un punto de referencia para evaluar la evolución del producto en las nuevas condiciones de explotación o mantenimiento.

Por ejemplo, si se fueran a externalizar en bloque el mantenimiento de una serie de aplicaciones de una organización probablemente lo primero que querrían conocer los posibles proveedores de ese servicio sería información general de las aplicaciones: tecnologías, arquitecturas, fecha de puesta en producción, etc… y métricas: número de incidencias de relacionadas con correctivos, frecuencia de mantenimientos evolutivos, volumen, calidad y formato de la documentación, etc… Si eso se adobara con informes Sonar que indiquen la evolución del análisis estático de código de las mismas, les permitiría todavía más ser más precisos en la estimación del esfuerzo que se requeriría para realizar el servicio en función del número de aplicaciones a mantener, las características del servicio y del acuerdo de nivel de servicio. Además de todo lo anterior, les sería interesante conocer las reglas de desarrollo y de calidad del software de la organización, el ecosistema de desarrollo, las características del entorno de producción, preproducción y desarrollo: sistemas físicos, software de base y servidores de aplicaciones, la estructura organizativa del departamento de informática, el proceso de paso a producción, etc…

La complejidad ciclomática es una métrica a tener en cuenta para evaluar la mantenibilidad, comprensión, testeabilidad y probabilidad de errores de una determinada aplicación.

Este término fue propuesto por Thomas J. McCabe en 1976 y tiene como una de sus características principales su independencia respecto a los lenguajes de programación (por lo menos, de los más convencionales), por lo que teóricamente podrían ser comparables aplicaciones realizadas con tecnologías distintas en base a su complejidad ciclomática. Digo teóricamente, porque además de la algorítmica las características propias del lenguaje de programación pueden influir en que sean más sencillas o no su inteligibilidad, mantenibilidad, etc… No obstante y en cualquier caso, resulta una aproximación muy a tener en cuenta de esos factores.

¿Qué mide la complejidad ciclomática? Pues el número de posibles caminos lógicos que tiene una aplicación. ¿Quiénes crean esos posibles caminos lógicos? Los métodos, las sentencias selectivas (if, case), sentencias iterativas (while, for), lanzamiento y tratamiento de excepciones (throw, catch), devolución de resultados de un método cuando no es lá última línea del mismo (return), operadores lógicos en guardas, etc…

Cuanto más caminos lógicos tenga una aplicación, una clase o un método más complejo resulta y por tanto, requiere un mayor esfuerzo desde el punto de vista de las pruebas unitarias (el número de pruebas unitarias para recorrer todo el código crece linealmente con la complejidad ciclomática (además de cumplirse eso, se verifica que: 1) la complejidad ciclomática es menor o igual que el número de casos de pruebas que se requiere para hacer cobertura de todo el código de la aplicación (téngase en cuenta que los else no suman complejidad ciclomática), 2) la complejidad ciclomática es mayor o igual que el número de casos de prueba que se requieren para verificar que realmente se “abren” los distintos caminos físicos)).

Por tanto, una baja cobertura de una aplicación viene a decir que existe una gran cantidad de código que no se ha verificado (utilizando esta estrategia), que se recorra, por lo que probablemente si no se ha recurrido a pruebas intensivas de la aplicación, muy probablemente se traduzca en errores evitables que se detectan posteriormente, incluso en producción).

También se requiere un mayor esfuerzo para la mantenibilidad y comprensión del código (¿cuántas veces nos hemos perdido en un mar de sentencias if anidadas?) y por todo lo anterior se incrementan las posibilidades de que existan errores, porque ¿cuántas veces nos hemos encontrado con que un problema en un método era provocado porque no se metía por la guarda correspondiente de una condicional o porque no entraba en un determinado bucle?, por lo que simplemente la mera experiencia nos indica que debe existir una relación entre la complejidad ciclomática y el número de errores de una aplicación.

Como la complejidad ciclomática es el resultado de los diferentes caminos lógicos que puede tener una aplicación es lógico que esta crezca conforme más extensa (en líneas de código) es una aplicación y por regla general una aplicación con muchas funcionalidades, grande, etc…, es más compleja, requiere mayor codificación y tendrá como consecuencia una mayor complejidad ciclomática (de esta manera existirá prácticamente una relación entre una clasificación de las aplicaciones por líneas de código y una clasificación de las aplicaciones por complejidad ciclomática, es importante señalar que no tienen por qué conservar el mismo orden aunque sí más o menos estarán por el mismo entorno, es decir, la segunda aplicación con más líneas de código, puede ser la cuarta en complejidad ciclomática o la quinta aplicación con más código, la segunda en complejidad. Por tanto este tipo de complejidad es inherente a las aplicaciones y existe por el simple hecho de la existencia de las mismas y por tanto, aplicaciones con envergadura se traducen en aplicaciones complejas de mantener y eso es consecuencia de su complejidad ciclomática intrínseca.

Independientemente de que una codificación eficiente puede eliminar caminos lógicos innecesarios, existe un límite y es el que da la propia dinámica de funcionamiento de un sistema de información que provoca que se codifique su comportamiento en algoritmos que como se han comentado anteriormente pueden ser complejos. Cuando se aproxima a este límite, lo más que se puede hacer es utilizar la complejidad ciclomática para determinar si determinados métodos o clases son demasiado complejas y requerirían ser analizadas de cara a dividirlas en otras más simples, mejorando así la mantenibilidad de las mismas.

Existen algunas clasificaciones basadas en rangos de complejidad ciclomática que determinan cuando es recomendable hacer la simplificación de determinadas clases y métodos y también hay casos de éxito de la aplicación de los mismos en algunas compañías.

En muchas ocasiones a simple vista se puede determinar si un método o una clase tienen una complejidad ciclomática alta, no obstante, esta tarea puede ser agotadora si la aplicación a analizar es muy grande, por ese motivo, lo mejor es delegar esa función en analizadores estáticos de código, como es el caso de Sonar, que permite obtener métricas de la complejidad ciclomática tanto a nivel de aplicación, como de clases y de métodos y utilizando su implementación de funcionalidades de drill down ir de datos más generales a información más de detalle.

Como todas las métricas de ingeniería del software, no hay que tomarse los resultados de la complejidad ciclomática al pie de la letra, sino saber interpretar qué es lo que están diciendo y tomar medidas para reducir el impacto de dicha complejidad en la aplicación (mayor cobertura de pruebas unitarias) y para tomar decisiones de revisión de la codificación en métodos y clases complejos y su posible simplificación en otros más sencillos.