Gerardo Contijoch

Experiencias del día a día trabajando con .NET – ASP.NET, C#, ASP.NET MVC y demas…

Archive for the ‘Visual Studio’ Category

Habilitar (y hacer funcionar) Code Coverage en Visual Studio

Posted by Gerardo Contijoch en mayo 12, 2009

Hace cerca de un mes, luego de escribir unos cuantos test sobre un código con el que estaba trabajando, se me ocurrió probar la capacidad de hacer Code Coverage (CC de ahora en adelante) desde Visual Studio. Lamentablemente lo que parecía sencillo de lograr, no lo fue. Lo primero a tener en cuenta es que el CC se configura a través de la pantalla de configuración de los Test Runs y no a nivel de Test Run. Esto implica que vamos a necesitar 2 sets de configuraciones diferentes para correr los tests con y sin CC. Para acceder a esta pantalla tenemos que ir a Test/Edit Test Run configurations/<configuracion_a_editar> y allí seleccionar la opción Code Coverage. Solo nos resta seleccionar los assemblies o proyectos a instrumentar (es decir, sobre los cuales hacer el CC) y aplicar (o guardar) los cambios.

Lo que hay que tener en cuenta ahora, es que si corremos los tests en modo debug el CC no se realiza a pesar de que lo hayamos habilitado y configurado correctamente. El CC solo tendrá efecto si los tests son corridos sin debug. Lamentablemente el warning de ésta situación (correr test en debug con CC habilitado) esta deshabilitado por defecto, lo que hace casi imposible determinar porque nuestro CC no se ejecuta. Para habilitar este warning, vamos a Tools/Options…/Tests Tools/Default Dialog Box Action y habilitamos el warning que dice ‘When starting a remote test run or a run with code coverage under the debugger:’ (en la versión en inglés, por supuesto). A partir de ahora si tenemos CC habilitado y queremos correr los tests en modo debug, una advertencia nos recordará sobre la deshabilitación temporal del CC.

Es increíble como algo tan sencillo es tan difícil de lograr en Visual Studio. No hay ningún menú dedicado al CC y en el menú Test no figura ninguna opción sobre esto (existe la posibilidad de abrir la ventana Code Coverage, pero nada mas). La ventana Test Runs tampoco posee ningún botón que nos permita habilitar/deshabilitar el CC (solo uno que nos permite ver los resultados). Tampoco hay ninguna opción en la ventana Code Coverage (yo esperaría habilitarlo o deshabilitarlo desde ahí mismo). En el toolbar Test Tools hay dos opciones relacionadas a CC, pero están deshabilitadas si no hubo CC (solo nos permiten navegar el código analizado). En la ventana Test Results hay 3 opciones para correr los tests (6 si contamos también las opciones de modo debug), pero ninguna que contemple el CC. Lo peor de todo es que una vez que encontramos como habilitarlo, la decisión de ocultar el warning hace que sea muy frustrante tratar de hacer funcionar el CC (yo estuve cerca de una hora sin ningún resultado). ¿Acaso tan difícil era agregar un botón a la ventana Test Runs que habilite o deshabilite el CC? ¿Porqué se tiene que habilitar a nivel de configuración general (lo cual en realidad no esta mal) y no dentro de cada Test Run?

Por cierto… ¿Para cuándo un CoverageExcludeAttribute como en NCover? (soluciones como el uso de DebuggerNonUserCodeAttribute y DebuggerHiddenAttribute no son aceptables)

La verdad, a mi parecer, es un desastre la manera en que esta implementado el acceso al CC en Visual Studio.

¡Nos vemos en el próximo post!

Referencias:

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Anuncios

Posted in Testing, Visual Studio | Etiquetado: | Leave a Comment »

Simplificar la depuración con el uso de DebuggerTypeProxyAttribute

Posted by Gerardo Contijoch en marzo 25, 2009

En el último post les hable sobre DebuggerDisplayAttribute, un atributo que nos permite cambiar la información que nos muestra el debugger de Visual Studio sobre un tipo. Ahora les voy a presentar otro atributo muy similar, pero cuya función es cambiar completamente lo que se muestra de un tipo, incluso sus propiedades. Estoy hablando de DebuggerTypeProxyAttribute. Al aplicar este atributo sobre una clase o estructura lo que hacemos es decirle al debugger que no use nuestra clase (o estructura) cuando inspeccionemos un objeto de ese tipo en el Debugger, sino que use un proxy a la misma. La idea detrás de esto es ocultar los miembros de nuestra clase (porque no son relevantes posiblemente) y mostrar los del proxy, los cuales son los que nos van a interesar ver cuando estemos depurando nuestro código.

Veamos como se vería un posible proxy para una clase Persona (tomada del post anterior y modificada ligeramente) junto a ella:

   1: [DebuggerDisplay("Nombre: {Nombre, nq}, Año de nacimiento: {FechaDeNacimiento.Year}, ¿Es Rosarino?: {Ciudad == \"Rosario\" ? \"Sí\" : \"No\", nq}")]
   2: public class Persona {
   3:     public string Nombre { get; set; }
   4:     public string Apellido { get; set; }
   5:     public int Edad { get; set; }
   6:     public string Ciudad { get; set; }
   7:     public DateTime FechaDeNacimiento { get; set; }
   8:
   9:     public bool EstaCasado { get; set; }
  10:     public Persona Conyuge { get; set; }
  11:
  12:     public Persona Padre { get; set; }
  13:     public Persona Madre { get; set; }
  14:
  15:     public IEnumerable<Persona> Hermanos { get; }
  16:
  17:     public bool PracticaDeportes { get; set; }
  18:     public IEnumerable<string> Deportes { get; }
  19:
  20:     public IEnumerable<string> Estudios { get; }
  21:
  22:     /// <summary>
  23:     /// Proxy para la clase Persona.
  24:     /// </summary>
  25:     internal class PersonaDebugView {
  26:         private Persona Persona { get; set; }
  27:
  28:         public PersonaDebugView(Persona p) {
  29:             Persona = p;
  30:         }
  31:
  32:         public string Nombre {
  33:             get {
  34:                 if (Persona.Madre != null) {
  35:                     return string.Format("{0} {1} {2}", Persona.Nombre, Persona.Apellido, Persona.Madre.Apellido);
  36:                 }
  37:
  38:                 return string.Format("{0} {1}", Persona.Nombre, Persona.Apellido);
  39:             }
  40:         }
  41:
  42:         public string NombreConyuge {
  43:             get {
  44:                 if (Persona.EstaCasado) {
  45:                     return Persona.Conyuge.Nombre;
  46:                 }
  47:
  48:                 return "No tiene conyuge";
  49:             }
  50:         }
  51:
  52:         public bool EsMayorDeEdad {
  53:             get { return Persona.Edad >= 21; }
  54:         }
  55:
  56:         public string PaisDeOrigen {
  57:             get { return RecuperarPaisAPartirDeCiudad(Persona.Ciudad); }
  58:         }
  59:     }
  60: }

Quisiera aclarar un par de puntos en este ejemplo. Primero, vemos que la clase proxy se encuentra dentro de la clase Persona. Esto es recomendable ya de ese modo el proxy puede tener acceso a los miembros privados de la clase que lo contiene y tiene el beneficio extra de que no se mezcla con el resto de las clases de nuestra aplicación. También es un requisito que el constructor del proxy tenga un parámetro del tipo de la clase que se desea ocultar.

Otro detalle que puede haber saltado para los que no leyeron el post anterior (¿qué están esperando?), es el uso de DebuggerDisplayAttribute. Si les interesa saber porque lo uso, pueden encontrar acá el motivo.

Si depuramos nuestra aplicación (aún sin haber aplicado el atributo DebuggerTypeProxyAttribute), veremos que la clase Persona se ve así en el debugger:

DebuggerProxyType-persona

Son muchos datos para una persona y si la mayoría de ellos no nos interesa (recordemos que estamos trabajando sobre un ejemplo) puede volverse un poco incómodo inspeccionar nuestras variables. Veamos ahora como se vería esta pantalla si aplicamos el atributo DebuggerTypeProxyAttribute de la siguiente manera:

   1: [DebuggerTypeProxy(typeof(PersonaDebugView))]
   2: [DebuggerDisplay(/*...*/)]
   3: public class Persona {
   4:     /*...*/
   5: }

DebuggerProxyType-personaconProxy

Las propiedades que estamos viendo son las del proxy (que no tienen que corresponderse necesariamente con las de la clase Persona) y nos muestran una vista totalmente diferente de la variable que estamos inspeccionando.

Presten atención a un nuevo miembro: RawView. Éste último, generado automáticamente, lo que hace es mostrarnos la vista original o sin modificar de nuestra clase y si lo abrimos veremos que tenemos acceso a todas las propiedades de la clase Persona, tal cual la definimos.

El uso de este atributo es muy común en las colecciones en donde se ocultan muchos miembros y solo se muestran unos pocos que son los más relevantes a la hora de trabajar con una colección. Siempre que inspeccionen una variable y vean el miembro RawView, van a estar viendo un proxy para esa clase y no su verdadera implementación.

Aplicando el atributo a nivel de ensamblado

Al igual que con DebuggerDisplayAttribute, DebuggerTypeProxyAttribute puede usarse a nivel de ensamblado exactamente de la misma manera. En el post anterior explico en detalle como se hace esto.

Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in .Net 2.0, Visual Studio | Etiquetado: , , | 2 Comments »

DebuggerDisplayAttribute, una gran ayuda durante la depuración

Posted by Gerardo Contijoch en marzo 19, 2009

Hace un tiempo, revisando el código fuente de Castle.Core, uno de los componentes más importantes de Castle Microkernel, redescubrí (porque me había olvidado por completo de el) uno de los atributos más útiles que existen en el .NET Framework, DebuggerDisplayAttribute, el cuál nos permite personalizar la información que se muestra de un objeto o miembro en las ventanas de debug en Visual Studio así como también en los tooltips que aparecen al pasar el cursor sobre una variable.

Imaginemos que tenemos la clase Persona definida de la siguiente manera:

   1: public class Persona {
   2:     public string Nombre { get {/*...*/} set {/*...*/} }
   3:     public int Edad { get{/*...*/} set{/*...*/} }
   4:     public string Ciudad { get {/*...*/} set {/*...*/} }
   5:     public DateTime FechaDeNacimiento { get {/*...*/} set {/*...*/} }
   6: }

Normalmente mientras estamos depurando nuestra aplicación al inspeccionar una variable de tipo Persona la ventana QuickWatch (Inspección rápida) nos muestra la variable de la siguiente manera:

DebuggerDisplayAttribute-personaSinNombre

Se puede ver que el valor (columna Value) mostrado es el propio tipo de la variable, lo cual es redundante ya que el tipo aparece aclarado en su propia columna. En nuestro caso, eso no importa mucho ya que al expandir la variable vamos a ver todas sus propiedades, que es lo que realmente nos interesa, pero imaginen que tienen una lista de personas y precisan ubicar una en particular por alguna de sus propiedades. El trabajo de encontrarla puede ser muy tedioso:

DebuggerDisplayAttribute-personasSinNombre

Por eso para ayudarnos en estos casos esta DebuggerDisplayAttribute, el cual nos permite personalizar el valor mostrado en la columna Value de modo que podamos mostrar información más útil que el tipo de la variable o miembro bajo inspección. La propiedad más importante de este atributo es Value (de tipo string) que no es ni más ni menos que el valor a mostrar en la columna Value. Esta cadena puede contener llaves ({}) entre las cuales se puede especificar el nombre de un miembro cuyo valor queremos mostrar. Veamos como podemos decorar nuestra clase con este atributo:

   1: [DebuggerDisplay("Esta persona es {Nombre}")]
   2: public class Persona {
   3:    /*...*/
   4: }

Como resultado de este cambio, ahora la clase se va a ver así en la ventana de Debug:

DebuggerDisplayAttribute-personasConNombre

Si queremos sacar las comillas de los valores de tipo string, simplemente agregamos nq al miembro al que hacemos referencia:

   1: [DebuggerDisplay("Esta persona es {Nombre, nq}")]
   2: public class Persona {
   3:     /*...*/
   4: }

DebuggerDisplayAttribute-personaConNombreSinComillas

Incluso podemos incluir expresiones simples en nuestra descripción, pero sólo si estamos trabajando con C#:

   1: [DebuggerDisplay("Nombre: {Nombre, nq}, Año de nacimiento: {FechaDeNacimiento.Year}, ¿Es Rosarino?: {Ciudad == \"Rosario\" ? \"Sí\" : \"No\", nq}")]
   2: public class Persona {
   3:     /*...*/
   4: }

DebuggerDisplayAttribute-personaConNombreYExpresion

Otra forma de uso

El hecho de usar este atributo para decorar las clases puede no ser muy bien visto ya que es algo que afecta al entorno de desarrollo y no tiene relación con el contenido de nuestras clases en si. Es ajeno a nuestros sistemas y su presencia no afecta (o al menos no debería afectar) al comportamiento de los mismos. Estamos modificando nuestras clases solo porque queremos que Visual Studio nos las muestre como a nosotros más nos gusta.

Para evitar involucrar la lógica de nuestras clases con la lógica de presentación particular de Visual Studio (otro IDE puede no soportar este atributo e ignorarlo por completo) podemos usar este atributo a nivel de ensamblado y crear un nuevo ensamblado con únicamente la declaración del atributo. De este modo, tendremos que especificar, además de la información a mostrar, la clase o estructura sobre la cual queremos aplicarla mediante la propiedad Target.

Para que quede claro esto último lo voy a explicar. La idea de usarlo a nivel de ensamblado es crear una nueva dll (proyecto de tipo Librería de clases). Este proyecto tiene que referenciar al ensamblado que contiene el tipo que queremos decorar. Esto significa que si queremos decorar el tipo XmlDocument, entonces vamos a tener que referenciar al ensamblado System.Xml.dll, en cambio, si queremos decorar nuestra clase Persona, vamos a tener que referenciar a la dll que genere nuestro proyecto.

Una vez dentro del nuevo proyecto buscamos el archivo AssemblyInfo (o cualquier otro archivo, simplemente me parece que éste es el lugar más apropiado para hacerlo) y agregamos algo similar a esto (yo voy a usar mi ejemplo):

   1: [assembly: DebuggerDisplayAttribute("Nombre: {Nombre, nq}, Año de nacimiento: {FechaDeNacimiento.Year}, ¿Es Rosarino?: {Ciudad == \"Rosario\" ? \"Sí\" : \"No\", nq}",
   2:                                     Target = typeof(DebuggerDisplayAttributeTest.Persona))]

Como se ve, usé la propiedad Target para especificar al tipo al que vamos a decorar.

Ahora solo resta compilar este ensamblado y copiarlo al path de visualizadores de Visual Studio (solo el ensamblado, no sus dependencias). Este path varia dependiendo la versión de Visual Studio y Windows. En el caso de Windows Vista, el path tiene la siguiente forma:

%userprofile%\Documents\Visual Studio [VERSION_VS]\Visualizers

Sobre Windows XP y 2003 (e imagino que en 2000 también) es el siguiente:

%userprofile%\My Documents\Visual Studio [VERSION_VS]\Visualizers

Una vez copiado el ensamblado reiniciamos Visual Studio y listo, ya tenemos nuestras clases decoradas sin necesidad de modificar su código.

Si prestan atención, en la carpeta de visualizadores van a encontrar un archivo llamado autoexp.cs. Si inspeccionan el archivo, van a ver que clases de .NET Framework fueron decoradas con este atributo. Son libres de modificarlo (¡no sin antes hacer un backup!) y agregarle todo lo que quieran, pero es responsabilidad de ustedes compilarlo en algún proyecto.

Nos vemos en el próximo post!

Referencias:

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in .Net 2.0, Visual Studio | Etiquetado: , , | 1 Comment »

Hacer referencia a una librería de clases desde una aplicación Silverlight

Posted by Gerardo Contijoch en febrero 10, 2009

Hoy me vi en la necesidad de utilizar una librería de clases que había creado hace un tiempo, desde una aplicación hecha en Silverlight 2.0 y descubrí que no podía hacerlo. Luego de investigar un poco me entere de que Silverlight usa una versión especial del .NET Framework, lo cual explica porque no se puede referenciar a un assembly compilado con el framework estándar.

La única solución para resolver este problema es crear una nueva librería de clases Silverlight (un nuevo tipo de proyecto que se agrega al instalar Silverlight) y hacer referencia a ella. Algunas personas sugieren, para no repetir código que ya hemos escrito, agregar links los archivos de código (*) en vez de copiar todos los archivos de nuestra librería, pero no lo sugiero debido a que como los frameworks son diferentes, el código escrito en uno puede no compilar en el otro.

En la siguiente imagen se pueden ver algunos assemblies con versión 2.0.5.0 (pertenecientes a Silverlight):

referenciassilverlight-object-browser

Estos son una versión especial de los assemblies del framework 2.0 (de ahí su numeración) y se encuentran en ‘C:\Program Files\Microsoft SDKs\Silverlight\v2.0\Reference Assemblies\’. Es importante tener en cuenta la versión y ubicación de estos assemblies ya que proyectos como los de Test no hacen referencia a estos y vamos a tener que agregarlas a mano, procurando referenciar las dlls versionadas como 2.0.5.0 y no las otras.

¿En que se diferencian los frameworks? No creo que sean tantas las diferencias entre ambos, pero me parece que son las suficientes para que no nos compile la mayoría de los proyectos con los que trabajemos, en especial si procesan xmls. Entre los assemblies modificados se encuentran System, System.Xml, System.Xml.Linq, y mscorlib. Los cambios que encontré yo en mi proyecto eran de fácil solución en su mayoría debido a que se trataban de sobrecargas de métodos que no existían en el framework de Silverlight.

¡Nos vemos en el próximo post!

(*) Para agregar un link a un archivo y no una copia del mismo en el Open file dialog que aparece cuando queremos agregar un item existente hay que seleccionar la opción Add As Link desde el menú que se despliega desde el botón Add. De este modo, estaremos referenciando al archivo original y no se creará una copia del mismo en la carpeta de nuestro proyecto.

referenciassilverlight-addasalinkPublicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Desarrollo Web, Silverlight, Visual Studio | Etiquetado: , | 1 Comment »

Personalizar la carga de DataSets tipados

Posted by Gerardo Contijoch en febrero 6, 2009

Ayer comentaba que había comenzado a trabajar con DataSets tipados por primera vez y no tardé en encontrarme con algunos problemas, principalmente debido a la falta de costumbre al trabajar con ellos. Hoy me encontré con otro problema muy molesto que tiene una solución simplísima, pero que me costó encontrar.

El método estándar para llenar las tablas de un DataSet tipado es mediante el método Fill() del TableAdapter generado dinámicamente para cada tabla. El problema con el que me encontré fue que no había una manera de llenar las tablas con datos previamente filtrados. Luego de investigar un rato encontré con la solución: simplemente hay que abrir el DataSet en el editor de esquemas y hacer click derecho sobre la tabla que queramos filtrar. A continuación elegimos Add–>Query… y veremos que se abre un asistente que nos ayudará a crear una consulta nueva que filtre los datos como nos parezca. También es posible utilizar un SP ya existente o crear uno nuevo en el momento. Cabe aclarar que si nuestra consulta depende de valores dinámicos, los mismos pueden ser provistos en forma de parámetros en la consulta dentro del asistente que se abre y el asistente generará un método con los parámetros necesarios para la consulta.

Si nuestra consulta no esta asociada a una tabla en particular, esto mismo se puede hacer sobre el propio DataSet (haciendo click derecho sobre el fondo del editor de esquemas). En este caso, los métodos generados se encontrarán en un objeto QueriesTableAdapter.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Visual Studio | Etiquetado: , , | Leave a Comment »

Actualizar el esquema de un DataSet tipado en Visual Studio

Posted by Gerardo Contijoch en febrero 5, 2009

No tengo la costumbre de trabajar con DataSets tipados principalmente porque trabajo con DataReaders o DataTables no tipados. Me gusta tener acceso a los datos y controlar lo que se hace con ellos yo mismo, sin ninguna clase que me los formatee ni organice automáticamente. Sin embargo, hoy decidí darles una oportunidad dentro de un prototipo de aplicación ya que precisaba hacer algunos INSERTs y SELECTs sobre pocas tablas y no quería perder tiempo con SPs escritos a mano.

La verdad es que los DataSets tipados son ideales para prototipos simples y me vinieron muy bien, pero me encontré rápidamente con una limitación: no hay una manera sencilla de modificar su estructura para reflejar los cambios en la estructura de la DB (algo relativamente común en las primeras etapas de desarrollo). En realidad si la hay, pero a lo que me refiero es a que esperaba alguna opción en algún lugar del estilo ‘Update DataSet Schema’ o ‘Sync DataSet Schema’.

Buscando un poco encontré dos soluciones que parecen ser las más adecuadas para estos casos. La primera consiste simplemente en borrar las tablas del DataSet y volver a agregarlas a mano desde el Server Explorer, mientras que la segunda consiste en modificar las consultas a mano con las cuales se generaron las tablas del DataSet (seleccionando la opción Configure del menú contextual que aparece al hacer click derecho en la tabla dentro del editor de esquemas del DataSet).

El problema de ambas soluciones esta en que al realizar la actualización uno pierde todos los cambios que pudo haberle hecho a los DataSets y DataTables. Para arreglar esto, acá sugieren transformar las clases generadas por Visual Studio en clases parciales (agregando ‘partial’ a la definición de la clase) y agregar las modificaciones a esas clases (ahora parciales) dentro de otros archivos, diferentes de los que genera Visual Studio de manera automática. Así, cuando se regeneren los DataSets nuestros cambios no son eliminados. No tengo a mano una copia de Visual Studio 2005 para verificarlo, pero la versión 2008 ya genera los DataSets y DataTables como clases parciales por lo que nos ahorraríamos un paso en este caso.

Esperemos que en una próxima versión de Visual Studio haya alguna manera un poco mas ‘user friendly’ de hacer esto.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Visual Studio | Etiquetado: , , | 3 Comments »

Code snippet para propiedades con respaldo en el ViewState

Posted by Gerardo Contijoch en enero 8, 2009

Desde la versión 2005, Visual Studio tiene soporte para code snippets. Los code snippets son templates para pequeñas porciones de código (normalmente usado con mucha frecuencia) que son escritas automáticamente mediante el uso de un keyword. Visual Studio trae unos cuantos code snippets, pero uno puede crear el suyo si lo desea.

Uno de los code snippets que más uso es prop, que genera el código de una propiedad, pero no siempre es cómodo de usar ya que supone que el valor de la propiedad se guarda en un campo de la clase donde se defina la misma, pero cuando estamos escribiendo páginas o controles web, las propiedades normalmente se respaldan en el ViewState y no en un campo privado. Es por ello que cree este code snippet para la generación de propiedades con respaldo en el ViewState. Se invoca con el keyword propviewstate.

Aca se ve como queda una propiedad generada con el snippet:

   1: public int Propiedad {
   2:     get {
   3:         return  (int)ViewState["propiedad"];
   4:     }
   5:     set {
   6:         ViewState["propiedad"] = value;
   7:     }
   8: }

Espero que les sea útil.

Pueden bajar el code snippet desde aquí.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Visual Studio | Etiquetado: | Leave a Comment »

Acceder directamente al test que falló en MSTest

Posted by Gerardo Contijoch en diciembre 16, 2008

Una de las cosas que más me molesta de ejecutar los tests dentro de Visual Studio (MSTest), es que para llegar al código de un test que falló, tengo que acceder a la ventana de resultados del test, y recién ahí hacer click en el link al archivo (que nos lleva directamente a la línea que falló).

Afortundamente, Simone Chiaretta encontró la solución al problema, ¡y la encontró dentro del propio Visual Studio!

Les dejo el link.

¡Nos vemos en el próximo post!

Publicado originalmente en https://gerardocontijoch.wordpress.com.

Posted in Testing, Visual Studio | Etiquetado: , , , | Leave a Comment »