Test Unitario y ficheros. Adiós DeploymentItem

Trabajar en un proyecto de test unitario que requiera de ficheros es un suplicio, además de tremendamente engorroso.

Si nos remitimos a la documentación de Microsoft, http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.deploymentitemattribute.aspx , debemos decorar nuestro método de test con el atributo DeploymentItem, y configurar la información de la ruta de entrada y salida del fichero. Este proceso es necesario ya que los test se ejecutan en el contexto de programa host (vstest.executionengine.exe)

Pero realmente esto no es suficiente, y para que realmente funcione debemos establecer varias propiedades a nivel del archivo (como CopyToOutput true) y configurar el test para que admita el deployment de archivos. Cuando solo necesitamos uno o dos ficheros, puede pasar, pero cuando el número de test que requieren de ficheros aumenta se convierte en un autentico calvario.

Por si fuera poco, debemos incluir el código para leer el fichero en nuestro test, con lo que estamos añadiendo complejidad y posibles puntos de error (un test podría fallar al leer el fichero, y no en la condición de prueba).

Para rematar la faena, la complejidad aumenta si ejecutamos nuestros test en un servidor de integración continua como parte de una Build. Si buscamos un poco el panorama es desalentador …

image

Afortunadamente existe un método muy sencillo que nos evita todo este jaleo, que es extremadamente simple y que además os lo voy a explicar ahora mismo! :-)

Es tan fácil como usar archivos, de recursos. Los archivos de recursos permiten incluir archivos como parte de sus componentes. Los ficheros adjuntos se almacenan fuera del archivo de recursos – lo que nos permite modificarlos de forma fácil desde el propio VisualStudio, y es el propio framework quien se encarga del resto. Además cuando accedamos al fichero lo haremos directamente a través de propiedades sin necesidad de tener que andar leyendolo.

Vamos a verlo con un sencillo ejemplo, Imaginemos un programa en el que tenemos la siguiente clase:

public class Persona    
{
    public static Persona Load(string xmlString) {
        var document = XDocument.Parse(xmlString);            
            
        var persona = new Persona();
        persona.Id = Guid.Parse(document.Root.Element("Id").Value);
        persona.Name = document.Root.Element("Name").Value;
        persona.SurName = document.Root.Element("SurName").Value;
        return persona;
    }

    public Persona()
    {
        this.Id = Guid.NewGuid();
    }

    public Guid Id { get; protected set; }

    public string Name { get; set; }

    public string SurName { get; set; }
           
}

La clase es muy sencilla, y solo tiene una serie de propiedades básicas. Le hemos añadido un método estático Load que nos permite instanciar la clase desde un string – ya sé que no es el mejor diseño, pero necesitaba un ejemplo válido para el articulo!!

Ahora, en nuestro proyecto de test añadimos un fichero Personal.xml con el siguiente contenido:

<?xml version="1.0" encoding="utf-8" ?>
<persona>
    <Id>316F0DFC-CD03-458F-85BE-389B7E0E2D0C</Id>
    <Name>www.devjoker.com</Name>
    <SurName>Unit Test y archivos</SurName>
</persona>

Este fichero nos va a servir como entrada para el test del método Load de la clase.

Ahora tenemos que añadir un archivo de recursos a nuestro proyecto de test, al que llamamos PersonaTestResources.resx. En un archivo de recursos podemos añadir el fichero simplemente modificando la vista a “Files” desde el combo de la esquina superior izquierda …

image

Y añadir el archivo Persona.xml al fichero de recursos arrastrandolo al interior de la vista de diseño.

Snap 2013-10-10 at 00.30.21

Y por fin el test:

using Files = TestSample.Test.Resources.PersonaTestResources;
[TestClass]
public class PersonaTest
{
    [TestMethod]        
    public void PersonaLoadTest() { 
        // arrange
            
        // act
        var persona = Persona.Load(Files.Persona);

        // assert
        Assert.AreEqual(persona.Id.ToString(), "316F0DFC-CD03-458F-85BE-389B7E0E2D0C",true);
        Assert.AreEqual(persona.Name, "www.devjoker.com");
        Assert.AreEqual(persona.SurName, "Unit Test y archivos");
    }

}

Fijaros que hemos creado un alias Files para nuestro fichero de recursos - using Files = TestSample.Test.Resources.PersonaTestResources; - , y podemos acceder al contenido del fichero simplemente accediendo a la propiedad de Persona  (dado que nuestro archivo se llamaba Persona.xml )

Cuando el test se ejecuta podemos ver que dicha propiedad tiene el contenido del fichero:

image

Lo mejor de todo es que además nuestro test se ejecuta sin problemas en un servidor de builds.

image

Este método es mucho más sencillo y fácil de mantener que el tradicional con el atributo DeploymentItem, asi que adios DeploymentItem … adios!

Saludos y hasta la próxima!.

Pedro  Herrarte  Sánchez
Test Unitario y ficheros. Adiós DeploymentItem
Pedro Herrarte Sánchez

Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación. Posee mas de diez años de experiencia trabajando para las principales empresas de España. Es especialista en tecnologías .NET, entornos Web (ASP.NET, ASP.NET MVC,jQuery, HTML5), bases de datos (SQL Server y ORACLE) e integración de sistemas. Es experto en desarrollo (C#, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE). Pedro es MCP y MAP 2012, es fundador, diseñador y programador de www.devjoker.com..
Fecha de alta:10/10/2013
Última actualizacion:10/10/2013
Visitas totales:10440
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com