Excluir el código generado de la cobertura de código

Una de las características que nos proporciona Visual Studio Team System es la Cobertura de código, que nos ayuda a saber que cantidad de código funcional cubren nuestras pruebas unitarias. El volumen de código que cubren nuestras pruebas es representado de forma porcentual y como cabe esperar lo ideal es mantener este porcentaje lo más alto posible, pero muchas veces debido al código que genera Visual Studio en algunas ocasiones, este porcentaje nunca alcanza el 100%.

Cubrir el 100% del código con nuestras pruebas unitarias es una tarea muy difícil pero si además tenemos código generado, que no debemos probar, y que también es contabilizado, podemos perder la perspectiva del nivel de cobertura que estamos alcanzando con nuestras pruebas. Lo ideal sería, al igual que se puede hacer con las reglas de Análisis estático de código, excluir el código generado del informe de cobertura de código, ¿no?.

Pues bien, a pesar de que no es una funcionalidad tal cual, es más bien un Workaround, existe la forma de excluir el código generado para que no contabilice cuando se esta realizando la cobertura de código, incluso hacer que el código generado no aparezca en el reporte de cobertura de código. El Tip/Trick/Hack o como queráis llamarlo surge a raíz de como es realizada la medición de la cobertura, que se basa en el Debugger para saber porque líneas de código se ha pasado, con lo que si conseguimos que el Debugger no pase por el código generado evitamos que ese código sea contabilizado, pero voy a dejar ya de dar tanto detalle y vamos a ver un poco de código.

Partiendo de un proyecto de librería de clases recién creado, tenemos una clase con el código que sigue:


using
System; using System.Collections.Generic; namespace Managers { public class ManagerClass { public List<Book> GetBooksByName(string bookName) { return null; } } }

Este código no hace absolutamente nada, con lo que si generamos un test unitario con el código que se muestra a continuación deberíamos obtener una cobertura del 100%, ¿no?
 

[TestMethod]
public void GetBooksByNameExpectedNull()
{
    // Arrange
    ManagerClass target = new ManagerClass();

    // Act
    List<Book> val1 = target.GetBooksByName(String.Empty);

    // Assert
    Assert.IsNull(val1);
}

Sin embargo tras ejecutar la prueba unitaria, obtenemos a nivel de ensamblado un 28,57% de cobertura, lo cual resulta un poco extraño. Si miramos el reporte de la cobertura de código vemos que el espacio de nombres Managers si tiene una cobertura del 100%, pero tenemos un tal Managers.Properties que representa una parte importante de nuestro código y que no esta probado, lo que hace que la media porcentual caiga en picado.

ExcluirCoberturaDeCodigo-1

La clase Settings dentro de Managers.Properties es código generado por Visual Studio y en este ejemplo representa un porcentaje muy alto de todo el código que hay en el proyecto, lo que hace que al no estar probado, nuestro índice de cobertura sea muy bajo. Para excluir este código de la medición lo único que tenemos que hacer es abrir el fichero Settings.cs y añadir, en este caso a nivel de clase, el atributo DebbugerNonUserCode o DebuggerHidden, con lo que el depurador no pasará por ese código y no se incluirá en el reporte.

using System.Diagnostics;

namespace Managers.Properties 
{    
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(
        "Microsoft.VisualStudio.Editors.SettingsDesigner." +
        "SettingsSingleFileGenerator", "9.0.0.0")]
    [DebuggerNonUserCode] /* Atributo para la exclusion */

    internal sealed partial class Settings 
        : global::System.Configuration.ApplicationSettingsBase 
    {
        private static Settings defaultInstance = 
            ((Settings)(global::System.Configuration.
            ApplicationSettingsBase.Synchronized(new Settings())));
        
        public static Settings Default 
        {
            get 
            {
                return defaultInstance;
            }
        }
    }
}

Como podéis comprobar en la siguiente imagen ya no hay rastro de Managers.Properties y nuestro porcentaje a nivel de ensamblado ya es real.

ExcluirCoberturaDeCodigo-2

Este es un ejemplo muy básico, y la proporción entre código funcional y código generado hace que no probar el código generado tenga mucho impacto, pero muestra como conseguir el objetivo del post perfectamente. Si lo probáis en un proyecto en el que tengais DataSets, o referencias a servicios Web podréis observar el resultado real.

Por ultimo, solo comentar que si decidimos usar este método para obtener una cobertura de código real, debemos tener presente que el código que este marcado con este atributo no cuenta en ningún aspecto para el depurador, con lo que si necesitamos poner un punto de interrupción en este código, éste será obviado por completo. Además si Visual Studio necesitara regenerar el código, por ejemplo una referencia a un servicio Web o un DataSet, como es lógico los atributos se borrarán y el código volverá a aparecer en el reporte de cobertura.

teamsystem.es
Este post es contenido cross-posting desde www.teamsystem.es y estoy muy interesado en tu opinión. ¿Porqué no te acercas y dejas un comentario para que todos podamos aprender?

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *