Medición de cobertura en .Net Core con Coverlet

Luego de cumplir con los primeros hitos de negocio y teniendo un equipo que empieza a estabilizarse me puse a hacer algunas pruebas para medir la cobertura de nuestro proyecto.

En primera instancia atiné a utilizar OpenCover, una herramienta que había utilizado en proyectos anteriores, pero me encontré que solo corre en Windows. Nuestra infraestructura de build corre en Linux y yo particularmente trabajo en MacOS. Con lo cual OpenCover quedó descartado.

Luego de Googlear un poco dí con Coverlet que según la documentación es multiplataforma. Investigando un poco más encontré este artículo de Scott Hanselman y con eso me bastó para hacer una prueba. A continuación voy a compartir algunos descubrimiento que hice aprendiendo a utilizar esta herramienta.

En primer lugar tenemos que saber que hay tres formas de utilizar esta Coverlet:

  1. Como una extensión de dotnet-cli
  2. Como un collector integrado al motor de ejecución de VSTest
  3. Como una tarea de MSBuild

Yo decidí ir por esta última estrategia. Para ello el primer paso es agregar el paquete coverlet.msbuild a cada uno de los proyectos de tests. Una vez agregado este paquete simplemente tenemos que agregar el parámetro de cobertura al momento de la ejecución de los tests

dotnet add package coverlet.msbuild
dotnet test /p:CollectCoverage=true

Si tenemos un solo proyecto de tests que cubre todos los proyectos/assemblies de nuestra solución, con esto ya habrá sido suficiente. Al ejecutar los comandos anteriores obtendremos una salida como la que se muestra en la siguiente figura.

Pero si nuestra solución, como es muy habitual, tiene varios proyectos de tests nos vamos a encontrar que la medición que hace Coverlet es «parcial»/»desagregada». Ocurre que cada proyecto de tests es ejecutado ejecutado independientemente haciendo que la medición de cobertura también sea independiente lo cual a su vez hace que tengamos varios reportes de cobertura. Esto se puede observar en la siguiente figura.

El primer reporte corresponde al proyecto de tests de Domain y nos indica que precisamente Domain tiene una cobertura de ~79%.
El segundo reporte corresponde al proyecto de tests de ApiServices y como ApiServices depende de Domain, la medición de cobertura considera ambos proyectos. Pero dado que los tests de ApiServices apenas tocan el código de Domain, la cobertura informada sobre Domain es mínima (~6%). Entonces lo que deberíamos hacer para obtener el valor correcto de cobertura es mezclar el reporte de cobertura generado por el proyecto de tests de Domain y el proyecto de tests de ApiServices. Aquí también coverlet nos da varias opciones. En mi caso, lo que hice fue ejecutar explícitamente cada proyecto de test por separado, escribiendo los resultados en un archivo y en la misma ejecución indicándole a Coverlet que realice el merge con el archivo de cobertura de la ejecución anterior.

dotnet test Domain.Tests/Domain.Tests.csproj /p:CollectCoverage=true /p:CoverletOutput=../coverage.json

dotnet test ApiServices.Tests/ApiServices.Tests.csproj /p:CollectCoverage=true /p:CoverletOutput=../coverage.json /p:MergeWith=../coverage.json

De esta forma el reporte se genera correctamente.

Una situación habitual cuando medimos la cobertura es no incluir en el cálculo algunas archivos. En nuestro caso ocurre que consumimos servicios SOAP, y utilizamos una herramienta que nos genera un conjunto de clases proxy para interactuar con SOAP. Dichas clases son almacenadas en un archivo Reference.cs que queremos excluir del análisis de cobertura. Para esto debemos incluir un parámetro adicional para Coverlet en la ejecución de los test /p:ExcludeByFile=»**/Reference.cs».

Bien, con todo lo descripto hasta el momento hemos logrado medir el % de cobertura de nuestro código. Lo siguiente que suele hacerse es ver cuales son las partes de código sin cobertura. Si bien coverlet tiene la capacidad de detectar esto, no provee un mecanismo cómodo para visualizarlo y por ello debemos utilizar otra herramienta complementaria. Pero eso será parte de otro post.

Notas sobre los IDEs para .Net Core

Notas sobre los IDEs para .Net Core

En breve estoy empezando a trabajar en un nuevo proyecto con .Net. Es mi vuelta a tecnología .Net luego de casi 3 años. Pero una diferencia relevante respecto de mi último proyecto es que en este caso utilizaremos .Net Core. En mi proyecto anterior utilicé .Net Framework 4.6 y dado que yo «vivo en MacOS» utilicé una máquina virtual con Windows 7 y Visual Studio 2017, lo cual anduvo muy bien. En este caso, dado que .Net Core corre nativamente en MacOS estoy apostando a esa posibilidad. Para esto instalé .Net Core y estuve probando distintas alternativas de IDE.

Precisamente el tema del IDE es una de las novedades más importante del mundo .Net. Tradicionalmente trabajar con .Net implicaba casi irremediablemente utilizar Visual Studio, porque si bien había algunas otras alternativas, ninguna estaba lo suficientemente estable o contaba con las funcionalidades necesarias para el desarrollo profesional. Con la salida de .Net Core y la iniciativa de Omnisharp, hoy en día es posible elegir entre varias alternativas.

Lo primero que probé fue utilizar Visual Studio Code que tiene un plugin para .Net/C#. La experiencia está bastante lograda, es posible correr los tests y debuggearlos desde dentro VSCode. También ofrece soporte para algunos refactors. Con el agregado de algunos otros plugins y la combinación con el dotnet-cli es una alternativamente perfectamente válida. Pero no quise quedarme ahí así que continúe probando.

Lo segundo que probé fue Visual Studio para Mac, la prueba fue corta pues me resultó muy incómodo ya que es distinto al tradicional Visual Studio de Windows y me sentí desorientado. Da la sensación que quisieron adaptar el Visual Studio a ciertas cuestiones de UI/UX de MacOS y el resultado para mi no fue bueno.

Mi tercera prueba fue con Rider, el IDE de JetBrains. Desde hace bastante tiempo cuando trabajo con Java uso el IDE de JetBrains (IntelliJ) con lo cual tenía que probar Rider. Y no me defraudó, la experiencia me resultó muy buena ya que a nivel IDE es casi como trabajar con IntelliJ y la integración con las herramientas .Net está muy bien lograda.

Aún tengo que hacer algunas pruebas para ver el soporte y la integración con algunos frameworks/herramientas de desarrollo (specflow por ejemplo) pero en principio estaré entre Rider y VSCode.

.Net Core: lo que MS no te contó

Si uno se pone a investigar sobre .Net Core encontrará que en la mayoría de las fuentes se destacan las siguientes cuestiones:

  • La posibilidad de correr de fuera de Windows, más concretamente en Linux y Mac.
  • La nueva .Net Standard Library y su objetivo de «unificar» el mundo del desarrollo .Net proveyendo verdadera portabilidad entre las distintas plataformas .Net.
  • La intención de tener un sistema mucho más modular, basado en la idea de un Core realmente pequeño y la capacidad de cargar módulos adicionales según se requiera, usando el gestor de paquetes NuGet.
  • Una nueva experiencia de usuario para el desarrollador basada en un nuevo set de herramientas en el que se destaca Visual Studio Code.

Si bien considero que todos estos puntos son muy relevantes, creo que el primero tiene un impacto grandísimo pero que curiosamente no parecer estar proporcionalmente publicitado. Por lo que vengo leyendo la capacidad de correr fuera de Windows «es vendida» desde el punto de vista de desarrollo: «ahora podes codear .Net en Linux». Pero a mi me parecer el mayor impacto de esta nueva capacidad no es tanto en desarrollo como en operación/producción, o sea: es posible hacer aplicaciones .Net y ponerlas a correr en un ambiente productivo Linux.

Tal vez esto no sea precisamente lo que más le interesa a Microsoft del nuevo .Net, pero definitivamente es lo más me interesa a mi 😉

Formas de ejecución de FxCop

Ejecución Manual

Si uno utiliza la versión standalone de FxCop, tiene en principio 2 alternativas: utilizar la interface de gráfica o la de línea de comandos.Pero hay que tomar en cuenta que mientras la interface de linea de comandos solo puede ejecutar análisis, la interface gráfica además de ejecutar análisis, permite crear proyectos de FxCop (.fxcop) con configuraciones específicas que incluyan conjuntos particulares de reglas y algunos otros parámetros específicos para la ejecución del análisis. Al mismo tiempo ocurre que la interface de línea de comando soporta  algunos opciones que la interface gráfica no, por ejemplo rulesets (.ruleset)

Otra forma de ejecutar análisis FxCop en forma manual es si uno cuenta con una version de Visual Studio que tenga la funcionalidad de Code Analysis incorporada. Es ese caso, pueden configurarse las reglas a aplicar desde las propiedades del proyecto y luego disparar el análisis desde el menú contextual del proyecto.

Ejecuación integrada a la compilación

Si uno cuenta con una versión de Visual Studio con la funcionalidad de Code Analysis incorporada, entonces también tiene opción de modificar los archivos de proyecto (.csproj) para que se dispare el análisis de código en cada compilación.

Ejecución con MSBuild

Esta opción es mi prefedida pues es independiente del Visual Studio lo cual la hace ideal a la hora de utilizar un build server. Básicamente consiste en generar un build script de MSBuild con una tarea de que se encargue de invocar a utilitario de linea de comando de MSBuild. Tiene un pequeño issue pues ni MSBuild ni FXCop proveen una tarea para ejecutar FxCop dentro de un script de MSBuild, por ello es necesario utilizar MSBuildExtensiónPack. Los interesado en esta opción pueden darle un vistazo a este build script que muestra un ejemplo (ver el target RunCodeAnalysis).

FxCop y Visual Studio

Continuando con la cuestión de análisis de código, quiero dedicar algunas líneas a estas dos herramientas. Como mencioné anteriormente,  Visual Studio ha incorporado nativamente a FxCop, pero he aquí algunos detalles curiosos:

  • No todas las ediciones de Visual Studio incorporaron FxCop, en particular las ediciones Professional no lo incorporaron hasta la version 2012 (nótese la diferencia entre version: 2008, 2010, 2012, etc  y edición: personal, professional, ultimate, etc).
  • Dentro de Visual Studio no hay ninguna mención a explícita a FxCop, sino que en los menús figura como Code Analysis, pero internamente es FxCop (pueden verse los assemblies dentro de la carpeta de Visual Studio).
  • Aún es posible descargar FxCop y utilizarlo de manera independiente al Visual Studio.
  • El FxCop independiente y el incluido en el Visual Studio no son exactamente lo mismo. Entre las diferencias hay algunos conjuntos de reglas adicionales que vienen con Visual Studio que no estan en el FxCop independiente.

Los puntos anteriores hacen que dependiendo de la versión específica de Visual Studio con la que uno cuente, la forma ejecutar el análisis de código sea diferente. en próximos post daré más detalles sobre esto.

Open source: new versions

In the last couple of weeks some new versions of open source projects have gone live.

In my opinion  the most interesting one is the first RTM release of Linq provider for NHibernate (NHibernate.Linq), at the moment it is a separete download, but it seems that it will be part of NHibernate’s Core package in future releases. [read more]

Also related to NHibernate, on July 14 it was published Castle Active Record 2.0 beta 1. It includes integration with NHibernate Search, basic Linq support and a feature to enable in-memory test. [read mode]

Spring Framework Team has schedule the release of Spring.Net 1.3 RC1 for July 29th, followed by the GA version on August 10th. [read more].

Finally, Sharp Architecture released the first RTM version on July 15th. [read more]

I hope to have some time during this week to show some examples of the new features of these new releases.

Enjoy it!

Something is changing…

Over the last two years some interesting things have happened in the .net community, among these things I would like to highlight the followings:

  • Greater interest in Domain Driven Design in contrast to the traditional MSDN Data driven way. This has stimulated the adoption of certain design techniques like DI and AOP among other.
  • As a consequence of the previous point there has been a wider adoption and diffusion of open source tools (beyond the P&P application blocks). Tools like NHibernate, Castle and Spring.Net have proven to be high quality products providing efficient solutions for typical problems in enterprise development. Event Microsoft (in a certain way) has recognized these facts, I think ASP.NET MVC is an example of this.
  • Massive adoption of agile development practices like continous integration, unit testing, pair programming and iterative development among others.

I think that evidence of these facts are the creation of the ALT.NET community and the publication of the excellent book «Foundations of Programming» by Karl Seguin.
I see this as great progress for the maturity of the community and the quality of its developments.

Embedded Resources

Sometimes your assembly on runtime depends on a file, like a image or a simple text file. To manage this file, you could store its location in the application configuration file, and then load your file by reading its location from configuration. Another option is to embedded the file as a resource in your assembly and then use the following code snippet to load it.

System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream(«NameOfTheFile»);

Lets see an example. Suppose an assembly called Model.dll that requires a file called TextFile.txt that is part of the same visual studio project. First of all you should define that file as an embedded resource (properties->build action = embedded resource). Then in your code, when you need to access this file you can load it this way:

System.IO.Stream fileStream = this.GetType().Assembly.GetManifestResourceStream(«Model.TextFile.txt»);
System.IO.StreamReader sr = new System.IO.StreamReader(s);
string fileContent = sr.ReadToEnd();
fileStream.Close();

Note that the name of the assembly has been appended to the of the file. One you have read the contents of the file, remember to close the stream

Tipos de excepciones

Independientemente de la tecnología de programación utilizada en toda aplicación es posible distinguir dos tipos de excepciones las de aplicación y las técnicas.
Las excepciones técnicas son producto de fallos en la infraestructura como ser falta de conectividad, caída de un servidor, etc.
Por su parte las excepciones de aplicación son producto de alguna acción incorrecta por parte del usuario y a grandes rasgos es posible clasificarlas en dos grupos: violaciones de formato (ingreso de un carácter en un campo numérico) y violaciones de reglas de reglas de negocio (alta de una entidad con un identificar repetido).
La distinción entre estos tipos de excepciones es necesaria ya que el comportamiento de la aplicación varia en base a estas.
Generalmente ante una excepción técnica la aplicación suele interrumpir la actividad del usuario mostrándole un mensaje del estilo «No es posible completar la operación requerida, por favor intente más tarde», sin hacer mayor distinción en el tipo particular de excepción.
Por su parte, ante excepciones de aplicación, el usuario suele recibir un mensaje más específico, indicándole el error que ha cometido y dándole la posibilidad de corregir el error cometido sin necesidad de volver a comenzar con la con la actividad que se encontraba desarrollando.
Otra diferencia entre estos tipos de excepciones radica en el loggueo de las misma. Las excepciones técnicas siempre se logguean, llegando incluso a generar notificaciones a los administradores del sistema, mientras que las excepciones de aplicación no suelen ser loggueadas (salvo por cuestiones de auditoría para detectar usos indebidos del sistema).
En el caso particular de .NET, las excepciones técnicas suelen ser subclases de SystemException, mientras que las excepciones de aplicación lo son de ApplicationException.

Toolkit de introducción a .net

Un buen punto para empezar a introducirse en el mundo .net es el programa del desarrollador 5 Estrellas:

http://www.mslatam.com/latam/msdn/comunidad/dce2005/

Este programa, va guiando al estudiante, de forma progresiva, comenzando casi de cero, y llegando incluso a exponer cuestiones de web services y conceptos de arquitectura.

Para poder ejercitar y seguir el curso a un buen ritmo, es necesario contar con el Visual Studio 2005. Si usted a un no cuenta con una versión del mismo, puede descargar el Visual Web Developer en forma gratuita de la siguiente ubicación.

http://msdn.microsoft.com/vstudio/express/downloads/

Finalmente es importante que gradualmente y al menos una vez por semana visite los siguientes sitios de referencia:

http://www.microsoft.com/practices
http://www.theserverside.net