¡Se acabo el ‘copy-paste’!

Clone Detective for Visual Studio Screenshot El antipatrón ‘programación de corta y pega’ es un mal que aparece a menudo en muchos proyectos. Si bien es cierto que Ibon Landa logró hacer de ello un arte en nuestros tiempos en Panda Software, no todo el mundo tiene su capacidad. Los problemas que se derivan de este antipatrón son muy numerosos, sobre todo relacionados con la mantenibilidad del código. Básicamente se trata de una violación en toda regla un principio básico en el desarrollo de software, el principio DRY (Don’t repeat yourself). Las duplicidades en el código a menudo llevan a inconsistencias y son un indicador claro de que el código no se está refactorizando adecuadamente.


Si bien es cierto que todo desarrollador experimentado sabe que a la larga el copy-paste es dañino, también es cierto que es algo que todos hemos hecho en alguna ocasión y que muchos desarrolladores poco experimentados a menudo abusan del copy-paste. El problema viene de que cuando este abuso se detecta el mal ya esta hecho. Basta un desarrollador poco displicinado o poco experimentado que caiga en este error para que el proyecto sufra los problemas derivados del mismo. Having duplicates can easily lead to inconsistencies and often is an indicator for poorly factored code.


Conscientes de este problema ha nacido Clone Detective for Visual Studio, un addin perfectamente integrado en Visual Studio cuyo cometido es detectar donde se están introduciendos duplicidades en el código, bien por copy-paste o bien por errores de diseño que obligan a introducir código muy similar. De momento solo funciona para C#.


Yo de momento no lo he utilizado en ningún proyecto grande, pues estoy de vacaciones, pero puedo decir que si que lo he instalado y tiene bastante buena pinta. Si queréis ver como funciona antes de instalarlo visitad la sección de videos de la web del proyecto en Codeplex.

Tercera encuesta de VersionOne sobre el estado del desarrollo ágil

3rd Annual Survey: The state of Agile Development

Por tercer año consecutivo los chicos de VersionOne ponen a nuestra disposición su encuesta anual sobre el estado del desarrollo ágil. Esta encuenta cada vez más popular da un idea muy interesante de cómo y por qué las empresas y los equipos de desarrolloestán adoptando metodologías ágiles. Yo es sido uno de los 2319 participantes en la encuesta.


Los datos que más me han llamado la atención y las conclusiones que he sacado son:



  • La gran mayoria de los profesionales y los equipos de desarrollo lleván entre dos y cinco años practicando metodologías ágiles. Solo un 11% de los equipos llevan más de cinco años. Sin duda las metodologías ágiles son algo nuevo, pero ya no tan nuevo, se ha pasado el punto en el que solo hay ‘early adopters’ y ya se trata de algo maduro, conocido y establecido.

  • En contra de lo que dicen muchos, parece que las metodologías ágiles escalan bien y son de aplicación en empresas y proyectos grandes. Un 32% de las empresas tienen más de 250 empleados. Cierto que este dato puede estar sesgado porque son las empresas más grandes las que más suelen interesarse por una metodología.

  • A pesar del incapié que solemos hacer los ‘agilistas’ en que todos los miembros del equipo estén en la misma ubicación, casi la mitad de los encuestados están usando metodologías ágiles con equipos distribuidos. Creo que las nuevas tecnologías que permiten que la experiencia de usuario de una reunión virtual sea cercana a la de una presencial y la mejora de las comunicaciones es la clave.
  • Muchas empresas, un 21% y un 20% respectivamente, están usando o planean usar metodologías ágiles en los proyectos externalizados. Parece que se ven las metodologías ágiles como una buen opción a la hora de gestionar el outsourcing. Tengamos en cuenta que el 43% no hacen outsourcing, dato muy en línea con la aversión que tenemos los ‘agilistas’ a esta práctica.
  • Acelerar el tiempo de desarrollo, gestionar mejor las prioridades cambiantes y incrementar la proridad son los tres razones principales por las que se plantea el uso de metodologías ágiles. La encuesta muestra también que en una enorme mayoría de las ocasiones estos objetivos se cumplen (alrededor del 75% de las ocasiones). Sin embargo el beneficio sobre le proceso de desarrollo más habitual (83%) es mejorar la visibilidad del proyecto, aspecto directamente relacionado con tener un proceso sano de desarrollo.
  • La mayor preocupación sobre la adopción es la ausencia de planificación a medio largo plazo. Esta labor es generalmente realizada por analístas de negocio o product owner, en mi experiencia el rol menos entendido y explotado en las metodologías ágiles. Dato muy en línea con el hecho de que quien impulsa la implantación de las metodologías ágiles en la mayoría de los casos son roles del departamente de desarrollo, no de la parte de negocio, que es la que tiene la información sobre las necesidades a medio y largo plazo.
  • El cambio de cultura (45%), la resistencia al cambio (44%) y la experiencia del personal (42%) son las principales barreras en la adopción de metodologías ágiles. Son los mismos factores que cuando no hablamos de metodologías ágiles.
  • Dentro del espectro de las metodologías solo Scrum (49%) y XP+Scrum (23%)tiene penetración significativa. La siguiente es XP (con un triste 8%), es curioso como XP ha perdido terreno pese a ser la primera que se popularizo.
  • La planificación explicita de iteraciones el la práctica más usada (86%) con un fuerte crecimiento frente a la encuesta anterior. Sin duda es una práctica de extremado valor. El testeo unitario, las reuniones diarias, las builds diarias y las automatizadas son las prácticas más usadas. Es curioso que todos las prácticas evaluadas han mejorado su adopción. Parece claro que todas las prácticas modernas de ingenieria del software aportan valor suficiente como para que los equipos estén impulsando su adopción de manera clara.
  • No son muchos lo proyectos ágiles que los encuestados declaran como fallidos. El principal motivo de fallo es la incapacidad de asumir los valores de las metodologías ágiles (23%) y la falta de experiencia (21%), son los problemas que típicamente se atajan con formación. Curioso porque el coste de contar con un mentor o Scrum Master experto es mucho menor que el coste de que un proyecto falle y se me antoja un antidoto eficaz.
  • El 89% de los equipos aseguran haber mejorado su productividad, el 25% dicen que esa mejora es mayor del 25%. El 83% han acortado los tiempos de desarrollo y el 84% han mejorado la calidad de sus productos. Estos datos muestran una fuerte correlación, esta claro que sin acelerar el proyecto y sin mejorar la calidad obtenida, cuando hablamos de software, es muy dificil obtener más productividad.  Sin embargo ‘solo’ el 65% dicen haber mejorado el coste del proyecto.
  • Todos los aspectos de desarrollo del software evaluados en la encuesta han mejorado en almenos el 70% de los encuestados. Esta claro que la adopción de metodologías ágiles mejora de manera enorme un motón de apectos de la ingeniería del software. Rara vez se presentan aspectos que hayan empeorado. Adoptar una metodología ágil es una apuesta clara a la hora de mejorar el proceso de desarrollo.
  • Las herramientas más usadas no cambian mucho respecto a la encuesta anterior.

Sin duda esta encuesta muestra mucha información interesante sobre la adopción de las metodologías ágiles. ¿Alguien conoce alguna encuesta similar sobre metodologías en general, no solo centrada en las ágiles?.

Cobertura de código más allá de las pruebas unitarias

Tendemos a asociar la cobertura de código de manera casi exclusiva a las pruebas unitarias. Sin duda, es muy relevante la cobertura de nuestras pruebas a la hora de poder estimar en que medida nos protegen de regresiones y errores. Además cuando escribimos pruebas, la cobertura nos proporciona información de suma relevancia a la hora de saber que porciones de nuestro código carecen en absoluto de pruebas y, en consecuencia, ilumina aquellos lugares donde debemos centrar nuestro esfuerzos. Una cobertura alta no garantiza unas pruebas unitarias excelentes, pero si es cierto, que sin la más alta cobertura posible, nuestras pruebas unitarias nunca serán excelentes.

Sin perjuicio de lo anterior es cierto que existen otros escenarios, menos conocidos, en los que observar la cobertura del código nos puede ayudar de manera significativa.

Debemos tener en cuenta que la cobertura de código nos proporciona información sobre el código de nuestra aplicación que se ha ejecutado, lo que muchas veces obviamos es que esa ejecución no tienen por qué estar provocada por la ejecución de pruebas unitarias.

Dicho esto, un primer escenario en el que me he encontrado interés en conocer la cobertura, es cuando se ejecutan pruebas manuales. En las pruebas manuales un tester o una herramienta de automatización de pruebas interactúa con el sistema en busca de errores o con el interés de certificar su ausencia. Generalmente nos se suele recoger la cobertura de este tipo de pruebas si bien es cierto que puede proporciona información valiosa: ¿Qué partes de código se utilizan en cada escenario? ¿Qué partes del código no son ejercitadas por las pruebas? ¿Qué partes del código son ejecutadas por más de una prueba? ¿Cubrimos mediante pruebas manuales aquellas partes del código no probadas por las pruebas unitarias?… Seguro que se os ocurren algunas cuestiones más, según cual sea vuestro escenario.

Otro escenario en el que la información sobre la cobertura es útil es cuando estamos depurando un error. ¿Cuántas veces no os habéis enfrentado a un error y a pesar de poderle reproducir habéis tenido problemas para saber en que parte del código se producía?.

En ambos escenarios y seguro que en algún otro, conocer que código se ha ejecutado nos puede ser de gran utilidad. Pero ¿cómo recoger información de cobertura de un código que no se ha ejecutado desde las pruebas unitarias ni, probablemente, desde dentro de Visual Studio?

Las herramientas de línea de comandos de Visual Studio pueden ayudarnos. En concreto, tenemos que usar vsinstr en primera instancia, que nos permite instrumentalizar un ensamblado para poder recuperar la información de cobertura del código asociado al ensamblado. Luego usamos vsperfmon (también se puede utilizar vsperfcmd) para recopilar esa información. Para poder analizar la información recopilada de manera coherente es necesario contar con los pdb asociados al ensamblado.

Supongamos que tenemos un ensamblado llamado MyAssembly.exe.

La siguiente instrucción instrumenta el ensamblado (el ensamblado original será renombrado):

vsinstr /coverage MyAssembly.exe

Luego con la siguiente instrucción comenzaremos la monitorización de la cobertura. Bastará ejecutar aquellos escenarios de nuestra aplicación sobre los que queremos recoger información de cobertura:

vsperfmon /coverage /output:cobertura.coverage

La información sobre la cobertura quedará recogida en el archivo cobertura.coverage, que podremos estudiar con Visual Studio de manera gráfica, con el código cubierto y no coloreado (si es que se encuentra disponible), tal y como acostumbramos cuando vemos la cobertura de nuestras pruebas.

Señalar que tanto vsinstr como vsperfmon se encuentran en el directorio Team ToolsPerformance Tools del directorio de instalación de Visual Studio.

¡Espero que esta técnica os resulte útil!

Invocar delegados anónimos asíncronamente (o como usar el pool de hilos en dos líneas de código)

Una de las características mas interesantes de los delegados es que pueden ser invocados de manera asíncrona. La pega de los delegados es que hay que declararlos, y hacer una función para asignarla al delegado y luego ya podremos hacer la invocación asíncrona. Las ventajas de la invocación asíncrona respecto a crear un hilo explicitamente son varias: menor cantidad de código y sobre todo, que el hilo será un hilo de pool de hilos de .Net, con las ventajas para el rendimiento que esto lleva asociadas.


Muchas veces usamos delegados asícronos para dotar de asincronía a un método síncrono, pero el problema es que tenemos que crear toda la artilleria de un delegado. Una pega aparejada es que a las complejidades propias de la programación asíncrona, uniremos la menor legibilidad (los delegados son muy útiles pero no son precisamente legibles).


La solución pasa por usar un delegado anónimo de manera que podemos poner en línea el código que se ejecutará en otro hilo. El truco del almendruco es simplemente asignar el delegado anónimo a un tipo de delegado ThreadStart. Además esta técnica nos permite saber de manera muy sencilla, usando un delegado AsyncCallback y poniedolo en el primer parámetro de la llamada a BeginInvoke, cuando el hilo levantado ha teerminado su trabajo. Podemos usar el segundo parámetro del método BeginInvoke del delegado de tipo ThreadStart para pasar estado al delegado que se ejdutará cuando el hilo termine. Si no necesitamos ninguna de estas características podríamos pasar a null ambos argumentos.


Sin duda, una manera curiosa y útil en ocasiones de usar el pool de hilos.


Creo que con el siguiente código el asunto quedará claro:




using System;


using System.Threading;


 


namespace SimpleThreadStart


{


  class Program


  {


    static void Main(string[] args)


    {


      ThreadStart ts =


        delegate


        {


          Console.WriteLine(«Los delegados anónimos son mágicos»);


        };


 


      ts.BeginInvoke(ThreadCompleted, «ESTAD0»);


 


      //Dar tiempo a que el hilo haga su trabajo…


      Console.WriteLine(«Pulse una tecla para terminar…»);


      Console.ReadKey();


    }


 


    //Esta función se ejecuta cuando el hilo termina su trabajo.


    static private void ThreadCompleted(IAsyncResult ar)


    {


      Console.WriteLine(«Se completo el hilo creado mediante un delegado asincrono»);


      Console.WriteLine(«El estado pasado fue {0}», (string)ar.AsyncState);


    }


  }


}


Espero que os resulte útil o al menos curioso.