jueves, 23 de junio de 2011

Mi AOS2011

Me encantan los Open Spaces. Mi primera experiéncia fue en Buenos Aires en marzo de 2009, y supuso una revolución para mi en la forma de encarar la organización de eventos. El segundo fue el del año pasado en Barcelona, en el que, a parte, participé en la organización. Y este fin de semana se realizó el Agile Open Spain 2011 en Pamplona, al que no podia faltar. Como siempre me encontré allí a un montón de amigos, aunque la novedad de este año fue poder ir acompañado de casi la totalidad de la gente de la oficina de Plain Concepts en Bilbao.

Una de las razones por las que me encantan los Open Spaces es porque creo que ejemplifican a la perfección el espiritu del agilismo. Es un evento hecho por la comunidad para la comunidad. Por supuesto que necesita un comité organizador ( y que lo hicieron a la perfección ) para todo el tema logístico, pero la "chicha" del evento, las 36 charlas que hubo, fueron un trabajo de los miembros de la comunidad para los miembros de la comunidad. Se formaron 36 equipos enfocados en dar el máximo valor posible a las charlas.



Yo propuse una charla sobre calidad del código que fue bien recibida y que creo que estubo bastante bien, aunque no se tocaron todos los temas que me hubieran gustado. La discusión se centró sobretodo en la cobertura de tests y en los comentarios en el código. También se habló de los equipos de QA.

Por otra parte asistí a charlas tan variopintas como Stubs, Mocks y Spies, taller práctico de histórias de usuario, talento, estimaciones, deduda técnica y romper la rutina.

Por encima de las charlas en sí ( que podéis ver en detalle en los diferentes resúmenes hechos por los participantes ) yo me quedo con las personas que asistieron al evento. Se reunieron 150 personas preocupadas por su profesión, con ganas de mejorar su entorno, con ganas de hacer cosas para ellos y para los demás y comprometidos con la excelencia.

Espero ya con ganas el Agile Open Spain del año que viene, en el que espero veros a muchos de vosotros.

Un saludo!

Instalar una plantilla metodológica en castellano en un TFS2010 en inglés

Puede darse el caso que tengamos un TFS 2010 instalado en inglés pero nos interese cargar una plantilla metodológica en castellano. Nuestro primer impulso será cargar la plantilla metodológica sin hacer ningún cambio en nuestro servidor y crear un proyecto con ella. A veces es bueno seguir los impulsos, así que vamos a ello.

En nuestro querido Visual Studio 2010 vamos al menú Team y abrimos el Process Template Manager:







Y seleccionamos nuestra plantilla para cargar. Se carga la plantilla correctamente y se nos añade a la lista de plantillas disponibles.



Una vez cargada la plantilla ya podemos crear un nuevo Team Project con ella, así que creamos un Team Project con el Team Explorer y como plantilla metodológica escogemos la plantilla recién subida. Todo parece ir bien hasta que...



Le hechamos una ojeada al log y vemos que el error está en la creación del portal de Sharepoint ya que no encuentra un template del site para el idioma español (3082):



Para solucionar esto nos vamos a la web de Microsoft a descargarnos el Language Pack para nuestra versión de Sharepoint, en nuestro caso la 3.0. Y la instalamos, claro. Al finalizar la instalación nos pedirá si queremos ejecutar el asistente para configuración de Productos y Tecnologías de SharePoint.



Le decimos que si y nos ejecutará el asistente, que prácticamente no requiere de nuestra intervención.



Y si todo ha ido bien:



Si nos vamos a la carpeta C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\1033\XML (inglés) veremos que tiene un fichero ( WEBTEMP.Microsoft.TeamFoundation.SharePoint.Dashboards) que en la carpeta C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\3082\XML (español) no está.

Tenemos que conseguir este archivo de alguna instalación del TFS en español y copiarlo aquí y volvemos a pasar el asistente para configuración de Productos y Tecnologías de SharePoint dejando las opciones marcadas por defecto. Una vez hecho esto ya podemos crear el nuevo proyecto con la plantilla metodológica en castellano.

Ahora solo nos faltará editar el portal de proyecto de SharePoint para que muestre los elementos en castellano en lugar de en inglés.

Espero que haya servido de ayuda.

Un saludo!

miércoles, 15 de junio de 2011

Codificación manual y enlace a datos de tests funcionales con CodedUI

En el anterior artículo, veíamos como hacer un test funcional con CodedUI grabando nosotros los pasos del test. En el artículo de hoy veremos como codificar a mano estos pasos, ya que llega a ser más rápido y más flexible hacerlo así.

Empezaremos de la misma manera, creando un proyecto de test, añadiéndole un archivo de test con CodedUI y generando una nueva grabación. La diferencia es que ahora, en lugar de hacer clic sobre el botón de grabar y empezar a realizar los pasos, arrancaremos la aplicación y arrastraremos el botón con la cruceta de la barra del test builder sobre un control de la aplicación, en nuestro caso el textbox correspondiente a la operación.



Al hacer esto se nos abrirá la misma pantalla que se nos abrió al hacer la aserción en el anterior tutorial. Esta vez, haremox clic sobre las dos flechas hacia la izquierda que hay arriba a la izquierda y se nos abrirá un panel que contiene un árbol donde se muestran los diferentes controles que vamos seleccionando.



Seleccionaremos el control que acabamos de añadir y haremos clic sobre el botón de añadir el control al UI map. Haremos lo mismo con todos los controles, incluída la cruz de cerrar la aplicación, hasta que nos quede algo parecido a esto:



Ahora ya podemos hacer clic sobre el botón de generar el código de la grabación. El Visual Studio detectará que no hemos hecho ninguna grabación y nos preguntará si queremos que añada los controles seleccionados al UI map del test. Le diremos que si.



Si nos fiajmos en el test de donde hemos partido, veremos que no ha cambiado nada, ya que no se ha realizado ninguna grabación. Vamos ahora a hacer por código lo mismo que hacia Visual Studio automáticamente por nosotros antes. Para ello, no vamos a editar el archivo UIMap.Designer.cs, ya que este archivo es autogenerado y podriamos perder los cambios realizados allí. Para permitirnos añadir nosotros nuestros tests, Visual Studio nos proporciona una clase parcial vacia situada en el archivo UIMap.cs. Es aquí donde podemos hacer un método nuevo con las acciones que queremos que se realicen.

Empezaremos incluyendo la libreria de testing para los controles Wpf:



Lanzamos la aplicación a testear:







Definimos las variables para manejar los textbox de la calculadora, que en CodedUI son WpfEdit:



Ahora definimos las variables para manejar los botones:



Inicializamos los textboxes con los valores que queremos testear:



Y simulamos un clic sobre los botones del igual y de cerrar la aplicación:



Ahora simplemente tenemos que llamar a esta función desde nuestra clase de test, y veremos que si ejecutamos el test este hace todo lo que le hemos dicho y pasa correctamente.



Por ahora solo hemos comprobado que la aplicación no le pase nada raro, pero no hemos comprobado que el resultado sea el correcto. Para ello tenemos que simular nosotros lo que, cuando grababamos los tests, eran las aserciones.

Para ello vamos ha hacer algo parecido a lo que hace automáticamente Visual Studio. Nos vamos a crear una clase que contenga todos los parámetros que necesitamos ( los dos operandos, la operación y el resultado de la operación) y vamos a crearnos una instancia pública de la misma en la clase UIMap.cs:



Modificaremos la función que acabamos de realizar en el UIMap.cs para que utilice los valores de las propiedades de esta clase y para que, después de clicar sobre el botón de igual, recupere el valor que hay en el textbox del resultado:



Ahora sólo nos queda rellenar los valores de los operandos y la operación desde nuestro test, y hacer un assert del valor esperado con el valor del parametro Resultado:



Y ahora sólo nos queda alimentar este tests con datos provenientes de un XML. Primero de todo nos creamos el XML, que tendrá una aspecto como este:



Ahora le decimos al test que sus datos se alimentaran de este XML. Para hacerlo, seguiremos los mismos pasos que si quisieramos hacer lo mismo en un test unitario. Nos vamos a la ventana de test view, seleccionamos el test y en la ventana de propiedades, clicamos sobre el botón situado en el campo Data Connection String. Se nos abrirá una pantalla como esta:



Seleccionamos XML file y clicamos en siguiente.



Clicamos sobre siguiente:



Seleccionamos la tabla adecuada en el XML ( en nuestro caso sólo tenemos una ) y verificamos que los campos sean correctos. Clicamos en finalizar. Nos pedirá de copiar el archivo en el proyecto y de añadirlo a la lista de items a desplegar. Le decimos a todo que si.

Ahora ya estamos preparados para utilizar estos datos. Para hacerlo, nos ayudaremos de la propiedad DataRow del objeto testContextInstance, de la siguiente manera:



Y ya tenemos el CodedUI tests alimentado con datos de un XML!

Espero que el tutorial os haya gustado y no os haya aburrido en exceso.

Un saludo!

miércoles, 8 de junio de 2011

Tests funcionales con CodedUI

Como ya muchos sabéis, CodedUI es la tecnología de Microsoft que nos permite realizar tests funcionales sobre nuestra aplicación, sea esta del tipo que sea. En el artículo de hoy veremos como crear un test funcional básico y añadirle una aserción. Empecemos!!

Lo primero es presentaros la aplicación que vamos a testear. Se trata, como no, de una pequeña calculadora realizada en WPF y compuesta de 4 textboxes y un botón. En los tres primeros textboxes introduciremos los operandos y la operación a realizar y, al apretar el botón, se nos mostrará el resultado en el último textbox.



Para realizar los tests vamos a crear un acceso directo a la aplicación en nuestro escritorio y vamos a añadir un nuevo proyecto de test a la solución. A continuación, añadiremos un nuevo item al proyecto de test de tipo CodeUITest. Automáticamente se nos mostrará un cuadro de diálogo que nos da a elegir entre generar un nuevo grabando acciones o utilizar uno existente. Escogeremos la primera opción.



Esto hace que nos aparezca la barra del CodedUI test builder, que es una pequeña barra que nos ayudará en nuestro cometido.



Como podéis ver, la barra sólo tiene cuatro botones;

  • Empezar o pausar la grabación.
  • Ver los pasos que llevamos guardados.
  • Seleccionar un control para hacer una aserción (luego lo vemos).
  • Generar el código de la grabación existente.

Para empezar le daremos al botón de grabar y empezaremos a realizar la prueba que queremos guardar. En este caso, será hacer doble clic en el acceso directo, introducir una operación del tipo 5 + 6, darle al botón y cerrar la aplicación. Esto en nuestra clase de test genera un código tal como este:



Ahora veremos un poco más el código interno, pero por ahora nos vamos a limitar a ejecutar el test. Esto hará magia en nuestro ordenador y se nos abrirá la aplicación, se tecleará lo mismo que hemos tecleado nosotros, se pulsará el botón, se mostrará el resultado y se cerrará la aplicación. Ni Tamariz lo haría mejor!

Si miramos un poco el código interno, veremos que es prácticamente auto-explicativo:



Vemos como abre la aplicación, inserta los textos correspondientes y hace clic en los botones. Destacar sobre todo las tres líneas donde rellenamos los textboxes, porque lo utilizaremos después para alimenar al test de datos.

Ahora vamos a hacer una aserción sobre el textbox del resultado. Lo que queremos es que el test compruebe que la operación es correcta, no sólo que no hay ningún problema para ejecutarlo. Así pues, vamos a hacer un nuevo test como si fuera un test unitario, es decir, haciendo un método público decorado con el atributo [TestMethod]. En el cuerpo del método, hacemos clic con el botón derecho del ratón y seleccionamos la acción "Generato code for CodedUI test -> User CodedUI Test Builder":







Volvemos a estar como antes, con la barra del CodedUI test builder. Realizaremos los mismos pasos pero, antes de cerrar la aplicación haremos clic sobre el botón de pausa y generaremos el códig de los pasos que llevamos hasta ahora. Ahora, haremos clic en el icono de la aserción y lo arrastraremos hasta el textbox del resultado. Esto hará que se nos habra la siguiente ventana:



Hacemos clic con el botón derecho en el campo text y seleccionamos la opción "Add asertion". Esto nos abre la siguiente pantalla, donde introducimos el valor que queremos asegurar que se muestre.



Generamos el código para la aserción, empezamos otra grabación para grabar el cierre de la aplicación y generamos el código para esta última acción. El código resultante tendria que ser algo parecido a esto:



Pasamos el test y vemos que se pone en verde. Si vamos a nuestra clase calculadora y cambiamos el comportamiento de la suma para que no devuelva la suma de los dos operandos, veremos que el test deja de pasar.

Bueno, pues por hoy ya es suficiente. Espero que os haya sido útil el tutorial. En la próxima entrega, veremos como alimentar este test de datos provenientes de un XML.

lunes, 16 de mayo de 2011

Mis tres días en la XP2011!

La semana pasada tuvo lugar en Madrid la conferencia internacional XP2011 sobre metodologías ágiles en desarrollo de software y de sistemas de información, la más grande de Europa y la segunda en tamaño del mundo después de la Agile Conferenceque se celebra en Estado Unidos, y tuve la inmensa suerte de asistir durante 3 días (la conferencia duraba 4, pero el primero de ellos no pude estar). Estaba realmente emocionado con la oportunidad ya que se iban a dar cita algunos de los grandes referentes en el mundo del desarrollo ágil de los últimos años cómo Mary y Tom Poppendieck creadores del término "Lean Software Development", David Anderson creador de Kanban y muchos otros cómo J.B. Rainsberger, Jurgen Appelo, Michael Feathers...

Así que con las expectativas muy altas llegaba el Miércoles por la mañana con la Keynote de Esther Derby titulada "Still No Silver Bullets" ya empezada. Después de terminar esta y de saludar brevemente a algunos compañeros de diferentes grupos ágiles de España pasamos directamente a las sesiones. El formato de la conferencia durante los dos días intermedios (el primero y el último eran talleres y tutoriales) mezclaba sesiones de una hora entera con lightning talks de 20 o 30 minutos cada una, lo que tiene su lado positivo (dinamiza mucho la conferencia) pero también su lado negativo (muchas veces el tema se toca de manera demasiado superficial).

Aun así salí contento de unas cuantas sesiones sobretodo de las de Jurgen Appelo: "The Purpose of Leadership and Governance" y la de Angel Medinilla presentando "Scrumban" (divertido e ilustrador como la mayoría de las veces que le he visto).


El primer día lo acabamos con la creación de la agenda del Open Space que se iba a realizar al día siguiente y más tarde con una cena de gala cortesía de la organización en la casa de campo de Madrid, donde se repartieron los premios a los mejores papers de la conferencia y donde después de la cena unas cuantas personas de la comunidad demostraron que no se les queda pequeño el adjetivo "ágil", con bailes imposibles, saltos fuera de lo común y movimientos de cintura realmente espectaculares... :P

El segundo día siguió un guión parecido: Keynote de Brian Marick (que consiguió que todos los presentes en la sala se pusieran a bailar tango...) y más sesiones y lightning talks. Esta vez creo que acerté un poco más con las sesiones cortas donde hubo cosas realmente curiosas cómo por ejemplo charlas sobre Zombies y Scrum por Marc Löffler, sobre rehabilitación de adictos al Command and Control por Angel Medinilla , sobre cómo Scrum podría convertirse en un nuevo paradigma del socialismo por Rafael Viveros (pero socialismo del de verdad, no del que nos venden ciertos políticos del tres al cuarto...) o alguna sesión más convencional sobre cómo empezar a hacer TDD de manera práctica por Thomas Nielssen.

Después de una interesante cena y post-cena por Madrid en compañía de unos chicos Holandeses (de los que no me acuerdo del nombre) nos fuimos a dormir cansados pero con ganas de afrontar el último día de conferencia que a priori se presentaba muy bien ya que se trataba de 2 talleres y tutoriales de 4 horas de duración cada uno.

Con 10 minutos de retraso debidos a problemas logísticos entramos al taller sobre Refactoring de Michael Feather's, que supuso una pequeña decepción...ya que la sesión no era de Refactoring!! En disculpa del señor Feathers hay que decir que en la puerta de la sesión había una hoja donde se explicaba cómo iba a ser el taller, pero al llegar tarde no nos dimos cuenta pero... ¿porqué poner ese título? Aún así la sesión nos sirvió para aprender un poco de Ruby, ya que era el el lenguaje en el que se hacía el taller

Tras pelearnos con Ruby fuimos a comer, y después una larguísima sobremesa (para mi uno de los únicos fallos de la organización, que por otro lado estuvo genial y además eran gente muy maja y a la que felicito desde aquí) nos dirigimos al último taller. Para el fin de fiesta escogí el taller de Jurgen Appelo, basado en su curso sobre Agile Management y que a priori tenía muy buena pinta. Y la verdad es que no defraudó. Aunque muchos acusan a Appelo de ser un mero recopilador de ideas de otra gente, yo creo que está creando cosas y conceptos interesantes, o por lo menos les está dando una visión que me parece muy adecuada. Además el taller fué entretenido y mezcló la teoría con juegos cómo el Delegation Poker el Meddlers of Catán o uno sobre una matriz de métricas, todos ellos muy amenos y que además te hacen pensar.

Meddlers of Catán de Jurgen Appelo

Al acabar el taller sólo tuve tiempo de despedirme de la gente y salir corriendo para no perder el AVE de vuelta a Barcelona donde cansado (pero contento por todo lo aprendido, por la experiencia vivida y por poder debatir sobre metodologías ágiles con algunas de las personas más destacadas de este país y de todo el mundo) no tardé en quedarme dormido...

miércoles, 4 de mayo de 2011

Waterfalacias: Mitos y creencias sobre Scrum

En toda transición hacia Scrum o cualquier otra metodología ágil es común enfrentarse a un elevado porcentaje de rechazo entre la gente que es parte de ese cambio (de hecho cualquier cambio impuesto suele generar rechazo en primera instancia). Los motivos que esta gente tienen para no aceptar este cambio no pueden ser de lo mas variado: hay quien tiene miedo a perder poder, otros intuyen que va a tener que "trabajar más" e incluso hay gente que simplemente están contentos con la situación actual, pero curiosamente muchos de ellos suelen coincidir en su argumentario a la hora de explicar el porqué de sus objeciones.
Algunos de estos argumentos comunes los recoge Mike Cohn en su estupendo libro "Succeding With Agile", y ciertamente son argumentos que yo mismo me he encontrado o que he escuchado mas de una vez cuando intentas explicar o formar a alguien en metodologías ágiles, y que ya se han convertido en mitos o creencias "populares".

En este artículo voy a intentar desmitificar algunos de estos argumentos, explicando mi visión sobre cada uno de ellos y intentado aclarar el porqué son incorrectos o inexactos.

Empecemos:

  • En Scrum no se planifica, por lo tanto no somos capaces de dar estimaciones a nuestros clientes
Aunque parezca lo contrario en Scrum se planifica bastante más que en las metodologías tradicionales, lo que pasa que esta planificación se lleva a cabo de una manera mucho más "responsable". En lugar de hacer todo el esfuerzo de planificación al inicio, donde la incertidumbre es mayor y estamos sujetos a cualquier tipo de cambio o imprevistos, en Scrum se va planificando durante toda la vida del proyecto, y además a diferentes niveles:
- Planificación inicial: Donde se crea, prioriza y estima el product backlog inicial del proyecto (normalmente se realiza en una iteración 0 o fase de Inception y los requisitos son definidos a alto nivel)
-Planificación durante cada iteración: Donde se refina el product backlog (Product Backlog Grooming) y se decide que se va a llevar a cabo durante la siguiente iteración (Sprint Planning Meeting)
-Planificación diaria: Donde el equipo ajusta la operativa del día a día (Daily Meeting)

Así vemos que en Scrum se está planificando continuamente y que la diferencia principal con metodologías más clásicas es que la planificación inicial no es ningún dogma, sinó que a partir de lo que se va aprendiendo durante el proyecto esta se va ajustando para cumplir mejor las expectativas del cliente.
  • Scrum necesita que todo el mundo sepa hacer de todo
Otro de los principales mitos de Scrum es que todo el mundo tiene que saber hacer de todo, y esto hace que los especialistas dejen de tener sentido. Aunque bien es cierto que demasiada especialización de los miembros del equipo puede ir en contra de los intereses del proyecto, realmente lo deseable es que "El Equipo" sea multidisciplinar, es decir que entre todos los miembros del mismo reúnan los "skills" necesarios para llevar a cabo el proyecto evitando cosas como equipos de analistas, equipos de testing, etc... que favorecen los nichos de conocimiento y el "lavado de manos" dentro de un proyecto. Si a esto le sumas que las personas que forman estos equipos son capaces de, más allá de su especialidad, ayudar con otras tareas en momentos concretos de los proyectos tenemos equipos donde el conocimiento está muy compartido y donde es difícil ver bloqueos ante la falta de alguno de los miembros.
  • Tenemos equipos distribuidos y en Scrum es necesaria la comunicación cara a cara
Al igual que as anteriores ideas, esta proviene de gente que simplemente se ha quedado en la superficie de Scrum y no ha profundizado en la misma. Uno de los principales valores de las metodologías ágiles es la comunicación entre los miembros del equipo , entonces "¿que hacemos si nuestro equipo es distribuido?" La respuesta más fácil es "no podemos hacer Scrum", aunque realmente la respuesta correcta sería: "lo mismo que si el equipo está co-localizado", aunque eso si, con matices. Obviamente la comunicación cara a cara no se sustituye con nada, pero con la tecnología actual deberíamos ser capaces de llevar a cabo un proyecto de manera muy normalizada con nuestros compañeros que trabajan en remoto (videoconferencia, chats, etc...)
  • Los equipos Scrum no documentan y nuestros clientes nos exigen documentación
En este punto no voy a comentar demasiado. Simplemente señalar que en Scrum y en las metodologías ágiles en general los documentos son un medio, nunca un fin, y por lo tanto se intenta evitar toda aquella documentación que no sea útil para que el proyecto se lleve a cabo satisfactoriamente y quedarse con aquella que si es importante. Es decisión de cada equipo pensar que es y que no es útil para este fin y actuar en consecuencia. Pero... ¿de verdad todavía nos creemos que toda la documentación que nos exigen algunas metodologías tradicionales tiene sentido?
  • Scrum no tiene en cuenta la arquitectura y el diseño
Nada más lejos de la realidad. Simplemente que el hecho de definir esta arquitectura y este diseño se lleva a cabo de manera totalmente opuesta a cómo lo intentan hacer las metodologías tradicionales: En Scrum no hay un equipo de "arquitectos" que deciden al principio del proyecto sobre un Power Point cómo va a ser la arquitectura, sino que a partir de unas líneas generales iniciales a alto nivel la arquitectura va emergiendo iteración a iteración a medida que se va desarrollando el proyecto, y además durante todo este tiempo los "arquitectos" trabajan codo a codo con los desarrolladores adaptando la arquitectura a los nuevos requisitos. De hecho en las metodologías ágiles se considera que buena parte del diseño (si no todo) está en el propio código y en consecuencia se le da el estatus y la importancia que eso implica, poniendo mucho énfasis en prácticas de ingeniería que aseguren una alta calidad y mantenibilidad del código (TDD, BDD, Pair Programming, Code Reviews, Continuous Integration, S.O.L.I.D Principles...)
  • Nuestros proyectos son demasiado complejos para realizarlos con Scrum
Esta es una de las ideas que menos entiendo ya que en toda la literatura sobre Scrum que he leído nuna he visto nada que pueda dar a entender esto. Precisamente Scrum funciona especialmente bien en proyectos complejos, siendo flexible a posibles cambios durante todo el proyecto, gestionando los riesgos de manera implícita iteración a iteración y potenciando además la creatividad y la innovación de los miembros del equipo lo que garantiza un porcentaje de éxito mucho mayor en cualquier proyecto.

Cómo veis, todos estos argumentos son fácilmente rebatibles desde el raciocinio y el sentido común y no deberían ser un problema real en una implantación de metodologías ágiles. Sin embargo, como ya hemos dicho antes, estas argumentaciones suelen ocultar otro tipo de miedos, y estos son el verdadero desafío a la hora de hacer que la gente esté receptiva o no ante un cambio metodológico.
Un saludo!!

sábado, 12 de marzo de 2011

Primeros pasos con Moq ( parte II )

Después de unas semanas liadas con el cambio de residencia y la incorporación a Plain Concepts volvemos a la carga con los artículos referentes a Moq ( aquí está el primero de la serie ).

Empecemos por el principio, es decir, por el constructor de nuestro mock. Al hacer el new tenemos dos opciones a la hora de indicar el comportamiento de nuestro objeto imitador:

  • MockBehaviour.Loose: el mock devolverá siempre valores por defecto si no está definido el Returns y si se llama a una función del mock que no tenga un Setup, no lanzará ninguna excepción
  • MockBehaviour.Strict: si se llama a una función del mock que no tenga un Setup, se lanzará una excepción y el test fallará.

Yo recomiendo utilizar la segunda opción ( MockBehaviour.Strict ) ya que seremos mucho más conscientes de lo que está haciendo el test.

En el anterior artículo vimos el uso de la función Verify. Esta función tiene 9 sobrecargas, en las que básicamente se pueden configurar dos cosas:

  • El string de error en caso de no cumplirse la condición.
  • El número de veces que queremos verificar que se ha hecho la llamada a la función.

Esta segunda opción se hace mediante la utilización de los métodos estáticos de la estructura Times. Ejemplos de utilización podrían ser:

  • Times.Never(): queremos verificar que la función nunca se llama.
  • Times.Once(): queremos verificar que la función sólo se llama una vez.
  • Times.Exactly(3): queremos verificar que la función se llama tres veces.
  • Times.Between(1, 5, Range.Inclusive): queremos verificar que la función se llama entre 1 y 5 veces, ambas incluidas.

En el anterior artículo también vimos como verificar que se había establecido el valor de una propiedad. Obviamente también podemos verificar que el valor de una propiedad se haya recuperado. Podemos verlo en el siguiente ejemplo:

[TestMethod]
public void Verify_Timeout_was_get()
{
    var mockDao = new Mock<IDAO>();
    AssetManager assetManager = new AssetManager(mockDao.Object);
    mockDao.VerifyGet(dao => dao.Timeout);
}

Siguiendo con las propiedades, también les podemos hacer un setup. La versión más sencilla es tratarlas como una función, de manera que podemos especificar el valor que queremos que devuelvan cuando se les hace un get. Para hacer esto, actuamos como si de una función se tratara:

mockDao.Setup(dao => dao.Timeout).Returns(1500);

La segunda versión es un poco más compleja, no en el código que tenemos que teclear ( muy sencillo ) sino en las funcionalidades que nos da. Si utilizamos el siguiente código:

mockDao.SetupProperty(dao => dao.Timeout);

estamos indicando a Moq que empiece a trackear la propiedad Timeout, con lo que el mock será consciente de cuando estemos intentando establecer un valor a Timeout y se guardará tal valor para futuros usos. Esto nos permitirá poder escribir un código tal como este:

[TestMethod]
public void Track_timeout_property()
{
    var mockDao = new Mock<IDAO>();
    mockDao.SetupProperty(dao => dao.Timeout);
            
    IDAO idao = mockDao.Object;
    idao.Timeout = 400;
    Assert.AreEqual(400, idao.Timeout);
}

Y esto es todo por por hoy. En futuros artículos veremos más características de este framework.

A testear!!

lunes, 21 de febrero de 2011

Un vistazo al ecosistema de Windows Phone 7

El crecimiento que ha tenido el desarrollo para dispositivos móviles en los últimos años, propiciado por tecnologías como Cloud Computing, el auge de las redes sociales y también, por qué no decirlo, la facilidad de obtener beneficios que tienen los desarrolladores con las tiendas  de aplicaciones (appstore, android market…) invita pensar que el desarrollo para dispositivos móviles (ya sean teléfonos, tablets o lo que venga después) va a ser uno de los mercados más importantes en los próximos años (si no lo es ya), y entrar en él va a ser prácticamente indispensable para todo desarrollador o compañía. 

Pero entrar en el desarrollo de Smartphones se antoja complicado. La multitud de plataformas ya existentes, y las que están apareciendo, provoca una gran fragmentación en el ecosistema móvil, haciendo difícil la elección de por dónde empezar: ¿Apostamos seguro por los IPhone y IPad? ¿O mejor tirar por la opción “libre” que representa Android?¿Quizás sea mejor apuntar a un tipo de cliente más de negocio cómo el que representa Blackberry?¿Bada, WebOs…? También existe la opción multiplataforma, donde estándares cómo el promovido por WAC y la W3C prometen interoperabilidad total, pero por ahora no pasan de ser intentos más o menos acertados.

Uno de los últimos grandes actores en sumarse a este mercado ha sido Microsoft, con su SO Windows Phone 7, que viene a sustituir al ya caduco Windows Mobile. A priori se podría pensar que el salto llega un poco tarde, con Apple ya consagrada y Android creciendo cada vez más, pero el buen trabajo realizado con el SO, la gran comunidad de desarrolladores y su reciente alianza con Nokia (anunciada en el pasado Mobile World Congress de Barcelona) hacen que se les haya que tener en cuenta.

Interfície gráfica

La original y sencilla interfície de usuario hacen de WP7 un sistema fresco y muy atractivo visualmente. Centrándose en el contenido y la tipografía han conseguido desmarcarse de las características interfícies de usuario de sus competidores basadas en listas e iconos, añadiendo además conceptos interesantes cómo el sistema de vista panorámica.

image Menú principal de un dispositivo con Windows Phone 7

imageSistema de vista panorámica

Desarrollo

Siendo el número potencial de usuarios de nuestras aplicaciones mucho menor, por el momento, que el de las otras grandes compañías, ¿qué nos ofrece a los desarrolladores Microsoft para que nos decidamos por ellos?

Plataformas y Herramientas

Una de las grandes ventajas de Microsoft, es su set de plataformas y herramientas, ya que son las mismas que utilizan los desarrolladores de .Net para web o escritorio. Visual Studio cómo IDE (pudiendo desarrollar en C# o VB.Net), Blend Expression, y Silverlight o XNA Game Studio (para aquellos que quieran desarrollar videojuegos en WP7) permiten una curva de aprendizaje muy pequeña a todos aquellos acostumbrados a desarrollar con ellas, en comparación con el coste de aprender otros lenguajes y plataformas.

Además estas herramientas, así cómo el emulador de WP7, están disponibles de manera gratuita en AppHub, donde también podéis encontrar otros recursos en forma de foros, tutoriales, etc.

Servicios y funcionalidades

Las APIs de WP7 proporcionan acceso a funcionalidades del teléfono como la geo-localización, la pantalla multi-táctil, el acelerómetro o el micrófono, además de servicios como la reproducción multimedia o las notificaciones Push (que permiten actualizar los bloques de la pantalla principal).

Por contra, el sistema no soporta multitarea, dejando en manos de los desarrolladores la opción de implementar opciones de salvar y recuperar el estado (de hecho lo recomiendan cómo Best Practice) para dar la sensación de que la aplicación no deja de funcionar en ningún momento.

WP7 tampoco permite el acceso a la API nativa de Windows. Microsoft justifica esta decisión en base a asegurar la fiabilidad de las aplicaciones desarrolladas, pero esto penaliza en la extensibilidad y personalización de la plataforma.

image SDK de WP7

La distribución de aplicaciones WP7 se realiza “únicamente” a través del Windows Marketplace. En este sentido la política de Microsoft es bastante cercana a la de Apple, no permitiendo instalar aplicaciones por otra vía que no sea la de su tienda (aunque es probable que haya gente que encuentre atajos :P). La cuota de acceso al Marketplace (para poder subir y vender aplicaciones) son de 99$ al año, y si no lo he entendido mal, el precio mínimo para una aplicación son 0,99$ (no se pueden subir aplicaciones gratuitas??)

Además, como anécdota, Microsoft no permite subir código libre al Market, lo que ha generado reacciones no muy positivas por parte de la comunidad Open-Source.

De nuevo Microsoft justifica estas medidas argumentando que así evitan que el Market se llene de aplicaciones absurdas que en muchos casos sólo sirven para perder el tiempo (por ejemplo,Android Market está lleno de ellas) y garantizan un alto nivel de calidad y una gran experiencia de usuario en todas sus aplicaciones.

Para abrir una cuenta en el MarketPlace se puede hacer también  través del AppHub

Conclusiones

El nuevo SO de Microsoft puede llegar a ser un importante animador en el sector de los Smartphones.Aunque de momento esté lejos en cuanto a números de las grandes dominadoras (Apple, Android, RIM…), su nombre, su gran comunidad de desarrolladores y su alianza con un gigante cómo Nokia hace que no haya que perderlo de vista.

A su favor tiene, además de lo mencionado:

  • Un SO realmente atractivo visualmente y original que además, da la sensación, funciona con una gran fluidez.
  • Herramientas conocidas por todos los desarrolladores Microsoft, permitiendo una curva de aprendizaje muy pequeña

Y cómo posibles puntos en contra:

  • Un sistema de distribución bastante restrictivo (aunque a Apple, con un sistema similar no le ha ido nada mal)
  • Un SO aún un poco verde
  • El limitado número de aplicaciones y clientes en comparación a las otras grandes compañías.

Espero que este pequeño artículo os haya ayudado a tener una idea global sobre WP7 y todo lo que le rodea.

Un saludo!!

martes, 1 de febrero de 2011

Estimando en Puntos de Historia

Después de una interesante discusión producida ayer en twitter y en la lista de agile-spain sobre la estimación en puntos de historia, he estado dándole vueltas al tema y me da la sensación de que es algo que mucha gente cuando empieza con Scrum no tiene demasiado claro. Lo viví en primera persona cuando me tocó supervisar la implantación de Scrum en mi última empresa, llegando incluso a tener discusiones grandes sobre porqué debíamos estimar así y no cómo se había hecho “toda la vida”… Así que me he decidido a aportar mi granito de arena y tratar de explicar de manera sencilla en qué consiste esto de los puntos de historia y qué beneficios aporta.

Antes de empezar, simplemente explicar, para quien no lo sepa, que los puntos de historia es la medida de estimación utilizada cuando se trabaja con Historias de Usuario, una de las técnicas mas utilizadas al trabajar con la metodología Scrum.

Relatividad

En primer lugar  los PH son relativos no absolutos. Es decir estimamos en función de la diferencia relativa entre una historia y otra. Si a una historia le damos 1PH, y a otra 3PH, esto únicamente indica que una es el triple que la otra. ¿Pero el triple de qué? Pues eso lo veremos después. Además, la relatividad se aplica entre diferentes equipos, es decir que 3PH para un equipo no tienen que significar lo mismo para otro equipo (aunque trabajen en el mismo proyecto, no importa!!)

De ahí viene el utilizar la famosa escala de  0, 1, 2, 3, 5, 8, 13, 40.., ya que lo que interesa no es el valor absoluto, únicamente el orden de magnitud, además de que nos ayuda a evitar la tentación de estimar hasta el más mínimo detalle: ¿Que importancia tiene estimar 40 o 42? Cuanto mas grande es la historia a estimar, menos certeza y precisión tenemos sobre la misma, con lo cual la escala nos ayuda a ser conscientes de esa imprecisión.

Tamaño

Cuando se estima en puntos de historia, lo que se intenta es dar un valor del TAMAÑO de la historia. ¿Y qué implica Tamaño? Pues yo entiendo que una combinación de:

  • Complejidad: No es lo mismo implementar una alta en un formulario que, por ejemplo, un algoritmo de inteligencia artificial para un juego
  • Esfuerzo: ¿Es una tarea que tengo que repetir en muchos sitios? ¿Me va a llevar mucho tiempo aunque sea una cosa fácil?
  • Riesgo: ¿Estamos trabajando con una tecnología desconocida? ¿Tiene la gente del equipo experiencia en el negocio?

Utilizando cómo métrica el tamaño, sacamos al tiempo de la ecuación, de manera que evitamos la tentación de buscar conflictos del tipo “esta historia debería estar hecha en 3 días, y tu llevas 4”, o cosas de este estilo que suelen aparecer cuando se utiliza la métrica del tiempo.

Entonces, alguien se preguntará, ¿cómo les decimos a nuestros clientes cuando tenemos listo el producto? Eso lo vamos a ver en el siguiente apartado.

Velocidad

La velocidad es el factor que nos sirve para ver cuanto trabajo somos capaces de entregar en cada sprint. Si nuestra velocidad son 15PH, estamos diciendo que entregamos 15PH de media en cada iteración. Con esto conseguimos ese factor de conversión de los puntos de historia a fechas, es la manera que tenemos de poder decirle a nuestro cliente cuando estimamos que nuestro producto estará listo (ojo, es una estimación, no hay que caer en el típico error de considerar que las estimaciones son contratos!!)

Hay que tener cuidado con esto, ya que se puede caer en la tentación de hacer cuentas y empezar a pensar en tiempo en lugar de estimaciones (1 tío 8 horas = 1PH). Esto aunque en media sea cierto no lo va a ser para todas las historias, e incluso es posible que haya historias de 1 punto, que por ejemplo se tarden mas en hacer que una de dos puntos. Por suerte, la velocidad actúa también cómo factor de corrección y a la larga, todas las historias que estén estimadas con los mismos PH van a caer mas o menos en la misma zona (la distribución aproximada debería tener forma de campana de Gauss)

Tareas

Conviene aclarar que lo que he dicho hasta ahora se refiere a la estimación de historias, no a la de las tareas en las que descomponemos dicha historia durante la planificación de Sprint. No es el objetivo de este post entrar en este tema, así que sólo diré que mi recomendación para la estimación de tareas es:

  • No estimarlas
  • O dividir la historia en tareas que ocupen aproximadamente un día

En Conclusión…

  • Los puntos de historia permiten abstraernos del tiempo a la hora de realizar estimaciones, de manera que podemos centrarnos en aspectos cómo la complejidad o el riesgo de la historia, y valorarla en función de eso.
  • Al indicar el tamaño relativo de una historia respecto a otra, es sencillo realizar estimaciones triangulando, con lo cual el proceso,con el tiempo, se vuelve muy eficiente.
  • Los PH evitan la especificación al detalle, poniendo de manifiesto el aumento de incertidumbre de una especificación a medida que esta aumenta.
  • La velocidad actúa cómo factor de corrección de las desviaciones en las estimaciones y nos permite realizar la conversión a fechas para poder dar plazos de entrega a nuestros clientes o superiores cuando sea necesario.

A partir de aquí lo que toca es experimentar y probar,e intentar encontrar la medida de estimación que mejor se adapte a nuestro equipo, aunque yo sin duda recomiendo encarecidamente probar con los PH!

Ya sabéis, cualquier comentario será bienvenido!!

sábado, 29 de enero de 2011

Primeros pasos con Moq

Aprovecho que en los últimos días los compañeros Luís Ruiz Pavón y Bruno Capuano han escrito sendos artículos sobre Moles ( aquí y aquí ) para hacer una pequeña introducción a otro framework de mocking llamado Moq.

Lo primero que tenemos que hacer es bajarnos la dll de su web . Una vez hecho esto ya podemos incluir la librería (Moq.dll ) en nuestro proyecto de test.

El código que vamos a testear se compone de una clase llamada AssetManager que tiene una dependencia a IDAO, una interfície para definir la manera en que se persistirán los objetos, ya sea en una base de datos, en un fichero o en memoria. Es esta interfície la que "mockearemos", evitando así tener que codificar una implementación para testear AssetManager.

ClassDiagram1

Lo primero que vamos a hacer es crear un stub para la función SaveAsset de IDAO. Para tener clara la diferencia entre un Mock y un Stub, consulta este artículo de Martin Fowler.

Veamos el código para testear esta función:

[TestMethod]
public void SaveAsset_returns_true()
{
   
var mockDao = new Mock<IDAO>();
   
AssetManager assetManager = new AssetManager(mockDao.Object);

    Asset asset = new Asset();
   
mockDao.Setup(dao => dao.SaveAsset(asset)).Returns(true);

    Assert.AreEqual(true, assetManager.SaveAsset(asset));
}

Como podemos ver estamos creando un stub de nuestra interfície IDAO indicando que cuando se llame a la función SaveAsset nos devuelva el valor true. Así, al invocar al método SaveAsset de la clase AssetManager, que a su vez llama al método SaveAsset de la interfície IDAO, nos devolverá true y el test pasará. Para comprobar que esto es cierto, basta con cambiar el valor de retorno de la función de IDAO y veremos que el test no pasa.

En el ejemplo anterior, nada nos garantiza que realmente se haya llamado a la función de IDAO, ya que SaveAsset de AssetManager podria haber devuelto true directamente. Ahora vamos a ver como podemos "mockear" una función y verificar que realmente se llama:

[TestMethod]
public void GetAssetByName()
{
   
var mockDao = new Mock<IDAO>();
   
AssetManager assetManager = new AssetManager(mockDao.Object);

    assetManager.GetAssetByName("MyFirstAsset");

    mockDao.Verify(dao => dao.GetAssetByName("MyFirstAsset"));
}

Como podemos ver claramente en el código, con la función Verify verificamos que se haya llamado a la función GetAssetByName de la interficie IDAO con el parámetro MyFirstAsset. Podemos comprobar que esto es cierto modificando el string "MyFirstAsset" de una de las dos llamadas por otro string. El resultado será que el test no pasará. Este tipo de cosas puede hacer que nuestro test sea demasiado frágil y, por lo tanto, difícil de mantener. Moq nos ofrece la classe It para lidiar con este tipo de problemas. Podriamos substituir el string "MyFirstAsset" por sentencias del tipo:

  • It.IsAny<string>() -> pasa como parámetro cualquier string

  • It.Is<string>(s => s.StartsWith("My")) -> pasa como parámetro un string que empieza por "My"

  • It.IsRegex("\ba") -> pasa como parámetro un string que empieza por la letra a

Al igual que podemos comprobar que se ha llamado a una función, quizá también nos pueda interesar comprobar que se ha seteado una propiedad. Para hacerlo, nos apoyaremos en la función VerifySet del mock:

[TestMethod]
public void Verify_ConnectionString_was_set()
{
   
var mockDao = new Mock<IDAO>();

    AssetManager assetManager = new AssetManager(mockDao.Object);

    mockDao.VerifySet(x => x.ConnectionString = It.Is<string>(s => s.StartsWith("Non")));
}

Con este código comprobaremos que se ha seteado la propiedad ConnectionString con un valor que empieza por "Non".

Y por hoy ya tenemos suficiente. Hemos visto que es muy fácil utilizar Moq y hacer los primeros pasos con él. En posteriores tutoriales veremos más características de este framework.

Hasta la próxima!

miércoles, 26 de enero de 2011

La importancia de un buen Product Owner y un buen Product Backlog

product-ownerMuchas de las implantaciones de Scrum ( u otras metodologías ágiles ) que he conocido estos años son implantaciones que podríamos llamar bottom-up, es decir que parten del equipo de desarrollo. Estos se dan cuenta que no pueden continuar con la organización que llevan ahora y deciden tomar cartas en el asunto y empezar a hacerlo por ellos mismos. Es lo que se denomina comúnmente agilismo de guerrilla.

Aun siendo una muy buena opción para empezar ( yo empecé así ) a la larga se acaba quedando corta y es necesaria la implicación de la gerencia para llegar a algo más completo. Para mi los principales puntos débiles son:

  • Adolecen de un mentor experimentado: en la mayoría de los casos, el equipo se ha documentado sobre Scrum y empieza a probarlo.

  • Mala repartición de los roles: sobretodo si sólo está utilizando Scrum un equipo, hay gente que tiene dos roles: equipo y Scrum Master o equipo y Product Owner. La por situación es si hay alguien que tiene los tres roles, en lo que esto tiene muchos números de convertirse en un command and control encubierto.

  • Product Owner poco implicado: al ser un miembro del equipo le va a costar hacer de Product Owner. No va a tener relación directa con el cliente, no va a saber todo lo que se tiene que hacer a lo largo del tiempo o no le va a gustar definir bien las historias.

Veamos este punto con un poco más de detalle. Todas las cosas en contra que he comentado no tienen porqué pasar... pero tienen muchos números de que pasen. A los desarrolladores en general no nos gusta demasiado hacer especificaciones, definiciones de acabado y cosas por el estilo. Por lo menos a mi no me entusiasma ni a ninguno de mis compañeros. Esto desemboca en que nuestro Product Backlog no sea lo que tendría que ser.

Pero llega un día en que alguien con mucha más relación con el cliente y con visión del producto se instala en tu equipo. Y empieza a generar un Product Backlog con todas las historias que quiere que a corto/medio plazo se implementen, las prioriza, detalla más las más importantes, especifica las condiciones de aceptación de cada una de ellas. Este día será un día importante en tu historia dentro del proyecto. Los cambios más importante que se producirán en tu equipo para mi son:

  • Ánimo dentro del equipo: ver que la gerencia se preocupa por el proyecto y pone toda la carne en el asador para que tire adelante anima a la gente.

  • Mayor cuidado con la aplicación: todos somos profesionales y estamos comprometidos, pero no es lo mismo que cada quince días el equipo le haga a un Product Owner "externo" la demo del sprint que se la hagan entre ellos.

  • Mayor acierto con la implementación de las histórias: el equipo desarrollará lo que el Product Owner quiere, no lo que él cree que el Product Owner quiere.

  • Mayor visión del producto: el equipo sabe hacia donde tirará el proyecto y puede tomar decisiones en función de ello.

Por lo tanto, si tienes ya un buen Product Owner en tu equipo, cuídalo y no lo dejes marchar, y sinó búscate uno en quanto puedas!

 

Nota 1: este post está basado en hechos reales. Ningún Product Owner, Scrum Master o miembro del equipo ha sido maltratado en la realización del mismo.

Nota 2: este post está basado en mi experiencia. Si la tuya es diferente, no dejes de contarla en los comentarios!

martes, 25 de enero de 2011

He leído: Clean Code

cleancode-225x300Empiezo nuestra aventura en geeks con la review de un libro que tengo pendiente desde hace algún tiempo, y que no es otro que Clean Code, de Robert.C. Martin.

Lo primero que tengo que decir de Clean Code, es que es un “Must Have” de cualquier desarrollador que se precie de serlo! Es un de esos libros que debería ser obligatorio que te hagan leer en la facultad, y no sólo leer, sino casi recitar de memoria!

¿Y porqué hago tales afirmaciones? Pues porque Clean Code es un libro genial, bien explicado, con ejemplos claros y concisos, va al grano, y además, es entretenido de leer (bueno, algunos capítulos son un poco pesados, pero en general es bastante ameno)

Si, si,¿pero de que va el libro? os estaréis preguntando muchos... Pues el libro trata simplemente de cómo escribir código limpio (el propio título lo indica). Algo que parece una chorrada pero que es sumamente difícil. En el libro, Robert no das las claves para  ser capaces de escribir código lo más legible posible, algo que además de facilitar la lectura (según él. el 90% del tiempo que pasamos programando, estamos leyendo código nuestro o de otras personas) va a afectar de manera directamente proporcional al diseño, la reutilización o la escalabilidad de nuestro código.

Cómo ya he comentado antes, el libro es muy conciso, presentando en cada capítulo soluciones a diferentes errores comunes que la mayoría de gente comete o ha cometido en diferentes ámbitos del código: Comentarios, Clases, Funciones, Tratamiento de errores, tests unitarios… todo ello aderezado con múltiple ejemplos sacados de proyectos reales. Esta estructura de los capítulos permite tanto una lectura secuencial cómo a modo de libro de consulta. Y además, y vuelvo a repetirme, el libro es muy ameno.

En definitiva, un gran libro que recomiendo a todos los desarrolladores (presentes, pasados y futuros) ya que puede ser una muy buena guía para intentar mejorar en nuestro trabajo.

Un saludo!!

lunes, 24 de enero de 2011

Ahora también en geeks!

Pues si, la popular comunidad de blogs sobre desarrollo y tecnologías Micrsosoft, geeks.ms nos ha abierto las puertas para que participemos en ella desde nuestro blog. Así que a partir de ahora podréis encontrar nuestros posts tanto aquí cómo en http://geeks.ms/blogs/devnettips/. Desde aquí queremos dar las gracias a Rodrigo Corral por permitirnos participar en la comunidad, a la cual intentaremos aportar material interesante y de calidad!

Un saludo desde devnettips!