¿Qué es eso de las metodologías? ( II )

Y llegado este momento, y después del post anterior dónde hablábamos de las buenas prácticas,  volvemos a la pregunta que nos hacíamos al principio.¿Qué metodología debo usar?¿Cuál es la mejor?¿Cómo puede empezar a usarla?

Pues la verdad que esta pregunta puede dar para mucho más que un post, pero intentaré dar algunas pinceladas que os puedan ayudar a empezar.

La respuesta no es una respuesta absoluta de todo o nada, es decir, no existe una metodología que claramente sea mejor que otra y que siempre debamos aplicar. Factores como el tipo de proyecto o empresa son determinantes en la elección metodológica.

Disponer de una herramienta que nos ayude en el uso de la metodología que elijamos es un factor importante, aunque no determinante. La herramienta nos puede ayudar a poder seguir los requerimientos que nos pide la metodología seleccionada de una manera más llevadera.

Como ya estaréis pensando, Team System es un producto que nos puede ayudar bastante. Tal es la importancia que cobran las metodologías en Team System, que el primer paso para crear un nuevo proyecto es elegir cómo queremos trabajar, es decir, la metodología.

clip_image003_thumb1

Uno de las grandes innovaciones y ventajas de Team System son las guías de proceso. Las guías de proceso nos dan las directrices a seguir para poder seguir una determinada metodología de desarrollo; Nos dicen que roles existen, cómo se relacionan, qué elementos de trabajo existen, cuáles son los flujos de los mismo etc..Factores claves para conocer qué tengo que hacer para poder implantar una metodología.

Otro factor importante a valorar es la contratación de alguien que ya tenga experiencia en el uso de metodologías de desarrollo y que nos pueda asesorar sobre cuál es la que más no conviene a nosotros. Nos puede ayudar a tomar la decisión y lo que suele ser más importante, a implantarla. Ayudarnos a implantar puede llegar a ser clave, ya que no suele haber segundas oportunidades en este tipo de decisiones.

Metodologías en Team System

Team System incluye dos metodologías por defecto; MSF for CMMI y MSF Agile.

MSF for Agile Software Development se define a sí mismo como un proceso ligero que se adhiere a los principios del manifiesto ágil. Elige MSF Agile para proyectos de ciclo de vida cortos y orientados a resultados, dónde el grupo de trabajo puede trabajar con documentación intermedia. MSF Agile es una guía flexible que ayuda a crear sistemas adaptativos, adelantándose al cambio, enfatizando las entregas periódicas al cliente y que fomenta las validaciones del cliente como medida del éxito.

MSF for CMMI Process Impovement está diseñado para llegar al nivel 3 CMMI. Extiede MSF Agile con planificación más formal, más documentación, más elementos de trabajo y mayor seguimiento. MSF for CMMI implementa una versión más ligera de lo que es la implementación más tradicional de CMMI.

clip_image005_thumb1

La diferencia principal está en el nivel de formalismo que exigen, el nivel de esfuerzo que hay que emplear y la profundidad de las métricas que se usan. Por ejemplo, MSF for CMMI incluye el rol del auditor dentro del proyecto, existiendo una serie de tareas e informes para ese rol. Las dos alternativas soportan procesos iterativos de desarrollo, con continuos ciclos de aprendizaje y refinamiento.

Existen otras metodologías, que aunque no viene por defecto, pueden usarse con Team System; RUP, CMMI en su implementación tradicional, Scrum o eXtreme Programing son algunas de las alternativas que ya están disponibles.

Y si aún así no fuese suficiente, Team System permite crearte tu propia metodología de trabajo, ya sea partiendo de cero o modificando algunas de las existentes. También debo decir, que aunque lo permite, no lo recomiendo.

¿Una metodología ágil o guiada por plan?

Las metodologías ágiles pueden encajar en la mayoría de los proyectos de desarrollo actuales y salvo en situaciones muy especiales, por ejemplo situaciones impuestas por el cliente, ayudaran más al éxito de nuestro proyecto que las guiadas por plan.

Aún así, tenemos que tener cuidado con la palabra ágil, ya que puede convertirse es un palabra peligrosa que se vuelva contra nosotros. Las metodologías ágiles surgieron como una alternativa a las metodologías formales estilo CMMI, las cuales se consideraban excesivamente pesadas y rígidas por su carácter normativo y su fuerte dependencia de las planificaciones detalladas previas al desarrollo.

Esto no implica que las metodologías ágiles no requieran documentación ni que no requieran planificación. Las metodologías ágiles dan otro enfoque, que se basa en los postulados del manifiesto ágil que deben ser asumidos si se quieren usar este tipo de metodologías:

· Valorar los individuos y su interacción, por encima de los procesos y las herramientas.

· El software funciona, por encima de la documentación exhaustiva.

· La colaboración con el cliente por encima de la negociación.

· La respuesta al cambio por encima del seguimiento de un plan.

Si queréis interesado en cambiar de metodología o empezar a aplicar una, mi recomendación sería utilizar Team System y MSF Agile. MSF Agile es una metodología ágil que no rompe en exceso con las formas de trabajar tradicionales y que puede hacer que la transición sea más llevadera. Otra metodología que me gusta especialmente es Scrum, pero debo reconocer que exige un cambio de mentalidad que no siempre es posible de realizar.

Conclusión

Disponer de una metodología adecuada en el proyecto es algo básico si queremos asegurar el éxito del mismo. Por tanto, la elección de la misma debe ser valorada correctamente teniendo en cuenta los diferentes condicionantes que pueda haber, como el tipo de proyecto o empresa.

Una vez que hemos puesto los cimientos del proyecto (las buenas prácticas ) Team System y MSF Agile pueden ser una alternativa válida para muchos de los proyectos que existen actualmente, aunque si queremos que esta elección sea lo más correcta posible, la mejor solución puede pasar por con contar con gente con experiencia en esta área, que pueda ayudarnos en la implantación de la herramienta y la metodología.

¿Qué es eso de las metodologías? ( I )

Una de las decisiones más importantes a la que nos enfrentamos en el inicio de todo proyecto es la elección de metodología a emplear; ¿cómo vamos a trabajar?. No es una decisión trivial, obviando muy a menudo esta pregunta, ya de de ella depende gran parte del éxito del proyecto.

Además, como veremos, elegir y aplicar una metodología implica un trabajo importante y suele implicar un cambio de mentalidad importante en las organizaciones, cosa que no siempre es fácil de conseguir.

Poniendo los cimientos: las buenas prácticas

Antes de empezar a profundizar en busca de una respuesta para esta pregunta debemos tener claro una cosa; el primer paso para aplicar una metodología es disponer de unas bases sólidas sobre la que se asiente; estas bases no son más que las buenas prácticas de desarrollo que todos deberíamos estar aplicando en nuestros proyectos.

Independientemente de la elección metodológica el uso de buenas prácticas es algo indispensable en todo proyecto de software. Conocerlas, saber cómo se usa y sobre todo aplicarlas es la base del éxito. Esta afirmación puede llegar a parecer muy obvia y lógica pero muy pocas empresas lo tienen tan claro, ya que no es nada habitual el uso de estas prácticas.

Algunas de las prácticas que deberíamos usar son:

· Disponer de una herramienta de control de fuentes. Disponer de esta herramienta es algo vital para poder realizar un buen trabajo en equipo. El gestor de fuentes hace de repositorio común para todos los miembros comunes, de manera que en todo momento el código está localizable en un único punto. Estas herramientas permite funcionalidaes de versiones, históricos o trabajo múltiples líneas de desarrollo. Adicionalmente, por ser un único punto para todo el código, en el punto ideal sobre el que hacer backups. Existen múltiples herramientas en el mercado que ofrecen esta funcionalidad, como SourceSafe, CVS, SubVersión o ClearCase.

· Disponer de una herramienta de gestión de incidencias. Tener constancia de las incidencias de mis desarrollos, saber el estado de las mismas, cuándo aparecieron, cómo se encontraron, cómo se corrieron….son puntos que deberíamos conocer en todo momento para poder conocer el estado del proyecto y poder tomar decisiones sobre él. ¿Cómo sabemos si estamos cerca de sacar una release si no tenemos una gestión de incidencias?¿Cómo podemos hacer una gestión de incidencias sin una herramienta adecuada?

· Automatizar las compilaciones de tu aplicación. En todo momento la aplicación completa debe poder compilarse sin ser un proceso traumático. Con un solo click, deberíamos poder disponer siempre de una versión de nuestra aplicación lista para poder ser desplegada.

Compilar de manera automatiza todo los días nos va a ayudar a detectar problemas de una manera rápida. ¿Quién no ha oído alguna vez la frase “Pues en mi máquina compila”? Es una frase muy habitual, que poco a poco deberíamos evitar, pero que si tiene que pasar, al menos enterarnos lo antes posible.

Pero este no es el aspecto más importante por el cuál hay que compilar de manera diaria, sino por la posible de poder realizar pruebas unitarias y pruebas de humo sobre la última versión de nuestra aplicación.

· Las pruebas unitarias y las pruebas de humo son un completo perfecto a las compilaciones diarias.

Las pruebas unitarias no es más que código que prueba otro código, pero que nos permite probar de una manera sencilla y periódica si nuestros desarrollos cumplen con lo que deberían hacer. Hacemos una vez un programa de pruebas y lo pasamos tantas veces como queramos.

Para los detractores de las pruebas unitarias diremos que escribir pruebas unitarias no es escribir el doble de código. Lógicamente, sí hay que escribir más código pero nunca el doble.

Si podemos hacer compilaciones y pruebas unitarias automáticas, nadie nos impide que las pruebas unitarias se pasen, también de manera automática, después de las compilaciones.

Del mismo modo, las pruebas de humo son una serie de pruebas funcionales que se deben pasar después compilar y desplegar nuestra aplicación para verificar el correcto funcionamiento de la misma.

Hacer este tipo de pruebas aumenta considerablemente la calidad de nuestros desarrollos y el descubrimiento temprano de errores, ya sean errores nuevos o regresiones a errores que ya se habían solucionado y ahora vuelven a fallar. ¿ Os suena la frase: “Pues esto funcionaba antes”? Con estas pruebas podremos evitar en gran medida esta frase.

· Escribir especificaciones, por pequeñas que sean es fundamental. Aunque en muchas ocasiones las personas más técnicas del grupo de desarrollo suelen ser reacias a escribir documentación ( igual hay que hacer que el Visual Studio sea también un editor de texto para que las escriban J ) es muy importante que lo hagan ya que ayuda a definir de una manera más clara qué es lo que debe hacer nuestra aplicación.

Escribir ayuda a tener que pensar y pensando se descubren situaciones que no se habían tenido en cuenta. Descubrir estas situaciones en esta fase reduce considerablemente el tiempo de desarrollo.

Para los que estéis interesado en conocer más sobre las buenas prácticas os recomiendo que echéis un vistazo al Test de Joel.

(http://www.joelonsoftware.com/articles/fog0000000043.html )

¿Cómo puedo empezar a usar buenas prácticas?

Muchos de vosotros en este momento os estaréis preguntado cómo podéis empezar a utilizar en vuestros proyectos estas buenas prácticas; ¿Qué herramientas tengo que usar?¿Cuándo me van a costar? Seguro que muy costoso usar todas estas herramientas..

Las dudas que pueden surgir pueden ser muchas, pero tenemos una herramienta de Microsoft para ayudarnos en esta labor; Team System. Este nuevo producto de Microsoft está orientado a la gestión del ciclo de vida del software y dispone de una gran variedad de herramientas y utilidades para que podamos usar en nuestros desarrollos; gestor de fuentes, gestor de incidencias, pruebas unitarias, compilaciones etc…

Independientemente de otras ventajas que ofrece Team System, seguramente más importante, destacamos la importante labor de integración que ha hecho Microsoft en este nuevo producto, ofreciendo de una manera integrada dentro de Visual Studio un gama muy amplia de herramientas necesarias para el día a día de nuestros desarrollos.

Muchas de las herramientas que incluyen ya existían antes de este producto y se podían ya utilizar pero lo importante es la integración; todas las herramientas se encuentran accesibles desde un único punto y se conocen entre ellas. Que se conozcan entre ellas es muy importante ya que podremos usaras de manera conjunta. Por ejemplo, sería sencillo poder compilar usando la última versión que esté en el gestor de fuentes y una vez compilado, pasar automáticamente nuestras pruebas unitarias.

clip_image002


Salvando los obstáculos del camino…

Llegado este momento más uno estaréis pensando que todo lo que hemos contado hasta ahora está muy bien, pero que es imposible que lo uséis en vuestras empresas. Entendéis que es necesario usar buena prácticas pero igual no está en vosotros la decisión de empezar a usarlas y la persona que puede tomar la decisión no entiende la importancia de usarlas y lo ve como un trabajo innecesario que no lleva a ningún lado.

Desgraciadamente este situación es muy habitual y aunque está cambiando poco a poco, el cambio el lento y largo. La resistencia al cambio es el factor más importante contra el que se tiene que luchar para poder empezar a aplicar este tipo de acciones que comentamos anteriormente. La decisión suele depender de personas que no llegan a comprender las necesidad de estas prácticas y que prefieren no “arriesgarse” usándolas y seguir como siempre, ya que mal o bien siempre se han conseguido terminar las cosas. Si os habéis fijado ponemos entre comillas la palabra “arriesgado”, porque aplicar buenas prácticas nunca se puede considerar un riesgo sino una manera de rebajar los riesgos en nuestros proyectos.

Tampoco podemos negar que partiendo de cero empezar a usar buenas prácticas no conlleve su esfuerzo inicial extra para el proyecto, pero lo debemos ver más como una inversión que como un gasto.

Una primera alternativa para solventar los las reticencias puede ser buscar un sponsor. Alguien dentro de la organización que sí que tenga poder de decisión y que pueda ayudarnos a realizar los cambios que necesitamos. Esta labor puede llegar a ser tan vital como tan difícil de conseguirla ya que muy pocas personas están interesadas en participar en procesos de mejora y tampoco se le puede robar tiempo al trabajo diario para poder afrontar esas mejoras.

Una segunda alternativa es comprar un sponsor. Es buscar a alguien y darle el poder suficiente para poder realizar los cambios que son necesarios. Este alguien es mejor que sea alguien de fuera, ya que está demostrado que cuando viene alguien de fuera suele caminar sobre las aguas y se le ve con más respeto y autoridad que a alguien de dentro de la organización. Esta opción también suele ser complicada de llevar a cabo, ya que para poder contratar a una persona de fuera es necesario disponer de la financiación necesaria para ello, cosa que no suele depender del equipo de desarrollo.

Existe un tercer camino más sencillo y que no necesita la ayuda de nadie pero que no nos sirva para implantar grandes cambios o cambios que se salgan del ámbito del proyecto. Actuar como el Caballo de Troya puede ser muchas veces la única alternativa que nos quede. Se trata de ir haciendo poco a poco cambios para mejorar día a día; si no tiene un gestor de fuentes, instálalo. Si no tienes un gestor de fuentes, instálalo. Son pequeños cambios que pueden mejorar nuestro trabajo e incluso podrían valer para poder llegar a conseguir un sponsor que vea que las mejoras que se han introducido son útiles y que siguiendo ese cambio se pueden conseguir más cosas.

Introducción a Team System

Aunque ya poco a poco cada vez más gente sabe qué es esto de Team System, todavía me encuentro con algunas situaciones en las que se desconoce y por este motivo he decidido publicar este post de introducción a Team System. Lo escribí hace tiempo con otro objetivo pero nunca vio la luz…

Visual Studio Team System es la solución Microsoft para gestionar el ciclo de vida completo de soluciones para plataforma Windows.

Con el uso de esta herramienta las empresas de software se verán beneficiadas de las importantes ventajas y beneficios que ofrece; permite reducir la complejidad del proceso de desarrollo, permite mejorar la colaboración de todos los miembros del equipo y mejorar la productividad, reduciendo los tiempos de desarrollo y pruebas. Y si aún así la herramienta no es suficiente se puede personalizar y extender todo lo que queremos, ya sea desarrollando aplicaciones propias o usando las que hayan creado terceras organizaciones.

clip_image002

Como veremos en los siguientes puntos, Team System incluye múltiples herramientas que permiten gestionar el ciclo de vida del desarrollo software. De una manera unificada, a través de Team System todos los roles involucrados en un proyecto de desarrollo disponen de las herramientas necesarias para realizar su trabajo de una manera eficiente. Se podría decir que Microsoft ha hecho una labor importante de integración, ya que las herramientas y utilidades que comentaremos a continuación no son nuevas en el mercado, siendo lo más importante la integración que existe entre ellas. Ya no es necesario utilizar múltiples herramientas de diferentes proveedores, cada una con su funcionamiento e interfaz. Ahora todas ellas están accesibles desde un único punto.

Team Server

Team System consta de dos componentes; una parte servidora y una parte cliente. La parte servidora se llama Team Server y su misión es facilitar y permitir el trabajo en equipo de todos los miembros del equipo de desarrollo. Esta parte servidora provee de múltiples herramientas que posibilita que haya mayor comunicación entre el equipo, con el objetivo de poder desempeñar mejor su trabajo.

Dejando atrás el SourceSafe

Desde mi punto de vista uno de los grandes puntos de este nuevo producto es el nuevo y potente gestor de fuentes que incluye. Sobre todo para los que hemos usado y sufrido sourcesafe esta característica nos será de gran utilidad. El gestor de fuente de Team Server no es una nueva versión de sourcesafe, sino un producto completamente nuevo, que supera con creces al anterior.

Para los usuarios de sourcesafe, que Team Server incluya este gestor de fuentes ya puede justificar su uso. Comentar que existe una herramienta de migración de sourcesafe a TeamSystem llamada VSConverter, que puede ser de gran utilidad para realizar el cambio.

Compilaciones

Otro punto interesante que provee el componente servidor es la posibilidad de hacer construcciones diarias de nuestro proyecto. Poder realizar compilaciones de una manera predecible es un factor crítico para el éxito de un proyecto. Además, como se verá más adelante Team System ofrece unos completísimos informes para poder conocer cómo son nuestras compilaciones y qué cambios ha habido en la última compilación respecto con la anterior, con el objetivo de poder centrarse en probar sólo los cambios.

Gestión de WorkItems

La gestión de workitems es uno de los puntos claves del producto. Un workitem es un elemento de trabajo dentro de una metodología en concreto. Por ejemplo, en MSF for CMMI los requisitos, tareas o bugs son los workitems. En cambio en MSF Agile se manejan escenarios en lugar de requisitos, ya que el enfoque y funcionamiento de esta metodología es diferente.

Para los habituados a usar Microsoft Excel y Microsoft Project para la gestión de los workitems comentar que podrán seguir haciéndolo, ya que Team System permite poder realizar estas acciones desde estos dos productos y mantener sincronizada toda la información.

clip_image004

Métricas

Team Server ofrece un completísimo sistema de informes, basado en Reporting Services, que permite obtener métricas sobre la evolución del proyecto, con el objetivo de poder tomar decisiones. Para el jefe de proyecto disponer de esta información es la base para poder tomar decisiones adecuadas que lleven al éxito del proyecto.

Gracias a la integración de todas las herramientas del ciclo de vida no será necesario realizar un trabajo adicional para poder obtener las métricas y será Team Server el encargado de obtenerlas a partir de la información de los workitems.

Como veremos más adelante, Team System da a las métricas un enfoque descriptivo, basándolas en gráficas multidimensionales que el jefe de proyecto debe interpretar para poder tomar decisiones.

clip_image006

Portal del Proyecto

¿A quién no le ha ocurrido que ha ido a buscar información del proyecto y no sabía dónde estaba?¿Cuántas veces ha ocurrido? Por desgracia, esta situación es muy habitual dentro de los proyectos.

Team Server incluye un portal, basado en Windows SharePoint Services, que sirve de repositorio común y de comunicación entre los diferentes integrantes del proyecto y que pretende evitar los problemas de comunicación que mencionábamos anteriormente.

clip_image007

Visual Studio Team Edition

El componente cliente es Visual Studio Team Edition. Existen varias ediciones diferentes que se orientan en función del perfil del desarrollador. Cada versión dispone de herramientas especializadas para apoyar el trabajo de cada perfil.

A Continuación se describen las cuatro versiones que existen actualmente de Visual Studio Team Edition.

Visual Studio Team Edition Software Architects

Esta versión incluye varios diseñadores visuales que ayudan a al trabajo de los arquitectos de cara a realizar aplicaciones orientadas a servicios y reducir los riesgos en la fase de implantación.

Incluye un diseñador de la arquitectura y un diseñador de despligue de la aplicación, permitiendo poder validar la arquitectura contra el diagrama de despligue. Por ejemplo si en el digrama de arquitectura dos componentes se comunican por el protocolo TCP y en el diagrama de despliegue existe una restricción de que las comunicaciones sólo son http, no validará la arquitectura contra el despliegue.


Visual Studio Team Edition Software Developers

Esta versión añade funcionalidad a las herramientas que ya vienen con visual Studio professional, sobre todo orientadas a mejorar la calidad de los desarrollos desde el principio y durante todo el ciclo de vida. Incluye varias herramientas que permiten al desarrollador centrarse en los problemas de rendimiento y seguridad que pueden afectarle.

Incluye un analizador dinámico, sólo disponible para C++ no manejado, que detecta errores en tiempo de ejecución como buffer overflow o problemas de seguridad.

Un analizador estático que informa de potenciales aspectos mejorables de nuestro código. Analiza los ensamblados ya generados e informa de problemas que pueda haber. El sistema está basado en reglas, reglas que el desarrollador puede configurar y extender. El analizador estático es FxCop, una herramienta que ya existía de manera independiente desde hace unos años.

Dispone de “Code Profiler”, que permite analizar el comportamiento de nuestros módulos desde el punto de vista del rendimiento. Esta herramienta es muy importante en entornos manejados, porque es muy difícil de prever las optimizaciones que hace el compilador y las que puede hacer el runtime de .NET durante la ejecución. Antiguamente, en C++, se podía llegar a ser más listo y escribir código en ensamblador para ganar rendimiento. Ahora es más difícil, hay muchas capas y el compilador hace cada vez más optimizaciones. Es de vital importancia que en todo proyecto haya un profiler. Si alguien sostiene que optimiza el rendimiento de su aplicación sin usar uno deberíamos dudar de lo que hace.

Las pruebas unitarias son un punto básico para mejorar la calidad de nuestros desarrollos. Una prueba unitaria no es más que código que prueba otro código. Team System facilita enormemente la creación de estas pruebas unitarias y el manejo de las mismas. Haciendo pruebas unitarias obtenemos pruebas que podemos repetir. Al modificar código podemos volver a pasarlas de manera automatizada y detectar errores en los cambios que hemos incluido. Seguro que a todos nos ha pasado que hemos hecho un cambio sin importancia que ha provocado efectos no deseados en otros módulos.

Muy unida a las pruebas unitarias está la cobertura de código. Una prueba unitaria es buena dependiendo de la cobertura de código. La cobertura nos mide cuánto código está probado por nuestras pruebas. Un tanto por ciento bajo denotaría unas pruebas pobres.

Visual Studio Team Edition Software Testers

Es una versión orientada a los testers del proyecto, que les permitirán verificar el rendimiento de la aplicación antes del despliegue. Que exista una versión especializada es un hito importante una que no es algo habitual en España disponer de tester en los equipos. Parece que la industria y ahora Microsoft le está dando más importancia a este puesto, ya que ha dedicado una herramienta para ellos. Desde nuestro punto de vista es esencial que en todo proyecto exista el perfil del tester.

Esta versión toma como base las herramientas de pruebas unitarias y cobertura de código que veíamos en el punto anterior, añadiendo algunas funcionalidades nuevas.

Usando las pruebas unitarias de manera repetitiva permite realizar pruebas de carga sobre nuestra aplicación, con el objetivo de ver cómo ésta se comporta en esta situación.

clip_image008

También permite grabar interacciones con las aplicaciones web, con el objetivo de poder repetir estas interacciones.

Por último, permite realizar pruebas manuales. Una prueba no es más que un documento Word que describe las pruebas que hay que hacer sobre el sistema y que un tester tiene que realizar manualmente.El tester realizará la prueba manualmente e incluirá el resultado de la misma dentro de Team System con el objetivo de que los resultados estén disponibles para el cálculo de las métricas.

Visual Studio Team Edition Database Edition

Por último, existe una versión orientado al trabajo con base de datos. Está destinada a facilitar el trabajo diario de los desarrolladores y administradores de base de datos ayudándoles a gestionar los cambios, las pruebas y la implantación.

Ofrece funcionalidad muy interesante, como generación de script de instalación de un schema, comparación dos schemas o generación pruebas unitarias.

clip_image009

Las guía de Proceso en Team System

Un factor clave para el éxito de Team System son las guías de proceso. Las guías de proceso nos dan las directrices a seguir para poder seguir una determinada metodología de desarrollo.

Generalmente en la mayoría de los proyectos actuales no se sigue una metodología. Sí es cierto que muchas empresas tienen una escrita, generan documentación, pero que guardan en un cajón hasta que es necesario pasar una certificación. En Team System las guías de proceso y la metodología cobra un factor crítico, estando siempre las guías de proceso disponibles para ser consultadas por cualquier desarrollador.

Si intentáis crear un proyecto el primer paso será la elección de la metodología. Fijaros, antes de empezar a trabajar piensa cómo quieres trabajar. Es una cosa muy simple, pero que muy pocas veces se hace. Por defecto, Team System incluye dos metodologías; MSF for CMMI y MSF Agile.

Esta decisión es una de las más importantes que hay que tomar, ya que mucho del éxito del proyecto depende de ella, que se tratará en el siguiente número.

clip_image011

Conclusión

Visual Studio Team System es una herramienta que viene con la intención de mejorar nuestros procesos de desarrollo. Como hemos visto ofrece múltiples ventajas orientadas a mejorar la productividad y la calidad de nuestros desarrollos.

Aún así, no deja de ser una herramienta, que nos puede ayudar, pero que no vale para nada si no estamos convencidos de su uso. Nos pone de manifiesto la importancia de aplicar buenas prácticas y la importancia de seguir una metodología. Si queremos, Team System nos ayudará a que tengamos éxito en nuestros desarrollos.

Pruebas unitarias: Cobertura de código

La cobertura de código es un factor clave para determinar cómo de bueno son nuestras pruebas unitarias.

La cobertura de código lo que nos dice es la cantidad de código que está sometido a nuestras pruebas. A mayor cobertura mayor cantidad de código está siendo probado por nuestras pruebas unitarias.

Una cobertura del 85-90% indica que la gran mayoría de nuestro código estaría siendo probado. Una cobertura menor indica que hay una parte importante de nuestra aplicación que está sin probar y que deberíamos completar nuestras para cubrir los escenarios que no están siendo probados.

Desde la configuración de las pruebas unitarias debemos establecer los ensamblados que deben instrumentalizarse para comprobar la cobertura de código. Visual Studio sólo medirá la cobertura en aquellos ensamblados que seleccionemos.

Para acceder a la configuración se las pruebas haz doble-click sobre el fichero LocalTestRun.testrunconfig.

clip_image002

Cuando se pasan las pruebas unitarias, una vez finalizada la ejecución de los pruebas, Visual Studio nos ofrece los datos relativos a la cobertura de código.

Estos datos no sólo nos dirán los porcentajes detallados de la cantidad de código probado, sino que también nos ofrecerán información muy útil para saber qué partes están probadas y cuáles no. De forma visualizar podremos ver la parte de código probada y no probada ya que Visual Studio nos colorea de forma diferente el código.

Es conveniente revisar la cobertura cuando hacemos las pruebas unitarias para conseguir que la mayor parte de código esté cubierto por una prueba.

clip_image004

Sobre esta venta podremos seleccionar la opción “Show Code Coverage Coloring” para poder ver el código coloreado de manera diferente, en función de si las pruebas han pasado o no han pasado por ahí.

image

Otra cosa que podemos hacer es combinar entre sí los resultados de diferentes ejecuciones de pruebas. Esto es así, porque desde la ventana de resultados se puede exportar e importar los datos a XML.

Si se importan varios resultados se puede juntar en uno y una vez juntados, se pueden volver a exportar.

Untitled

Del mismo modo el resultado de las pruebas también se puede exportar e importar y del mismo modo que al que hemos comentado, se pueden juntar los resultados de varias pruebas. Los ficheros generados tienen extensión trx.

Por último comentar que una cosa que hay que tener en cuenta, es que para obtener los datos de cobertura Visual Studio instrumentaliza los ensamblados seleccionados, para incluir en ellos información extra que le sirva para calcular la información que necesita.

Si los ensamblados están firmados y se instrumentalizan, la firma ya no será valida, ya que se está cambiado el fichero. Por tanto, será necesario volver a firmarlos. En la configuración de la cobertura de código se puede especificar el archivo de claves para volver a firmar los ensamblados.

Pruebas unitarias: Manos a la obra ( II )

En el post anterior vimos una introducción al framework de Visual Studio para el desarrollo de pruebas unitarias. En este post completaré algunos aspectos que no se mencionaron en el post anterior.

En el ejemplo que vimos en el post anterior implementamos una prueba muy simple sobre el método Sumar.

[TestMethod()]
public void SumarTest()
{
    ClaseEjemplo target = new ClaseEjemplo();
    int a = 1;
    int b = 2;
    int expected = 3;
    int actual;
    actual = target.Sumar(a, b);
    Assert.AreEqual(expected, actual);
}

En la prueba podéis ver cómo usando la sentencia Assert.AreEqual se comprueba si el resultado del método Sumar corresponde con el resultado esperado.

La clase Assert es parte del Framework y que se incluye dentro de la referencia Microsoft.VisualStudio.QualityTools.UnitTestFramework. Esta clase nos proporciona algunos métodos para comprobar los resultados de los métodos que están sometidos a la prueba; IsFalse, IsNull, AreSame…..

clip_image002

Parece por tanto, que toda prueba debería terminar con una clausula de este tipo para comprobar si la prueba ha sido correcta o no. Pues bien, esto no es así.

Aunque seguramente usaremos alguno de los métodos de la clase Assert en la mayoría de las situaciones no es de uso obligatorio. Si no usamos esta clausula, la ejecución de la prueba dará un resultado correcta siempre y cuando la ejecución de la misma no genere una excepción.

Por ejemplo, vamos a modificar nuestro método suma para que sólo sume valores positivos y si alguno de los parámetros que recibe es menor que 0, que devuelva una excepción.

public int Sumar(int a, int b)
{
    if (a < 0 || b < 0)
        throw new ArgumentException();
    
    return a + b;
}

En este caso, nos podría interesar hacer una prueba dónde comprobemos que no se genera una excepción cuando los parámetros sean mayores que 0. En esa prueba no sería necesario incluir ninguna sentencia de comprobación. Si le pasamos valores positivos la prueba será correcta siempre y cuando no genera una excepción.

Del mismo modo, nos interesará hacer una prueba para comprobar que la validación se hace correctamente y que se devuelve la excepción ArgumentException en este caso.

En este caso, deberemos decorar el método de prueba con el atributo ExpectedException. Con este atributo estamos especificando que el resultado esperado de la ejecución de la prueba es la excepción ArgumentException. Si no se genera la excepción o la excepción no es del tipo esperado, la prueba fallará.

[TestMethod()]
[ExpectedException(typeof(System.ArgumentException))]
public void SumarTest()
{
    ClaseEjemplo target = new ClaseEjemplo();
    int a = -1;
    int b = -2;
    int actual;
    actual = target.Sumar(a, b);
}

Para terminar con esta introducción hablaremos sobre los métodos de inicialización. En las clases que contienen las pruebas unitarias existen cuatro métodos qué tienen una finalidad especial y que están decorados con un atributo que determina su objetivo.

El atributo ClassInitialize identifica un método que contiene código que debe ejecutarse antes de que se ejecute cualquiera de las pruebas de la clase y para asignar los recursos que utilizará la clase de pruebas.

El atributo TestInitialize identifica un método que contiene código que se ejecuta antes de cada prueba que contiene la clase y se usa para asignar y configurar los recursos  que necesitan todas las clase de la prueba.

El atributo ClassCleanup identifica un método que se utilizará después de la ejecución de todas las pruebas de la clase y para liberar los recursos  obtenidos por la prueba.

El atributo TestCleanup contiene código que se ejecutará después de ejecutar cada prueba y se puede usar la liberar los recursos  obtenidos durante la prueba.

//Use ClassInitialize to run code before running the first test in the class
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
}

//Use ClassCleanup to run code after all tests in a class have run
[ClassCleanup()]
public static void MyClassCleanup()
{
}

//Use TestInitialize to run code before running each test
[TestInitialize()]
public void MyTestInitialize()
{
}

//Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
}

Claro está, el uso de estos métodos no es para nada obligatorio y sólo deberemos emplearlos en las situaciones que lo necesitemos. Por defecto ,al generar la prueba, estos métodos están comentados.

Como ya vimos en los post anteriores una prueba unitaria debería funcionar de manera independiente al entorno y una vez ejecutada dejarlo tal y como estaba antes de ejecutar la prueba.

Estos cuatro métodos nos ayudarán a cumplir con estos dos objetivos ya que nos podrán ayudar a preparar el entorno y los recursos necesarios para la ejecución de las pruebas y a restaurar el entorno y liberar los recursos una vez ejecutadas.

Pruebas unitarias: Manos a la obra ( I )

Hasta ahora he estado hablando de las pruebas unitarias desde un aspecto puramente teórico.

He hablado sobre las características una buena unitaria, de sus beneficios y de los mitos que rodean hasta buena práctica.

Y aunque todavía intentaré escribir algo más en el aspecto teórico ha llegado el momento de ver algo más práctico.

En los próximos post intentaré aportar mi granito de arena y explicar de una manera sencilla las características que viene con Team System para realizar pruebas unitarias desde un aspecto más práctico.

Como muchos ya sabréis Visual Studio nos proporciona un sistema sencillo para poder crear nuestras pruebas unitarias. Nos facilita la creación de los proyectos de pruebas y nos genera la estructura básica que tiene que tener la prueba.

Supondremos que tenemos una clase que tiene un método Suma. Este método, recibe como parámetro dos valores enteros y devuelve la suma ambos. Sí, el ejemplo es un poco tonto pero la idea es dar a conocer la herramienta, tiempo habrá para complicar el ejemplo.

public int Sumar(int a, int b )
{
    return a + b;
}

Una vez implementado el método necesitamos probarlo. Para ello creamos nueva primera prueba unitaria. Si seleccionamos el método Sumar, en el menú contextual tendremos la opción de crear una prueba unitaria.

La prueba la podremos crear en un nuevo proyecto de test o en uno ya existente. Como es nuestra primera prueba, lógicamente, lo incluiremos en un nuevo proyecto de test.

Mi recomendación es crear al menos un proyecto de Test por cada proyecto que tengas en tu aplicación, en lugar de crear un único proyecto de test que englobe todos los las pruebas de tu aplicación.

image

image

El nuevo proyecto que se crea es un proyecto normal y corriente. La única peculiaridad que tiene una referencia de Microsoft.VisualStudio.QualityTools.UnitTestFramework.

image

Ten en cuenta, que con este paso no se crea la prueba, sólo la estructura de proyectos, clases y métodos. Es labor de desarrollador, en base a las especificaciones del módulo, el desarrollo de las pruebas. Es importante que el desarrollador realice tantas pruebas como sea necesario para cubrir al máximo la funcionalidad del módulo que se prueba.

Fijaros en el código del método de prueba que tanto la clase como el método son clases y métodos normales, con la única peculiaridad que el método está decorado con el atributo TestMethod.

///A test for Sumar
///</summary>
[TestMethod()]
public void SumarTest()
{
    ClaseEjemplo target = new ClaseEjemplo(); // TODO: Initialize to an appropriate value
    int a = 0; // TODO: Initialize to an appropriate value
    int b = 0; // TODO: Initialize to an appropriate value
    int expected = 0; // TODO: Initialize to an appropriate value
    int actual;
    actual = target.Sumar(a, b);
    Assert.AreEqual(expected, actual);
    Assert.Inconclusive("Verify the correctness of this test method.");
}

Cuando hemos creado el proyecto de Test, en la solución han aparecido dos nuevos ficheros: Sample.vsmdi y LocalTestRun.testrunconfig.

Si hacemos doble-click sobre el archivo vsmdi podremos acceder al editor de la lista de pruebas unitarias. Desde aquí podremos ver, lanzar o depurar todos las pruebas unitarias que contiene la solución. Y digo que contiene la solución, porque este fichero es común para todos los proyectos de Test de la solución. Si éste contiene 2 proyectos de Test, desde la lista de pruebas unitarias veremos todas las pruebas de los dos proyectos.

image

El fichero LocalTestRun.testrunconfig lo que nos va a permitir es configurar algunos aspectos relacionados con la ejecución de las pruebas, como activar el análisis de la cobertura de código.

image

Una vez que tenemos la estructura de nuestro método de prueba tendremos que implementar la prueba.

La idea es muy sencilla. Si pasamos 1 y 2 en los parámetros de entrada el método sumar nos tiene que devolver 3. Es decir, sabiendo los parámetros de entrada y lo que hace el método que estamos probando, sabremos lo que tiene que devolver.

El objetivo de la prueba es comprobar que el método Sumar hace exactamente lo que se espera de él. Si el método Sumar en lugar de 3 devolviese 7, porque se ha equivocado al sumar, la prueba unitaria fallaría.

Una vez hecha prueba recuerda eliminar la sentencia Assert.Inconclusive.Esta sentencia se incluye cuando se crea la prueba e indica que el resultado de la prueba no es concluyente. De esta manera se marcan las pruebas que no están implementados.

        [TestMethod()]
        public void SumarTest()
        {
            ClaseEjemplo target = new ClaseEjemplo();
            int a = 1;
            int b = 2;
            int expected = 3;
            int actual;
            actual = target.Sumar(a, b);
            Assert.AreEqual(expected, actual);
        }

Una vez, hecha la prueba sólo tenemos que ejecutarla. Desde la ventana de lista de pruebas podemos ejecutar todas las pruebas o sólo aquellas que seleccionemos. En la parte inferior, en la ventana de resultados de la prueba veremos el resultado de la ejecución de los mismos.

image

Bueno, por el momento lo dejamos aquí. En el siguiente post seguiremos viendo algunos aspectos básicos del Framework de pruebas unitarias, como son la cobertura de código o el uso de atributos.

¿El método TryParse genera excepciones?

Como todos ya sabréis el método TryParse se utiliza para realizar conversiones de un tipo a otro, por ejemplo, para convertir una fecha representada en una variable string a una variable de tipo DateTime.

Si la conversión se puede realizar, devuelve true como resultado y en el segundo parámetro devuelve la fecha que representa el primer parámetro.

Si la conversión no se puede realizar, devuelve false como resultado y en este caso, por tratarse de un tipo DateTime devuelve MinValue en el segundo parámetro.

public static bool TryParse(
    string s,
    out DateTime result
)

Lo bueno de TryParse frente a otros métodos de conversión es que no genera una excepción si se produce un error en la conversión….o sí que puede generlas????

Pues sí, sí que puede….al menos es capaz de generar esta excepción:

Unhandled Exception: System.IndexOutOfRangeException: Index was outside the bounds of the array.

La razón de este error a día de hoy la sigo sin tener muy clara pero lo que sí tengo claro es que está relacionado con la configuración regional.

Y explico por qué no lo tengo muy claro; dos equipos, idéntica configuración regional, mismo sistema operativo, idioma etc……en uno funciona y en otro no. Mil pruebas jugando con la cultura en la conversión y nada…..todo parece correcto pero salta la excepción.

Y la solución pues algo ridícula a priori pero funcionó…..cambiamos el formato de la hora de la configuración regional, cambiamos para que en el hora no se incluyera la marca de AM/PM….y a partir de ese momento el método TryParse empezó a funcionar según las especificaciones.

Y lo más raro aún, volvimos a cambiar la configuración para ponerla en el estado anterior y seguía funcionando…ya no conseguimos volver a generar la excepción…

Este caso es un poco raro pero parece ser que sí que hay un error en el Framework .NET 2.0 con el método TryParse. No he podido comprobar si con el 3.5 ocurre lo mismo pero es más que probable que ya esté solucionado.

Aunque la situación que comento no es la misma, por lo que he podido leer, también existe un bug en el método TryParse de la versión 2.0 cuando en el formato de la fecha de la configuración regional se usan espacios como caracteres de separación pudiendo llegar a generarse esta excepción.

Conclusión, que aunque no está nada claro, si de repente os dais cuenta que el método TryParse os genera una excepción no penséis que os habéis vuelto loco y buscar en la causa en la configuración regional.