1. Apuntes de la #XPWeek 2011
Cursos básico y avanzado
Complemento al libro de TDD:
www.dirigidoPorTests.com/el-libro
Participantes: @carlosble, @eamodeorubio, @AlfredoCasado, @alberto_vilches, @jsayar, @R_Climent,
@istepaniuk, @vicentgodella, @josmasflores, @david_vi11a, @magmax9, @ArturoHerrero, @skirmish84,
@antoniojrossi, @earroyoron, @farroyocastro, @losalamero, @bitness_es
Aviso: Usaremos indistintamente los términos TDD y BDD.
2. Hagas o no hagas TDD/BDD
Lo más importante:
● Que no haya código duplicado
● Que los nombres sean adecuados
● No dejar literales en el código: reemplazar números mágicos y cadenas por
constantes con semántica.
● Con palabras del dominio de negocio
● Sin información técnica
● No vale “utils”, “tools”, “Helper”, “Impl”, “I”, “Abstract”, etc
Lo segundo más importante:
● S.O.L.I.D
http://www.carlosble.com/2011/07/ultra-simplifying-solid/
http://eamodeorubio.wordpress.com/2011/03/07/diseno-software-agil-4-solid-1-%c2%bftus-clases-son-bomberotorero/
Están resumidos en español en el libro de TDD: www.dirigidoPorTests.com/el-libro.
3. El algoritmo TDD
Rojo: usa toda tu experiencia y conocimiento para
expresar el comportamiento que te gustaria que
tu código tuviese, con la mejor API posible.
Verde: No pienses, actúa rápido
Refactor: No vale añadir funcionalidad. Aplica las
reglas del código limpio vistas en la diapositiva
anterior
4. Malinterpretaciones del algoritmo
Algunos compañeros pensaron que para obtener
verde rápido podían escribir en el test, una API
temporal de su código de producción, que luego
podrían cambiar.
Error: El código del test no se puede cambiar una
vez está en verde. El refactor de los tests no
admite cambios en la API publica del SUT (código
de producción).
5. Aclarandonos con el diseño
Lo primero es saber qué quieres diseñar/probar.
Si no está totalmente claro el comportamiento a
especificar, no puedes lanzarte a tirar código.
El SUT (objeto a prueba) nunca puede ser un
doble, sino, ¡no estamos ejecutando nuestro
código!
¿Quién es el SUT? ¿Quíenes son los
colaboradores? ¿Qué responsabilidades tiene
cada elemento?
6. De lo fácil a lo difícil
TDD no está bien hecho sin la TODO-List. Y la
TODO-List está bien gestionada cuando los
casos más sencillos se atacan primero.
Tanto con TDD como haciendo sólo refactoring,
hay que ir de lo más evidente a lo más ofuscado.
¡Lo más fácil primero, siempre y cuando ayude a
triangular!
7. Dos enfoques
Outside-in (tambien top-down): Empezamos a
diseñar clases a las que de antemano les
creamos dependencias. Estas aparecen en el test
en forma de doble (stub, spy o mock).
Inside-out (también bottom-up): Empezamos a
diseñar clases pequeñas sin dependencias
aparentes.
En ambos casos, pueden emerger nuevos
artefactos a base de refactoring.
Algunos asocian BDD con el primer enfoque y TDD con el segundo.
8. Unit Vs Integration
Maximiza el número de tests unitarios y minimiza
el de integración. Los tests unitarios siguen las
reglas F.I.R.S.T
Los test de integración dependen de plataforma y
no hay reglas universales para escribirlos. Son un
dolor y hay que escribir el mínimo suficiente.
9. Mantenimiento de los tests
El código de los tests es igual de importante que el de
producción por eso su mantenimiento es clave. Aplicamos la no-
duplicidad y sobre todo los nombres adecuados.
Setup/Teardown adecuados y comunes para todos los tests de
su clase.
AssertEqual y assertTrue son poco informativos y
poco legibles. Hamcrest nos da más expresividad. Propuesta de
formato para Junit:
@Test public void
nombre_separado_por_underscores() throws Exception
{ …
assertThat(result, containsString(“esperado”));
}
http://weblogs.javahispano.org/artesanodeprimera/entry/escribiendo_mejores_te
st_ii
10. Test Doubles
Nunca doblamos clases que no son nuestras.
Usamos stubs para doblar métodos de consulta.
Usamos espias y mocks para doblar acciones.
Un espía y un mock pueden simular una consulta igual
que un stub.
El mock es un policía estricto. Un espía es un stub que
además recuerda todo lo ocurrido y nos lo puede decir.
http://weblogs.javahispano.org/artesanodeprimera/entry/escribiendo_mejores_te
st_iii_mocking
11. No te olvides de la arquitectura
Las características horizontales deben ser
estudiadas y diseñadas al comienzo del proyecto:
http://www.carlosble.com/2011/01/tddbdd-architecture-and-frameworks/
Las características verticales (requisitos de
negocio), emergen en nuestro BDD. A veces
aplicamos patrones de diseño expresando los
tests de la manera adecuada, sin que sea YAGNI
(innecesario).
12. MVC no es orientado a objetos
El patrón MVC no es orientado a objetos. No
importa que en Grails un Controller sea una clase con métodos
y en Django sea un módulo con métodos. Ciertamente atacar a los
controllers con pruebas es mucho mas sencillo con Grails . El MVC es un
patrón arquitectónico.
Cuanto más nos acoplamos a un framework
MVC, menos margen tenemos para modelar
comportamiento con objetos.
Acoplate al framework para hacer CRUD pero
evitalo para permitir que TDD te ayude a modelar
el negocio de manera emergente.
13. Controller: responsabilidades
El controller gestiona entrada y salida. Su misión
es conectar con negocio/dominio sin que éste
tenga que conocer elementos como HttpRequest.
Podemos diseñar la casuistica del controller
aplicando TDD, con espías y stubs para los
objetos de negocio.
El paso de parámetros de controller a negocio se
debe hacer con DTOs (Data Transfer Objects, objetos tipo struct
inicialmente) cuando son más de dos parámetros
14. Controller = N, Negocio = N - 1
Los objetos de dominio/negocio no deben saber
nada del controller.
El controller debe hacer el menor número posible
de llamadas al dominio.
Ej/Test: El usuario logueado puede enviar un mensaje al usuario registrado con
nickname 'paco'.
Implementación: El controller necesita obtener el usuario logueado de la sesión.
Puede por tanto pedir el usuario al servio de sesion, porque necesitamos
quitarnos la capa HTTP antes de pasar a dominio (no pasamos un Request a
dominio) pero NO obtendrá el usuario con nickname 'paco', simplemente pasará
el nickname al dominio. Dominio sabrá qué debe hacer con el nickname.
15. XP son mas cósas
Pair Programming (PP):
● 2 Teclados y 2 ratones en un mismo ordenador con una
gran pantalla.
● El navegador no interrumpe, apunta y aporta.
● Navegador y piloto se intercambian frecuentemente.
● Empatía, respeto, y no más de 5 horas al día.
Integración contínua (CI):
No tiene por qué ser automática pero es aconsejable. La
idea es unir del código de todos todo el tiempo y llevarlo
a UAT (user acceptance testing).
El código es de todos: Code reviews + PP
16. XP son valores
● Pragmatismo
● Sentido común
● Mejora contínua
● Autosuperación
● Reconocer los errores propios
● Trabajo en equipo
● No basta con hacerlo funcionar, hay que hacerlo
bien.
17. Artesanía del software
● Lo principal es maximizar el valor para el cliente.
● Trabaja con plena atención en lo que se hace.
● El artesano no se hace en dos días.
● Es responsabilidad del que aprende el
aprovechar la ayuda del que enseña.
http://www.etnassoft.com/biblioteca/apprenticeship-patterns/
● Aprende de los demás y comparte lo que sabe