Miniguía de Live HTTP headers

El otro día comenté de pasada esta excelente y útil extensión de Firefox. Como todo, cada uno encuentra su uso particular a cada herramienta trabajando en el desarrollo de aplicaciones web resulta práctico y se echa de menos en otros navegadores. Aunque hay otras opciones, como Wireshark o WebScarab, no son tan sencillas ni se integran tan bien con el navegador.

Al instalar la extensión, aparece una nueva opción en el menú de Herramientas llamada Live HTTP headers. Al abrirla se ve algo parecido a esto:

Live HTTP headers main screen

Directamente aparece la utilidad capturando cabeceras hasta que se desmarque la opción de Capture. Arriba hay 4 pestañas que veremos con más detalle y abajo un botón Save All… para guardar un archvo de texto con todos los datos recopilados, otro Replay… para repetir un bloque y después Clear y Close para limpiar y cerrar.

La pestaña Generator nunca la he usado. Se supone que sirve para hacer un listado detallado de todos los accesos y luego pasarlo a alguna herramienta que genere tests de carga a partir de los datos. La otra pestaña de la que se puede prescindir es About, aunque está bien saber quién hay detrás de todo esto.

La pestaña de Config muestra algunas opciones como la configuración de los POST, que nunca he tocado pero es para no leer las peticiones de este tipo, leerlas rápidamente, completas o limitadas a 1k. Supongo que para depuración de envío de grandes cantidades de datos puede ser útil limitar de algún modo. Se puede elegir si usar una CSS para mostrar más bonito el listado, si abrir en una pestaña y opciones de filtrado para evitar capturar cierto tipo de peticiones. Finalmente se puede añadir a la barra lateral. En cualquier caso, las opciones por defecto suelen bastar.

Pero entrando en materia, lo útil es la inspección de cabeceras, es decir, la pantalla principal y ese pequeño botoncito donde pone Replay. Muchas veces me he encontrado con protecciones de datos por javascript que, de acuerdo, con un navegador normal a un usuario normal, funcionan bien y evitan errores. Pero ni todos los navegadores son como querríamos ni todos los usuarios tienen las mismas intenciones.

Pongamos por ejemplo un simple formulario de registro. Se comprueba por javascript que los datos son correctos, no de dejan el nombre en blanco, ponen una contraseña, ponen un mail aparentemente correcto, aceptan el aviso legal y todo lo que el cliente desee. Luego estos datos deben validarse en el servidor, por lo menos para evitar sorpresas, pero ¿cómo se puede probar eso si solamente se puede entrar por el navegador? Una opción es desactivar javascript, pero igual ni siquiera funciona el formulario, así que entra en juego la opción de repetir una petición de la herramienta que nos ocupa.

Formulario simple

Simplemente hay que capturar el momento en que se pulsa enviar y capturar el flujo de información. En algún sitio habrá una petición de POST (si es GET, probar las cosas es tan sencillo como ir modificando los parámetros y para eso no se necesita ninguna herramienta). Se situa el cursor sobre la petición y se pulsa el botón de Replay…

Live HTTP headers replay screen

Y mágicamente aparece un desglose de la petición. Por un lado las cabeceras arriba (que son completamente modificables, de hecho he cambiado las URL y información sobre las cookies que aparecía) y abajo el contenido del POST.

Un ejemplo podría ser dejar el nombre en blanco. Solamente hay que borrar Prueba después de tNombre= todo lo que hay hasta & y es como si estuviera en blanco. Al hacer esto, abajo hay un contador de Content-Length que es sumamente importante ya que ese dato se ha de copiar al valor de arriba. En este caso, antes era 94 y al borrar Prueba se queda en 88, por lo que hay que modificar el valor 94 de la cabecera por 88 para que funcione, de lo contrario cosas extrañas van a pasar.

Hecho esto, simplemente hacer click sobre Replay a se volverá a lanzar la petición en el navegador y mostrará el resultado de esta. En el mejor de los casos nos indicará que pongamos el nombre y en el peor aparecerá un bonito error. Suerte. (En mi caso no ha pasado nada especial pero sospecho que el correo que contacto se ha enviado a algún sitio, mañana veré).

Y eso es todo, espero que resulte de utilidad… y ¡no hagáis maldades!

WatiN, testando aplicaciones web

WatiN LogoHacía tiempo que tenía pendiente en mi trabajo probar el Selenium, pero era una de esas cosas que uno lo mira un día, no le acaba de ver el punto y lo deja para más adelante. Y no es que no sea útil, realmente es completo, funciona en varias plataformas, tanto de navegadores como de sistemas operativos. Tiene un IDE sencillo que genera scripts e incluso es ámpliamente usado en Ruby on Rails, el framework de moda. Pero aun así, no me acabó de entrar por el ojo.

Una de las pegas que siempre le encontré fue que la integración en los proyectos web de .NET y en tests de NUnit no era lo más cómodo ni simple. Barreras, en definitiva. Pero he descubierto que no era el único que tenía esta impresión: he visto una comparativa de WatiN, Watir y Selenium (siempre hay alguien que te facilita el trabajo). Leyéndolo he decidido probar WatiN.

Y la verdad que la experiencia ha sido muy positiva. Los tests son sencillos de escribir, funcionan como es de esperar y con un lenguaje sencillo y claro. He probado primero algo parecido al ejemplo que hay en su página de inicio y por desgracia no ha funcionado a la primera. Pero estaba claro que algo estaba haciendo mal porque todo se colgaba a la hora de cerrar el Internet Explorer… Después de darle un par de vueltas he desactivado todos los plugins y voilà: funcionaba perfectamente. Al final era el Flashget que interactuaba de forma un tanto extraña.

Después me he puesto a jugar validando alerts de javascript y se ha complicado un poquillo, pero recurriendo a las listas de correo, alguien había preguntado ya mis dudas, como siempre. Al final el uso del DialogHandler ha quedado algo tal que así:

        [Test]
        public void BasicTest()
        {
            using(IE ie = new IE("http://intranet/formulario.aspx"))
            {
                AlertDialogHandler alertHandler = new AlertDialogHandler();
                ie.DialogWatcher.Add(alertHandler);

                ie.Button(Find.ByName("Continuar")).ClickNoWait();

                alertHandler.WaitUntilExists(5);
                alertHandler.OKButton.Click();
            }
        }

Realmente es duro y laborioso escribir este tipo de tests, pero como puede que mi futuro pase por diseñar un nuevo producto más o menos complejo durante unos cuantos meses, el testado de la interfaz de usuario será importante para validar que todo funciona como es debido.

Comparar bases de datos SQL Server

Hace tiempo que andaba buscando una herramienta sencilla que me permitiera fácilmente comparar dos bases de datos a nivel estructural, simplemente para ver si con el paso del tiempo y la progresiva solución de bugs y ampliación de funcionalidades han creado alguna inconsistencia entre la base de datos de desarrollo y la de producción.

Una temporada lo hacía generando scripts SQL y comparando vía Winmerge. Funcionaba, pero solo en versiones iguales de SQL Server y no siempre, ya que el orden de exportación lo decide el servidor con un criterio que desconozco pero que depende de muchos factores.

SQL Effects Clarity Side by Side Screenshot

El otro día buscando llegué hasta la página de SQL Effects, donde ofrecen un producto llamado SQL Effects Clarity CE, una versión gratuita y limitada (básicamente sin ningún tipo de exportación ni de informe) de uno de sus productos más interesantes. Lo descargué, lo probé y la verdad que me encantó. La vista “side-by-side” es bastante cómoda y aunque la versión comercial tiene más funcionalidades, para lo que necesitaba me resultó más que suficiente.

En rojo pone las cosas que hay distintas y viendo el detalle podemos deducir cuál es la diferencia entre una y otra. Además, compara también procedimientos, triggers y vistas y incluso tiene la posibilidad de comparar el recuento de filas.

La única pega es que la version SQL 2005 Express tiene el vicio de devolver los valores por defecto como <code>((0))</code> y la versión normal devuelve <code>(0)</code>, con lo que indica que hay diferencias cuando en realidad no es así.