Buscar este blog

martes, 31 de mayo de 2011

Nunit - modelo basado en restricciones (constraint)

Desde la versión 2.4 de Nunit se tiene una nueva sintaxis llamada constraint-model, que tiene como mayor ventaja una claridad mayor en la lectura del código (por supuesto esto mas cierto si hablas ingles).
Esta nueva sintaxis es tan fácil de usar como la anterior basada en afirmaciones (assert) y supuestamente es más poderosa, aunque según los autores de Nunit no se recomienda la una o la otra preferentemente, en realidad es más cuestión de gusto, aunque puede ser preferible el uso de la nueva sintaxis al usar junto con otros frameworks,
En fin les dejo un ejemplo básico del tema:


   1:  [TestFixture]
   2:  public class UserTestConstraint {
   3:      [Test]
   4:      public void ConstructorTest() {
   5:          User user = new User("Pedro", "secreto");
   6:          Assert.That(user.Name, Is.EqualTo("Pedro"));
   7:          Assert.That(user.Password, Is.EqualTo("secreto"));
   8:          Assert.That(user.Password, Is.Not.EqualTo("secreto1"));
   9:      }
  10:  }

Para aprender más acerca de las pruebas unitarias con .Net Framework visita:
Lista de artículos acerca de pruebas unitarias con .Net Framework

lunes, 23 de mayo de 2011

Tips y errores del control WebBrowser (Windows.Forms)

Te manda una excepción FileNotFoundException al usar la propiedad DocumentText, y estas seguro de que el documento ya se termino de cargar correctamente.

Este es un bug del control WebBrowser y al parecer Microsoft no tiene pensado arreglarlo, afortunadamente hay otras formas de obtener el código fuente de la pagina sin tener este error para ello debes usar la propiedad DomDocument del WebBrowser y convertirla a la clase HTMLDocument incluida en el ensamblado mshtml por lo que debes agregar a tu proyecto una referencia a ese ensamblado, con este objeto podemos usar la propiedad documentElement e innerHTML, en ella tenemos el código que buscamos.
para mayor claridad aquí esta el ejemplo:



   1:  string content = ((mshtml.HTMLDocument)browser.Document.DomDocument).documentElement.innerHTML;

lunes, 16 de mayo de 2011

Métodos de extensión

Los métodos de extensión son una forma muy sencilla y conveniente de agregar funcionalidad a código existente en .Net Framework se usan básicamente cuando necesitamos agregar funcionalidad a un código que no podemos cambiar, son muy usados en la librería de clases base, donde se utilizan por ejemplo para implementar Linq.
La forma de crear un método de extensión es crear una clase estática en la cual los métodos de extensión tienen como característica que el primer argumento de la función esta precedido por el modificador this y este parámetro es el que indica el tipo de datos que extiende el método.
Por ejemplo para extender el tipo string[]:

   1:  static class StringExtension {
   2:      public static void PrintAll(this string[] strings) {
   3:          foreach(string i in strings) {
   4:              Console.WriteLine(i);
   5:          }
   6:      }
   7:  }
Y podemos usar el método como si estuviera incluido en el tipo string[]:

   1:  static void Main(string[] args) {
   2:      string[] strings = new string[] { "hola", "mundo", "con", "extensiones"};
   3:      strings.PrintAll();
   4:      Console.ReadLine();
   5:  }

Cabe mencionar que no esta recomendado usar mucho los métodos de extensión, si es posible añadir los métodos en la clase que los necesita es mejor incluirlos directamente.

lunes, 9 de mayo de 2011

Usando XPath en .Net Framework

XPath es una tecnología que nos permite encontrar información en un documento XML, .Net Framework tiene integrada un API muy sencilla de usar que nos permite usar XPath en nuestras aplicaciones.
Aquí les muestro un ejemplo sencillo del uso de esta API.
Las clases principales son XPathDocument que nos permite cargar el documento a utilizar, XPathNavigator que nos permite realizar las consultas deseadas y XPathIterator que nos trae los resultados de la consulta.
También existe la interface IXPathNavigable que al ser implementada nos permite usar otro tipo de fuentes de datos que no sean XML.
En este ejemplo no explico detalles sobre XPath puesto que este es un blog de .Net y no de XML pero si quieres saber mas acerca de esta tecnología puedes visitar el tutorial de XPath en http://www.w3schools.com/XPath/default.asp.
Consideremos el siguiente xml:

   1:  <?xml version="1.0"?>
   2:  <Peliculas>
   3:    <Pelicula>
   4:      <Titulo>Mazinger</Titulo>
   5:      <Director>Jackie chan</Director>
   6:      <Estrenado>1975-03-19T00:00:00</Estrenado>
   7:      <Actores>
   8:        <Actor>
   9:          <Nombre>John Wayne</Nombre>
  10:          <Nacimiento>1915-10-23T00:00:00</Nacimiento>
  11:          <Roles>
  12:            <Rol>
  13:              <NombrePelicula>Mazinger</NombrePelicula>
  14:              <NombreRol>Estrella</NombreRol>
  15:            </Rol>
  16:          </Roles>
  17:        </Actor>
  18:      </Actores>
  19:    </Pelicula>
  20:    <Pelicula>
  21:      <Titulo>Terminator</Titulo>
  22:      <Director>James Cameron</Director>
  23:      <Estrenado>1985-02-14T00:00:00</Estrenado>
  24:      <Actores>
  25:        <Actor>
  26:          <Nombre>Arnold</Nombre>
  27:          <Nacimiento>1953-10-11T00:00:00</Nacimiento>
  28:          <Roles>
  29:            <Rol>
  30:              <NombrePelicula>Terminator</NombrePelicula>
  31:              <NombreRol>Protagonista</NombreRol>
  32:            </Rol>
  33:            <Rol>
  34:              <NombrePelicula>Terminator</NombrePelicula>
  35:              <NombreRol>Enemigo</NombreRol>
  36:            </Rol>
  37:          </Roles>
  38:        </Actor>
  39:        <Actor>
  40:          <Nombre>Linda Hamilton</Nombre>
  41:          <Nacimiento>1972-08-12T00:00:00</Nacimiento>
  42:          <Roles>
  43:            <Rol>
  44:              <NombrePelicula>Terminator</NombrePelicula>
  45:              <NombreRol>Protagonista</NombreRol>
  46:            </Rol>
  47:            <Rol>
  48:              <NombrePelicula>Terminator</NombrePelicula>
  49:              <NombreRol>Perseguida</NombreRol>
  50:            </Rol>
  51:          </Roles>
  52:        </Actor>
  53:      </Actores>
  54:    </Pelicula>
  55:  </Peliculas>
Para encontrar todos los actores usaríamos este código:

   1:  XPathDocument peliculas = new XPathDocument("peliculas.bak.xml");
   2:  XPathNavigator pelNav = peliculas.CreateNavigator();
   3:  XPathNodeIterator actoresIt = pelNav.Select("//Actor");
   4:  Console.WriteLine("Todos los actores");
   5:  while(actoresIt.MoveNext()) {
   6:      Console.WriteLine("Nombre: " + actoresIt.Current.SelectSingleNode("Nombre").Value);
   7:      Console.WriteLine("Fecha de nacimiento: " + actoresIt.Current.SelectSingleNode("Nacimiento").Value);
   8:  }
Cabe mencionar que el API es de solo lectura por lo que podemos consultar información pero no modificarla.

lunes, 18 de abril de 2011

Usar o no DBLinq

La respuesta rápida: no lo uses.

DBLinq es un proyecto muy interesante nos permite accesar a diferentes tipos de bases de datos de la misma forma en accesamos a SQL Server con Linq a SQL Server de .Net Framework, tiene una herramienta (DBMetal.exe) que nos crea un conjunto de clases equivalente a las que se crean para Linq a SQL con Visual Studio o sqlmetal.exe.
Para mi lo mejor que tiene DBLinq es que solo cambiando la cadena de conexión y en ocasiones cambiando un poco el código generado por DBMetal.exe podemos cambiar de tipo de servidor (por ejemplo de SQL Server a MySql sin modificar el programa en lo más mínimo, pues la cadena de conexión se puede cambiar por ejemplo en el app.config o web.config, por lo que si escribes tu programa usando DBLinq tienes soporte instantaneo para todas las bases de datos que soporta este framework y las que soporte en el futuro.
Entonces por que recomiendo que no lo uses?
Aquí vienen las malas noticias, el proyecto tiene errores que lo hacen simplemente inutilizable, simplemente DBMetal.exe no puede manejar cualquier base de datos, basta que tengamos alguna asociación de tablas que no le guste al programa y nos mandara un error mientras que sqlmetal.exe puede manejar la misma base de datos sin problemas.
Aun así con un poco de trabajo se puede crear las clases necesarias y usar DBLinq en cualquier base de datos, sin embargo nos topamos con el siguiente problema: los querys regresan datos incorrectos.
Así es, lo corrobore con Linq a SQL, Linq a objetos y otros frameworks e indudablemente DBLinq regresa datos incorrectos, solo funciona para las bases de datos y querys mas triviales.

Más aun el proyecto a abril del 2011 parece abandonado y no ha habido cambios en el código durante más de un año.
La buena noticia es que el proyecto ahora se incluye como parte de Mono y los desarrolladores de Mono arreglan los errores que se reportan con mucha rapidez, yo pretendo trabajar un poco con ellos ya que en realidad el proyecto tiene un potencial muy grande y ya me gustaría estarlo usando en todos mis proyectos actuales.

En conclusión: De momento no cambies todavía a DBLinq pero mantén un ojo en el proyecto debido a su potencial.

Para aprender más sobre Linq visita:
Lista de artículos acerca de Linq

jueves, 14 de abril de 2011

LibCurlNet: alternativa a WebRequest

Curl es una librería escrita en C para utilizar diversos protocolos de red y LibCurlNet es un wrapper de la librería para usarla en .Net Framework es una buena alternativa para las clases que derivan de WebRequest sobre todo si quieres usar un protocolo no so soportado por WebRequest, los protocolos que soporta esta API son HTTP, HTTPS, FTP, FTPS, SCP, SFTP, TFTP, TELNET, LDAP, DICT y FILE.
Además WebRequest a veces falla sin ninguna razón aparente y también en estos casos podrías usar Curl como una alternativa.
Se puede descargar desde el sitio de LibCurlNet.
LibCurlNet nos presenta dos formas de uso principalmente la llamada easy y la llamada multi, En esta entrada hablare de la interfaz easy con HTTP que como su nombre nos indica es muy sencilla de usar, un poco más complicado que WebRequest pero no demasiado.
El API se accede en el espacio de nombres SeasideResearch.LibCurlNet y lo primero que hay que hacer es inicializar el API con la llamada al método Curl.GlobalInit y al terminar de usar el API se usa necesariamente el método Curl.GlobalCleanup, es muy importante hacer estas llamadas solo una vez en toda la vida del programa de lo contrario obtendremos errores.
Ahora pasamos a usar la clase Easy para bajar un archivo html con la operación GET (también se soporta POST y PUT).
El wrapper usa casi directamente el API en C y no esta muy orientada a objetos pero aún así resulta muy sencilla de utilizar en general usamos la funcíon SetOpt del objeto Easy para establecer las opciones de transferencia incluyendo la URL, proxy, headers, seguimiento de redirecciones, etc y utilizamos la llamada a Perform para obtener el resultado, aquí es donde esta la mayor diferencia entre WebRequest y CURL, la llamada a Perform por si misma lleva a cabo toda la transferencia, pero lo único que nos da como resultado es código que nos indica si se realizo la transferencia o no y la causa del fallo, para obtener los datos tenemos que escribir una función que usara el objeto Easy (como un delegado) para transmitirnos los datos en forma de un arreglo de bytes y es nuestra responsabilidad decidir que hacemos con esos bytes.
También podemos obtener el código http de la respuesta con la función GetInfo.
Si queremos remplazar o eliminar los headers que manda Curl automáticamente  podemos agregar estos headers con o sin valor y se eliminaran o remplazaran en la transferencia.
El mismo objeto Easy se puede usar cuantas veces queramos para diferentes URLs y el mismo tratara de reutilizar la misma conexión a menos que se indique lo contrario, cuando se termine de usar debemos llamar a easy.Cleanup antes de la llamada a Curl.GlobalCleanup de lo contrario se provocara un error.
A continuación les dejo el ejemplo en C# que explica el proceso por si mismo.


static void Main(string[] args) {
    Curl.GlobalInit((int)CURLinitFlag.CURL_GLOBAL_ALL);
    Easy easy = new Easy();
    easy.SetOpt(CURLoption.CURLOPT_URL, "http://localhost/");
    easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true);
    easy.SetOpt(CURLoption.CURLOPT_CONNECTTIMEOUT, 10);
    easy.SetOpt(CURLoption.CURLOPT_TIMEOUT, 90);
    easy.SetOpt(CURLoption.CURLOPT_PROXY, "http://localhost:8080");
    easy.SetOpt(CURLoption.CURLOPT_USERAGENT, "My Download");
    easy.SetOpt(CURLoption.CURLOPT_ENCODING, "gzip,deflate");
    easy.SetOpt(CURLoption.CURLOPT_FAILONERROR, true);
    Slist headers = new Slist();
    headers.Append("Pragma:");
    headers.Append("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7");
    easy.SetOpt(CURLoption.CURLOPT_HTTPHEADER, headers);
    List<byte> buffer = new List<byte>();
    Easy.WriteFunction writer = new Easy.WriteFunction(OnWriteData);
    easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, writer);
    easy.SetOpt(CURLoption.CURLOPT_WRITEDATA, buffer);
    easy.Perform();
    int code = 0;
    easy.GetInfo(CURLINFO.CURLINFO_RESPONSE_CODE, ref code);
    easy.Cleanup();
    Curl.GlobalCleanup();
    string content = "";
    using(MemoryStream mStream = new MemoryStream(buffer.ToArray())) {
        using(StreamReader reader
        = new StreamReader(mStream, Encoding.UTF8)) {
            content = reader.ReadToEnd();
        }
    }
    Console.WriteLine("Status: " + code.ToString());
    Console.WriteLine(content);
    Console.WriteLine("leido");
    Console.ReadLine();
 
}
private static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb
, Object extractData) {
    List<byte> buffer = (List<byte>)extractData;
    buffer.AddRange(buf);
    return size * nmemb;
}

miércoles, 30 de marzo de 2011

Validando esquemas xml con .Net Framework

Uno de los objetivos de los esquemas xml (archivos .xsd) es poder validar que un archivo xml cumpla con las reglas que se especifican en el esquema, .Net tiene el API necesaria para realizar esta validación y es muy sencillo.
Consideremos el siguiente esquema:

   1:  <?xml version="1.0" standalone="yes"?>
   2:  <xs:schema id="Peliculas"
   3:                       targetNamespace="ProbadorConsola"
   4:                       xmlns:xs="http://www.w3.org/2001/XMLSchema"
   5:                       xmlns="ProbadorConsola"
   6:                       elementFormDefault="qualified">
   7:    <xs:element name="Peliculas">
   8:      <xs:complexType>
   9:        <xs:choice minOccurs="0" maxOccurs="unbounded">
  10:          <xs:element name="Pelicula">
  11:            <xs:complexType>
  12:              <xs:sequence>
  13:                <xs:element name="Titulo" type="xs:string" minOccurs="0" />
  14:                <xs:element name="Director" type="xs:string" minOccurs="0" />
  15:                <xs:element name="Estrenado" type="xs:string" minOccurs="0" />
  16:                <xs:element name="Actores" minOccurs="0" maxOccurs="unbounded">
  17:                  <xs:complexType>
  18:                    <xs:sequence>
  19:                      <xs:element name="Actor" minOccurs="0" maxOccurs="unbounded">
  20:                        <xs:complexType>
  21:                          <xs:sequence>
  22:                            <xs:element name="Nombre" type="xs:string" minOccurs="0" />
  23:                            <xs:element name="Nacimiento" type="xs:string" minOccurs="0" />
  24:                            <xs:element name="Roles" minOccurs="0" maxOccurs="unbounded">
  25:                              <xs:complexType>
  26:                                <xs:sequence>
  27:                                  <xs:element name="Rol" minOccurs="0" maxOccurs="unbounded">
  28:                                    <xs:complexType>
  29:                                      <xs:sequence>
  30:                                        <xs:element name="NombrePelicula" type="xs:string" minOccurs="0" />
  31:                                        <xs:element name="NombreRol" type="xs:string" minOccurs="0" />
  32:                                      </xs:sequence>
  33:                                    </xs:complexType>
  34:                                  </xs:element>
  35:                                </xs:sequence>
  36:                              </xs:complexType>
  37:                            </xs:element>
  38:                          </xs:sequence>
  39:                        </xs:complexType>
  40:                      </xs:element>
  41:                    </xs:sequence>
  42:                  </xs:complexType>
  43:                </xs:element>
  44:              </xs:sequence>
  45:            </xs:complexType>
  46:          </xs:element>
  47:        </xs:choice>
  48:      </xs:complexType>
  49:    </xs:element>
  50:  </xs:schema>

Y el contenido xml que queremos validar:

   1:  <Peliculas xmlns="ProbadorConsola">
   2:      <Pelicula>
   3:      <Titulo>Mazinger</Titulo>
   4:      <Director>Jackie Chan</Director>
   5:      <Estrenado>1975-03-19T00:00:00</Estrenado>
   6:      <Actores>
   7:        <Actor>
   8:          <Nombre>John Wayne</Nombre>
   9:          <Nacimiento>1915-10-23T00:00:00</Nacimiento>
  10:          <Roles>
  11:            <Rol>
  12:              <NombrePelicula>Mazinger</NombrePelicula>
  13:              <NombreRol>Estrella</NombreRol>
  14:            </Rol>
  15:          </Roles>
  16:        </Actor>
  17:      </Actores>
  18:    </Pelicula>
  19:  </Peliculas>

Lo primero que debemos hacer es validar que el documento contenga el espacio de nombres del esquema si no lo contiene la validación fallara diciéndonos que el documento es valido aun cuando en realidad no cumpla las reglas del esquema.
El código para encontrar el espacio de nombres (c#):

   1:  XDocument peliculas = XDocument.Load("peliculas.xml");
   2:  XPathNavigator nav = peliculas.CreateNavigator();
   3:  nav.MoveToFollowing(XPathNodeType.Element);
   4:  IDictionary<string, string> ns
   5:      = nav.GetNamespacesInScope(XmlNamespaceScope.All);
   6:  bool schemaFound = false;
   7:  foreach(KeyValuePair<string, string> namespaces in ns) {
   8:      if(namespaces.Value.CompareTo("ProbadorConsola") == 0)
   9:          schemaFound = true;
  10:  }
  11:  if(!schemaFound) {
  12:      Console.WriteLine("Esquema no encontrado");
  13:      return;
  14:  }
Ahora si podemos proceder a validar el documento con el esquema que puede estar en un archivo local o en Internet:

   1:  XmlSchemaSet schema = new XmlSchemaSet();
   2:  schema.Add("ProbadorConsola", "peliculas.xsd");
   3:  peliculas.Validate(schema, null);
   4:  Console.WriteLine("Esquema valido");
   5:  Console.ReadLine();

Hacemos notar que si utilizas Linq a XSD todo esto lo hace en una sola linea de código al cargar el documento.

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework

sábado, 26 de marzo de 2011

Instalar Linq a XSD

En una entrada anterior ya vimos lo que se puede hacer con Linq a XSD pero dejamos el proceso de instalación pendiente ya que es un poco complicado y merece una entrada independiente.
Linq a XSD es muy útil y no deberíamos detenernos en su uso debido a las pocas complicaciones que tiene su instalación sobre todo tomando en cuenta que es un proyecto de Microsoft y probablemente se incluya en versiones futuras de Visual Studio.
Bueno lo primero es descargarlo desde el proyecto de Linq a XSD en Codeplex y colocar los archivos descargados en una carpeta preferentemente dentro de la carpeta de nuestra solución, en nuestro ejemplo se colocara en la carpeta Components\LinqToXsd\bin en la raíz de nuestra solución y añadimos los archivos en una carpeta de solución solo para recordarnos donde están y no es un paso obligatorio.
Ahora abrimos las propiedades del proyecto en que vamos a usarlo y en la pestaña Build Events en el recuadro Pre-build event command line colocamos el siguiente texto:

SET LINQTOXSDBINDIR=$(SolutionDir)Components\LinqToXsd\bin

Cuidando que la ruta apunte a donde pusimos los archivos.


Ahora necesitamos modificar el archivo csproj de la solución (Linq a XSD solo funciona en C-Sharp, pero puedes hacer una DLL que después utilizaras en VB.Net), para esto descargamos la solución, en el explorador de la solución escogemos el proyecto que estamos usando, click derecho y Unload Project, click derecho y Edit proyecto.csproj.
Vamos al final del archivo y después del cierre del último elemento <propertygroup> ponemos este código:

   1:  <PropertyGroup>
   2:      <LinqToXsdBinDir Condition="'$(LinqToXsdBinDir)' == ''">$(SolutionDir)Components\LinqToXsd\bin</LinqToXsdBinDir>
   3:  </PropertyGroup>

Nótese que al pegar el código Visual Studio lo formatea poniéndole lineas nuevas alrededor de la ruta, debemos modificar esto de tal forma que la quede igual que en el código de ejemplo de lo contrario tendremos errores. A continuación muestro la forma en que NO debe quedar la modificación

   1:  <PropertyGroup>
   2:      <LinqToXsdBinDir Condition="'$(LinqToXsdBinDir)' == ''">
   3:          $(SolutionDir)Components\LinqToXsd\bin
   4:      </LinqToXsdBinDir>
   5:  </PropertyGroup>

Falta introducir otro código en el mismo archivo, también al final del archivo después de el cierre del último elemento <import> colocamos el siguiente código:

   1:  <Import Project="$(LinqToXsdBinDir)\LinqToXsd.targets" />

Listo recargamos la solución y al archivo .xsd para el que queremos crear las clases le cambiamos el Build Action a LinqToXsdSchema compilamos y se nos generan las clases que necesitamos, es necesario notar que las clases se encuentran en el espacio de nombres indicado en el atributo targetNamespace del esquema xml (.xsd) y no en el de nuestro proyecto por lo que debemos buscar las clases en ese espacio de nombres.

Para aprender más sobre Linq visita:
Lista de artículos acerca de Linq

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework

viernes, 18 de marzo de 2011

Cobertura de código (Code Coverage) con pruebas unitarias de Visual Studio

Una de las funciones que tiene los proyectos de pruebas de Visual Studio es la Cobertura de Código o Code Coverage en ingles, esta función nos permite saber que porcentaje del código de nuestro proyecto estamos probando lo cual es muy importante pues puede haber errores en el código que no estamos probando y esta función nos da una idea de que pruebas nos faltan por escribir.

Para habilitar la cobertura de código previo requisito es que tengamos una versión de Visual Studio que tenga soporte para proyectos de prueba, al crear nuestro proyecto de prueba Visual Studio crea automáticamente un archivo llamado LocalTestRun.testrunconfig en una carperta Elementos de la solución (Solution Items) directamente bajo la solución para habilitar la cobertura de código hacemos doble click en este archivo y nos aparecerá la ventana de configuración de las pruebas en esta ventana escogemos la sección Cobertura de Código y nos aparece una lista con las dll's y ejecutables que produce nuestra solución debemos marcar los elementos para los que queremos habilitar la cobertura de código aplicamos los cambios cerramos y listo ya tenemos habilitada la cobertura de código en nuestras pruebas.


Para obtener los resultados ejecutamos las pruebas que queremos analizar y abrimos el panel Resultado de Cobertura de Código (Code Coverage Results) aquí vemos una lista que nos muestra detalle los porcentajes de código que estamos probando pudiendo expandir la lista hasta saber exactamente que parte del código se probo en que porcentaje.


En la imagen podemos ver que solo se probo el 4 por ciento del código con lo cual sabemos que nos falta mucho por probar, por supuesto es un ejemplo solo demostrativo.

Para aprender más acerca de las pruebas unitarias con .Net Framework visita:
Lista de artículos acerca de pruebas unitarias con .Net Framework

miércoles, 16 de marzo de 2011

Integrar NUnit a Visual Studio

Hay varias formas de integrar NUnit a Visual Studio, aquí mostrare la más sencilla y la que me parece la más conveniente.
Siguiendo las instrucciones del sitio de NUnit agregamos una herramienta personalizada a Visual Studio y le agregamos los parámetros necesarios para ejecutar NUnit en el proyecto actual estos datos son:

Titulo: NUnit
Comando: C:\Program Files\NUnit 2.5.1\bin\net-2.0\nunit.exe
ajustando la ruta a donde tenemos instalado NUnit
Argumentos: $(ProjectDir)$(ProjectFileName)
Directorio Inicial: $(ProjectDir)bin/Debug/



Eso es todo seleccionamos en el editor un archivo que este en un proyecto de pruebas NUnit y en el menú de herramientas seleccionamos NUnit y se abrira NUnit usando el proyecto de pruebas seleccionado, nótese que tiene que estar abierto y activo en el editor algún archivo que pertenezca a un proyecto de pruebas de NUnit de lo contrario nos marcara un error.

La otra opción es mucho mejor ya que integra los proyectos de pruebas de NUnit con la interfaz de Visual Studio sin necesidad de abrir el ejecutable de NUnit y mostrando los resultados dentro de la pantalla de Visual Studio, el requisito es que tengamos una versión de Visual Studio que soporte proyectos de prueba.
Esto se logra usando el componente NUnitForVS que podemos bajar de CodePlex y funciona para las versiones 2008 y 2010 de Visual Studio.
Después de instalar el complemento tenemos que modificar los proyectos de NUnit en nuestras soluciones lo que debemos hacer es descargar el proyecto de la solución (Unload Project desde el explorador de soluciones) y editar el archivo csproj tenemos que añadir la siguientes lineas:

<projecttypeguids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</projecttypeguids>

al final de la primer sección <propertygroup> que encontremos en el archivo.
Después de esto ya estamos listos para ejecutar nuestras pruebas abrimos la ventana Vista de Pruebas (Test View) y encontraremos nuestras de NUnit mezcladas con las pruebas de Visual Studio (si es que tenemos alguna) e identificadas por un icono de una N al pricipio:


Ejecutamos las pruebas y obtenemos los resultados en el panel de resultados de las pruebas:


Para aprender más acerca de las pruebas unitarias con .Net Framework visita:
Lista de artículos acerca de pruebas unitarias con .Net Framework

martes, 8 de marzo de 2011

Linq a XSD: leyendo xml con tipos

Como hemos comentado en una entrada anterior es muy fácil usar xml con Linq en .Net, pues bien es posible usarlo aun mas fácilmente usando Linq a Xsd que es un proyecto de Microsoft disponible en CodePlex y que nos permite crear una estructura de clases a partir de un esquema de xml que representa el contenido de nuestro xml, obviamente el requisito es que tengamos o creemos un esquema xml para poder usar esta característica. Recordemos que en una entrada anterior vimos como crear esquemas con herramientas disponibles libremente.

Instalar esta herramienta es un poco complicado por lo que en esta entrada solo dare una breve introducción a lo que se puede hacer con esta herramienta y en otra entrada incluire otros ejemplos incluyendo el procedimiento de instalación.

Lo primero es tener a la mano nuestro esquema consideremos este xsd:


   1:  <?xml version="1.0" standalone="yes"?>
   2:  <xs:schema id="Peliculas"
   3:                       targetNamespace="ProbadorConsola"
   4:                       xmlns:xs="http://www.w3.org/2001/XMLSchema"
   5:                       xmlns="ProbadorConsola"
   6:                       elementFormDefault="qualified">
   7:    <xs:element name="Peliculas">
   8:      <xs:complexType>
   9:        <xs:choice minOccurs="0" maxOccurs="unbounded">
  10:          <xs:element name="Pelicula">
  11:            <xs:complexType>
  12:              <xs:sequence>
  13:                <xs:element name="Titulo" type="xs:string" minOccurs="0" />
  14:                <xs:element name="Director" type="xs:string" minOccurs="0" />
  15:                <xs:element name="Estrenado" type="xs:string" minOccurs="0" />
  16:                <xs:element name="Actores" minOccurs="0" maxOccurs="unbounded">
  17:                  <xs:complexType>
  18:                    <xs:sequence>
  19:                      <xs:element name="Actor" minOccurs="0" maxOccurs="unbounded">
  20:                        <xs:complexType>
  21:                          <xs:sequence>
  22:                            <xs:element name="Nombre" type="xs:string" minOccurs="0" />
  23:                            <xs:element name="Nacimiento" type="xs:string" minOccurs="0" />
  24:                            <xs:element name="Roles" minOccurs="0" maxOccurs="unbounded">
  25:                              <xs:complexType>
  26:                                <xs:sequence>
  27:                                  <xs:element name="Rol" minOccurs="0" maxOccurs="unbounded">
  28:                                    <xs:complexType>
  29:                                      <xs:sequence>
  30:                                        <xs:element name="NombrePelicula" type="xs:string" minOccurs="0" />
  31:                                        <xs:element name="NombreRol" type="xs:string" minOccurs="0" />
  32:                                      </xs:sequence>
  33:                                    </xs:complexType>
  34:                                  </xs:element>
  35:                                </xs:sequence>
  36:                              </xs:complexType>
  37:                            </xs:element>
  38:                          </xs:sequence>
  39:                        </xs:complexType>
  40:                      </xs:element>
  41:                    </xs:sequence>
  42:                  </xs:complexType>
  43:                </xs:element>
  44:              </xs:sequence>
  45:            </xs:complexType>
  46:          </xs:element>
  47:        </xs:choice>
  48:      </xs:complexType>
  49:    </xs:element>
  50:  </xs:schema>

Y después el archivo xml que vamos a utilizar:


   1:  <?xml version="1.0"?>
   2:  <Peliculas xmlns="ProbadorConsola">
   3:    <Pelicula>
   4:      <Titulo>Mazinger</Titulo>
   5:      <Director>Jackie chan</Director>
   6:      <Estrenado>1975-03-19T00:00:00</Estrenado>
   7:      <Actores>
   8:        <Actor>
   9:          <Nombre>John Wayne</Nombre>
  10:          <Nacimiento>1915-10-23T00:00:00</Nacimiento>
  11:          <Roles>
  12:            <Rol>
  13:              <NombrePelicula>Mazinger</NombrePelicula>
  14:              <NombreRol>Estrella</NombreRol>
  15:            </Rol>
  16:          </Roles>
  17:        </Actor>
  18:      </Actores>
  19:    </Pelicula>
  20:    <Pelicula>
  21:      <Titulo>Terminator</Titulo>
  22:      <Director>James Cameron</Director>
  23:      <Estrenado>1985-02-14T00:00:00</Estrenado>
  24:      <Actores>
  25:        <Actor>
  26:          <Nombre>Arnold</Nombre>
  27:          <Nacimiento>1953-10-11T00:00:00</Nacimiento>
  28:          <Roles>
  29:            <Rol>
  30:              <NombrePelicula>Terminator</NombrePelicula>
  31:              <NombreRol>Protagonista</NombreRol>
  32:            </Rol>
  33:            <Rol>
  34:              <NombrePelicula>Terminator</NombrePelicula>
  35:              <NombreRol>Enemigo</NombreRol>
  36:            </Rol>
  37:          </Roles>
  38:        </Actor>
  39:        <Actor>
  40:          <Nombre>Linda Hamilton</Nombre>
  41:          <Nacimiento>1972-08-12T00:00:00</Nacimiento>
  42:          <Roles>
  43:            <Rol>
  44:              <NombrePelicula>Terminator</NombrePelicula>
  45:              <NombreRol>Protagonista</NombreRol>
  46:            </Rol>
  47:            <Rol>
  48:              <NombrePelicula>Terminator</NombrePelicula>
  49:              <NombreRol>Perseguida</NombreRol>
  50:            </Rol>
  51:          </Roles>
  52:        </Actor>
  53:      </Actores>
  54:    </Pelicula>
  55:  </Peliculas>

Linq a XSD nos genera una jerarquía de clases que nos permite manejar el xml usando datos tipeados con soporte de Intellisense y comprobación por parte del compilador, por ejemplo para listar los datos de todos los actores:


   1:  Peliculas peliculas = Peliculas.Load("peliculas.bak.xml");
   2:  var actores = from p in peliculas.Pelicula
   3:                from a in p.Actores
   4:                from actor in a.Actor
   5:                select actor;
   6:  Console.WriteLine("Todos los actores");
   7:  foreach(var actor in actores) {
   8:      Console.Out.WriteLine("Nombre: " + actor.Nombre);
   9:      Console.Out.WriteLine("Fecha de nacimiento: " + actor.Nacimiento);
  10:  }

En conclusion Linq a XSD es un complemento muy útil para el manejo de XML en .Net Framework.
Hay que tener en cuenta que el proyecto a Marzo del 2011 aún esta en etapa Beta y es mejor probar bien nuestro código para evitar errores inesperados, como sea el proyecto es muy útil y es probable que posteriormente sea incluido como parte del .Net Framework.

Para aprender más sobre Linq visita:
Lista de artículos acerca de Linq

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework

viernes, 25 de febrero de 2011

Creando DataSets tipeados a partir de cualquier XML

Un DataSet tipeado es muy útil ya que nos permite acceder a los datos del DataSet por medio de tipos fuertes usando los nombres de las columnas y con comprobación de parte del compilador.
La forma de crear un DataSet de este tipo es con el editor de DataSets que es en realidad un editor de esquemas xml.
Una propiedad del xml es que se puede inferir su esquema prográmaticamente y usar el resultado para crear un el DataSet tipeado, esto se hace leyendo el xml en un DataSet sin tipos y usando el método WriteXmlSchema del DataSet para escribir el esquema en un archivo, se incluye el archivo en el proyecto en que se desea usarlo y al abrirlo Visual Studio crea automáticamente el código y los archivos de soporte necesarios para el DataSet tipeado.

Aquí esta el código para crear el Dataset.

   1:  DataSet schemaCreator = new DataSet();
   2:  schemaCreator.ReadXml("peliculas.xml");
   3:  schemaCreator.WriteXmlSchema("peliculas.xsd");

Por ejemplo para el siguiente XML.

   1:  <Peliculas>
   2:    <Pelicula>
   3:      <Titulo>Mazinger</Titulo>
   4:      <Director>Jackie Chan</Director>
   5:      <Estrenado>1975-03-19T00:00:00</Estrenado>
   6:      <Actores>
   7:        <Actor>
   8:          <Nombre>John Wayne</Nombre>
   9:          <Nacimiento>1915-10-23T00:00:00</Nacimiento>
  10:          <Roles>
  11:            <Rol>
  12:              <NombrePelicula>Mazinger</NombrePelicula>
  13:              <NombreRol>Estrella</NombreRol>
  14:            </Rol>
  15:          </Roles>
  16:        </Actor>
  17:      </Actores>
  18:    </Pelicula>
  19:  </Peliculas>

Nos genera este esquema


Todo esto nos permite usar los métodos  ReadXml y WriteXml del DataSet para cargar el y guardar el contenido xml y usar el mismo de una forma muy similar a una base de datos, también podemos usar Linq contra el DataSet.

Claro que también hay herramientas que nos permiten obtener el esquema del xml sin escribir código, una de ellas es XMLViewer, que es una utilidad para ver el contenido de archivos xml en forma tabular y también obtiene el esquema del archivo, también la herramienta de linea de comandos xsd que se incluye con el SDK de .Net Framework nos sirve para obtener el esquema.

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework

sábado, 12 de febrero de 2011

Que es LINQ

Linq es el acrónimo en ingles para Language-Integrated Query que significa Lenguaje Integrado de Consulta y es un subconjunto agregado a los lenguajes de .Net para realizar búsquedas  y otras operaciones sobre conjuntos de datos, esto es: el mismo lenguaje de tu preferencia puede realizar operaciones sobre conjuntos de datos proporcionándote verificación por parte del compilador,  Intelisense y verificación de tipos sobre las consultas, la sintaxis es muy parecida a SQL con la ventajas antes mencionadas debido a que no se usan con cadenas como en SQL.

Linq puede realizar consultas sobre diversas formas de conjuntos de datos a través de extensiones especificas al conjunto de datos que estas manejando, así existen por lo menos las siguientes extensiones provenientes de Microsoft y otras fuentes:

Linq a objetos: permite manejar consultas a los tipos básicos de .Net como listas y arreglos y sobre clases ya sea del sistema o propias.
Linq a DataSets: las consultas se hacen sobre los componentes de un DataSet ya sea normal o tipeado.
Linq a SQL: las consultas se realizan sobre la base de datos SQL Server con todas las ventajas antes mencionadas.
DBLinq: es un proyecto independiente que es similar a Linq a SQL con la ventaja de que podemos usar bases de datos diferentes a SQL Server y de hecho podemos cambiar de tipo de base de datos con solo modificar la cadena de conexión.
Linq a XML: nos permite realizar consultas en datos guardados en XML.

Para darnos una idea rápida de la forma en que se utiliza Linq tenemos los siguientes ejemplos sencillos de Linq a datos.
Podemos consultar en un arreglo los elementos que cumplen con cierta condición (c#):


   1:  string[] strings = new string[] { "1", "2", "3", "2", "1" };
   2:  IEnumerable<string> two = from s in strings
   3:                            where s == "2"
   4:                            select s;
   5:  Console.Out.WriteLine("s == 2, count{0}", two.Count());

el mismo código en Visual Basic es prácticamente idéntico:


   1:  Dim strings() As String = New String() {"1", "2", "3", "2", "1"}
   2:  Dim two As IEnumerable(Of String) = From s In strings _
   3:     Where s = "2" _
   4:     Select s
   5:  Console.Out.WriteLine("s == 2, count{0}", two.Count())

El resultado de la consulta es un IEnumerable y tenemos que recorrerlo de alguna forma para obtener resultados, en el ejemplo el método Count (que es un método de extensión) recorre el resultado de la consulta y nos entrega la cuenta de los elementos que cumplieron con las condiciones.

También podemos consultar más de un conjunto de datos a la vez (c#):



   1:  int[] integers = new int[] { 1234, 754, 309, 233 };
   2:  var query = from i in integers
   3:              from s in strings
   4:              where i.ToString().Contains(s)
   5:              select new { s, i };
   6:  foreach(var i in query) {
   7:      Console.Out.WriteLine("{0}, {1}", i.s, i.i);
   8:  }

en Visual Basic:

   1:  Dim integers() As Integer = New Integer() {1234, 754, 309, 233}
   2:  Dim query = From i In integers _
   3:     From s In strings _
   4:     Where i.ToString().Contains(s) _
   5:     Select New With {s, i}
   6:  For Each i In query
   7:      Console.Out.WriteLine("{0}, {1}", i.s, i.i)
   8:  Next

En este caso usamos una consulta que une dos conjuntos y después se recorre la consulta para obtener los resultados.
Para aprender más sobre Linq visita:
Lista de artículos acerca de Linq

miércoles, 9 de febrero de 2011

Leyendo y Escribiendo XML con Linq en Visual Basic

Escribir xml en Visual Basic es tan fácil como se dice simplemente se escribe el xml tal cual en el código de Visual Basic y el compilador convierte el árbol completo en una instancia de la clase XElement:


   1:  Dim  xml As XElement =  <Root> _
   2:      <Elemento /> _
   3:  <Root>

Si necesitamos incluir en el xml el valor de una variable o cualquier código podemos usar los tags <%= >:


   1:  Dim a As String = "Hola"
   2:  Dim  xml As XElement =  <Root> _
   3:      <Elemento><%= a %></Elemento> _
   4:  <Root>

Escribir xml también es sencillo pero no tan directo.
En este ejemplo uso Linq para crear XML desde un árbol de objetos y después poder leer de nuevo el XML con Linq y crear de nuevo los objetos.
Por supuesto para correr los ejemplos hay que crear los tipos de datos necesarios, todas las colecciones son de tipo List(Of T)
Escribir (Linq a XML):


   1:  Dim peliculas As List(Of Pelicula)
   2:  Dim source As New PeliculaTA
   3:  peliculas = source.Retrieve()
   4:  Dim xmlArch As XElement = _
   5:   <Peliculas>
   6:       <%= From m In peliculas _
   7:           Select _
   8:           <Pelicula>
   9:               <Titulo><%= m.Titulo %></Titulo>
  10:               <Director><%= m.Director %></Director>
  11:               <Estrenado><%= m.Estrenado %></Estrenado>
  12:               <Actores>
  13:                   <%= From a In m.Actores _
  14:                       Select _
  15:                       <Actor>
  16:                           <Nombre><%= a.Nombre %></Nombre>
  17:                           <Nacimiento><%= a.Nacimiento %></Nacimiento>
  18:                           <Roles>
  19:                               <%= From r In a.Roles _
  20:                                   Select _
  21:                                   <Rol>
  22:                                       <NombrePelicula><%= r.Pelicula %></NombrePelicula>
  23:                                       <NombreRol><%= r.NombreRol %></NombreRol>
  24:                                   </Rol> _
  25:                               %>
  26:                           </Roles>
  27:                       </Actor> _
  28:                   %>
  29:               </Actores>
  30:           </Pelicula> _
  31:       %>
  32:   </Peliculas>
  33:  File.WriteAllText("peliculas.xml", xmlArch.ToString())

Leer (XML a Linq):


   1:  Dim xmlArch As XElement = XElement.Load("peliculas.xml")
   2:  Dim peliculas = From m In xmlArch...<Pelicula> _
   3:   Select New Pelicula With { _
   4:    .Titulo = m.<Titulo>.Value _
   5:    , .Director = m.<Director>.Value _
   6:    , .Estrenado = m.<Estrenado>.Value _
   7:    , .Actores = (From c In m...<Actor> _
   8:    Select New Actor With { _
   9:   .Nombre = c.<Nombre>.Value _
  10:   , .Nacimiento = c.<Nacimiento>.Value _
  11:   , .Roles = (From r In c...<Rol> _
  12:   Select New Rol With { _
  13:   .Pelicula = r.<NombrePelicula>.Value _
  14:   , .NombreRol = r.<NombreRol>.Value _
  15:   }).ToList() _
  16:   }).ToList() _
  17:   }

El resultado de el último ejemplo es un Enumerable(Of Pelicula) el cual hay que recorrer por ejemplo con For Each para obtener resultados.

Para aprender mas sobre Linq visita:
Lista de artículos acerca de Linq

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework