IIS7 Smooth Streaming en Beta

Microsoft saca en Beta la tecnología Smooth Streaming para IIS 7, que permite visualizar videos de alta calidad independientemente del ancho de banda que tenga el usuario, permitiendo visualizar videos sin necesidad de esperar el buffering, ya que la reproducción de los mismos empezará de manera instantánea.

Podéis ver en SmoothHD un ejemplo de uso de esta tecnología, que Microsoft ha sacado de la mano de Akamai.

Podéis instalar la extensión desde Microsoft Web Platform o directamente desde aquí.

A disfrutarla!

[Artalde.NET] Report Builder, que los informes los haga el usuario! otra vez…

El próximo día 3 de marzo, martes, será la siguiente charla de Artalde, el grupo de usuarios del País Vasco. El lugar y hora será el mismo de siempre, de 19:00 a 21:00 en la universidad de Deusto.

EL ponente esta vez será el gran Miguel Egea y su charla tratará sobre una temática similar a la que tenía pensada Salvador Ramos y que tuvimos que suspender a causa de las condiciones climatológicas.

Agenda:

19:00 – 19:15 Registro.

19:15 – 20:15 Report Builder. ¡Qué los informes los haga el usuario!

  • Modelos de datos y Report Builder ¿vía muerta?
  • Report Builder 2.0, ventajas e inconvenientes sobre 1.0
  • Diseñador de consultas contra motor multidimensional
  • Creación de informes

Podéis registraros aquí.

Y antes que lo pregunte alguien, todavía no podremos vivirlo online, aunque algún día espero que podamos llegar a ese punto. Lo siento 🙁

Pruebas unitarias: MythBusters

Aunque los beneficios de las pruebas unitarias puedan parecer claros, no es más cierto que a día de hoy se usan en muy pocos proyectos. Pero sin son tan buenas,¿por qué no se usan?

Pues la razón principal es que existen bastante desconocimiento en esta materia, poca tradición y algunos falsos mitos.

Uno de los mitos es creer que escribir pruebas unitarias es escribir el doble de código; escribir el código de la aplicación y escribir el código de pruebas. Escribir una prueba nunca es escribir el doble de código, aunque lógicamente sí es escribir más código. El mito es totalmente falso.

Las pruebas siempre se deben ir escribiendo a medida que se desarrolla el software. A medida de desarrollamos vamos probando nuestro código lo que nos permite asegurar que el módulo queda terminado correctamente, libre de incidencias.

La realización de pruebas unitarias debe ser un proceso obligatorio en nuestros desarrollos y que no queden a la voluntad del desarrollador. Si el desarrollador no está habituado a su uso diario es muy fácil que tienda a evitar realizar este tipo de pruebas.

Si no estás familiarizado con el uso de pruebas unitarias la perseverancia debe ser tu gran aliado. Debes estar convencido de que el uso de pruebas unitarias es el enfoque correcto y no ser flexible; las pruebas unitarias no son opcionales y deben realizarse a medida que se desarrolla.

Dejar la implementación de pruebas para el final no es realista, ya que las pruebas nunca se llegarán a implementar y si lo hacen, serán de una baja calidad, ya que la persona que las realiza considerará que es una pérdida de tiempo, considerando que su tarea ya estaba terminada sin realizar estas pruebas.

¿Y si no escribiéramos este código cómo probamos? Pues la experiencia me dice que hay diferentes situaciones.

La primera situación es que no se prueba. Se implementa el módulo pero no se prueba, dando por hecho que nuestra experiencia como desarrolladores hará que las incidencias sean mínimas. Cuando tenemos todos los módulos lo probamos de forma integrada a través de pruebas funcionales.

Esta situación es la situación peor con la que podemos encontrarnos, pero desgraciadamente es la más habitual. Los tiempos de integración, depuración y corrección de incidencias se multiplican. El tiempo que va desde que consideramos que el producto está terminado hasta que realmente está terminado puede llegar a ser superior al tiempo invertido en el desarrollo, y lo digo por experiencia, por mala experiencia.

Otra situación algo mejor, es el uso de aplicaciones de pruebas de usar y tirar. Todos hemos implementado aplicaciones tontas, generalmente de consola, para probar el módulo que estamos desarrollando y que posteriormente integraremos en un sistema mayor.

La situación no es la ideal pero realmente el desarrollo de pruebas unitarias puede tener una semejanza con este tipo de aplicaciones, siendo éste último concepto más avanzado y mejorado para que pueda ser reutilizable, independientes y completas.

Estas aplicaciones de usar y tirar nos valen para la primera vez y si somos exhaustivos nos permitirá probar bien nuestro módulo. La realidad nos dice que esta aplicación se tira y que ante cualquier modificación en el módulo nos comportamos como en la situación primera, en las pruebas con sistema completa y pruebas funcionales.

Otro mito, unido al anterior, es que desarrollar pruebas unitarias hace que los tiempos de desarrollo se incrementen, incrementando los costes del proyecto.

Entre desarrollar y no probar y desarrollar haciendo pruebas unitarias, reconoceré que es más rápido desarrollar sin probar…..pero creo que esto no nos vale….así que entre desarrollar con pruebas unitarias y desarrollar probando con métodos más rústicos, ésta segunda es más lenta y por tanto, más cara.

La manera más rápida de desarrollar software es desarrollarlo bien. Como hemos comentado en el punto anterior, si no desarrollamos código de calidad y no realizamos pruebas, los tiempos de desarrollo se podrán disparar enormemente; tiempo de integración, tiempo de depuración, tiempo de incidencias etc…

Pero hay un problema mayor; la pérdida de confianza del cliente. Un producto de baja calidad, lleno de incidencias es la peor tarjeta de presentación.

Por otro lado, hay que tener en cuenta que cuando más larga sea la vida de la aplicación más beneficios se obtendrán del sistema de pruebas unitarias.

Muchos productos tienen un mantenimiento evolutivo que implica el desarrollo de nuevas funcionalidad y la corrección de incidencias. Sin un proceso adecuado de pruebas unitarias, los tiempos de pruebas se dispararán en fases posteriores, ya que será necesario probar y corregir tanto las nuevas funcionalidades como las funcionalidades ya existentes.

Cierto es también que la adopción de pruebas unitarias dentro del equipo de desarrollo implica una inversión en formación. La primera vez que las empleemos llevará algo más de tiempo ya que tenemos que familiarizarnos con las herramientas y con el framework de pruebas unitarias. Este tiempo es algo habitual asociado a cualquier proceso de aprendizaje que sólo sería imputable al primer proyecto que se desarrolle.

Videos en Channel 9 España sobre patrones

Ya están disponibles un par de videos míos en Channel 9 que muestran un ejemplo de cómo implementar los patrones singleton y observer en plataforma .NET.

Los videos están orientados a gente principiante en el mundo de los patrones. Muestran una implementación sencilla de los patrones singleton y observer.

image

image

Se pueden ver directamente desde la página ( se necesita Silverligth 2.0 instalado ) a calidad bastante buena o se pueden descargar en varios formatos para poder verlos en local.

Dentro de poco espero poder subir algún más sobre esta temática.

Beneficios de las pruebas unitarias

Con las pruebas unitarias todos ganan. La vida de desarrollador será mucho más fácil, ya que la calidad de su código mejorará, se reducirán los tiempos de depuración y la corrección de incidencias y por tanto el cliente estará mucho más contento porque la aplicación hace lo que él quiere que haga, por lo que ha pagado.

Las pruebas fomentan el cambio y la refactorización. Si consideremos que nuestro código es mejorable podemos cambiarlo sin ningún problema. Si el cambio no estuviera realizado correctamente las pruebas nos avisarán de ello. Seguramente la frase “si funciona no lo toques” a más de uno familiar les resultará familiar. Si hubiera pruebas unitarias, no sería necesario pronunciarla.

Se reducen drásticamente los problemas y tiempos dedicados a la integración. En las pruebas se simulan las dependencias lo que nos permite que podemos probar nuestro código sin disponer del resto de módulos. Por experiencia puede decir que los procesos de integración son más de una vez traumáticos, dejándolos habitualmente para el final del proyecto. La frase “sólo queda integrar” haciendo referencia a que el proyecto está cerca de terminar suele ser engañosa, ya que el periodo de integración suele estar lleno de curvas.

Las pruebas nos ayudan a entender mejor el código, ya que sirven de documentación. A través de las pruebas podemos comprender mejor qué hace un módulo y que se espera de él.

Nos permite poder probar o depurar un módulo sin necesidad de disponer del sistema completo. Aunque seamos los propietarios de toda la aplicación, en algunas situaciones montar un entorno para poder probar una incidencia es más costoso que corregir la incidencia propiamente dicha. Si partimos de la prueba unitaria podemos centrarnos en corregir el error de una forma más rápida y lógicamente, asegurándonos posteriormente que todo funciona según lo esperado.

image

Características de una buena prueba unitaria

Las pruebas unitarias se tienen que poder ejecutar sin necesidad de intervención manual. Esta característica posibilita que podamos automatizar su ejecución.

Las pruebas unitarias tienen que poder repetirse tantas veces como uno quiera. Por este motivo, la rapidez de las pruebas tiene un factor clave. Si pasar las pruebas es un proceso lento no se pasarán de forma habitual, por lo que se perderán los beneficios que éstas nos ofrecen.

Las pruebas unitarias deben poder cubrir casi la totalidad del código de nuestra aplicación. Una prueba unitaria será tan buena como su cobertura de código. La cobertura de código marca la cantidad de código de la aplicación que está sometido a una prueba. Por tanto, si la cobertura es baja, significará que gran parte de nuestro código está sin probar.

Las pruebas unitarias tienen que poder ejecutarse independientemente del estado del entorno. Las pruebas tienen que pasar en cualquier ordenador del equipo de desarrollo.

La ejecución de una prueba no puede afectar la ejecución de otra. Después de la ejecución de una prueba el entorno debería quedar igual que estaba antes de realizar la prueba.

image

Las diferentes relaciones que puedan existir entre módulos deben ser simulada para evitar dependencias entre módulos. La simulación suele hacerse en base a interfaces usando stubs o mocks.

Es importante conocer claramente cuál es el objetivo del test. Cualquier desarrollador debería poder conocer claramente cuál es el objetivo de la prueba y su funcionamiento. Esto sólo se consigue si se trata el código de pruebas como el código de la aplicación.

Es importante tener en cuenta que aunque estas son las características de una buena prueba, no siempre será posible ni necesario cumplir con todas estas reglas y será la experiencia la que nos guiará en la realización de las mismas.

Cómo ordenar una lista…será por opciones!!

El método más habitual para comparar una lista es utilizar el método Sort. Este método utiliza internamente el método CompareTo de los elementos que la lista contiene.

Con datos simples, como un string o un int, no es necesario hacer nada especial para ordenar la lista pero si tenemos una lista de datos más completos, por ejemplo, una lista de entidades, deberemos hacer algo más.

Supongamos que tenemos una entidad que tiene dos propiedades; nombre y fecha, y queremos tener la posibilidad de ordenar por la fecha, tanto de forma ascendente como descendente.

   1: public class MiEntidad
   2: {
   3:     public string Nombre { get; set; }
   4:     public DateTime Fecha { get; set; }
   5: }

Opción 1: La primera opción es que nuestra entidad implemente la interfaz IComparable. Ésto nos obligará a implementar un método adicional en nuestra clase, llamado CompareTo. Éste método será al que se llame cuando se llame al método Sort de la lista.

   1: public class MiEntidad : IComparable<MiEntidad>
   2: {
   3:     public string Nombre { get; set; }
   4:     public DateTime Fecha { get; set; }
   5:     
   6:     public int CompareTo(MiEntidad other)
   7:     {
   8:         return this.Fecha.CompareTo(other.Fecha);
   9:     }
  10: }

 

Pero ¿ qué pasa si queremos ordenar una lista de objetos y no tenemos acceso al código de la misma y no podemos implementar este método adicional?

Opción 2: Tendremos que crear una nueva clase que implemente IComparer. Esta clase incluya la lógica necesaria para saber cómo tiene que comparar dos objetos de tipo MiEntidad y la emplearemos al llamar al método Sort.

   1: public class MiEntidadComparador : IComparer<MiEntidad>
   2:     {
   3:         private SortOrderEnum sortOrder = SortOrderEnum.Ascending;
   4:  
   5:         public MiEntidadComparador(SortOrderEnum sort)
   6:         {
   7:             this.sortOrder = sort;
   8:         }
   9:  
  10:         public int Compare(MiEntidad x, MiEntidad y)
  11:         {
  12:             if (this.sortOrder.Equals(SortOrderEnum.Ascending))
  13:                 return x.Fecha.CompareTo(y.Fecha);
  14:             else
  15:                 return y.Fecha.CompareTo(x.Fecha);
  16:         }        
  17:     }

Una vez que tenemos la clase, la usaremos al invocar al método Sort.

   1: lista.Sort(new MiEntidadComparador(SortOrderEnum.Descending));
   2: foreach (MiEntidad me in lista)
   3:     Console.WriteLine(me.Nombre);

Opción 3: Si aún así no nos apetece hacer esta clase, siempre podemos usar un delegado.

   1: lista.Sort(
   2:         delegate(MiEntidad x, MiEntidad y)
   3:         {
   4:             return x.Fecha.CompareTo(y.Fecha);
   5:         }); 

Opción 4: Pero todavía hay más opciones, esta vez usando LINQ. Eso sí, recuerda que debes LINQ está disponible a partir de la versión 3.5 de Framework.

   1: var listaNombre = from c in lista
   2:         orderby c.FECHA descending
   3:         select c.Nombre;
   4: foreach (string nombre in listaNombre)
   5:     Console.WriteLine(nombre);

Opción 4: o lo mismo usando expresiones lambda.

   1: foreach (MiEntidad me in lista.OrderByDescending(x=>x.Fecha).ToList())
   2:     Console.WriteLine(me.Nombre);

Espero que os sea de utilidad!