Ahora que se ha pasado un poco la tormenda de TDD is dead y cada uno ha podido buscar las armas y posicionarse de bando que más le convenía creo que es el momento de que podamos hablar de testing en el mundo real.
Antes de explicar cual es mi aproximación para hacer testing automático está bien que explique qué significa para mi:
Odio el testing, testear es un mal necesario, si pudiese no testearía, cuando hago algo personal no testeo, ni se me pasa por la cabeza joderme la vida pensando en testear cuando estoy disfrutando programando algo que quiero ver cuanto antes. Odio todo lo relacionado con el testing y sobretodo odio que la gente centre toda la atención en el testing, como si el testing por si solo sirviese de algo.
Pero el testing es necesario. Es como ir a comer con tus suegros (*), sabes que si no lo haces va a ser mucho peor. Puede que en algún proyecto corto merezca la pena no hacerlo, pero en general habría que estar muy tocado para no hacerlo y tener una suite de test que te permita estar un poco más seguro, sobretodo a largo plazo.
Dicho esto, mi política para hacer tests es:
Si puedo hago solo test de integración: intento hacer mocks de los extremos y testeo la máxima parte del stack posible. Por ejemplo, si tengo que testear un diálogo (html + javascript) creo el diálogo con los modelos adecuados y lanzo los eventos que lanzaría el usuario y hago checks del UI y de lo que debería tener el servidor/modelo. Como anecdota, el backend de la app que estuvo un día en portada de google tenía 25 tests que cubrían casi todos los casos. Es posible que estés testeando la misma cosa varias veces, se puede vivir con ello sin problema.
Casi-nunca hago el test antes. Sinceramente, a mi hacer el test antes no me dice nada del diseño, como mucho me dice si se me ha olvidado algún parámetro, pero de ahí a que la arquitectura emerja va un paso. Cuando programo algo ya tengo en la cabeza lo que debe hacer a alto nivel, los detalles de implementación no son el diseño amigos (aunque nos lo vendan así).
Sólo hago el test antes cuando voy a resolver un bug. Ya sabéis, RED -> FIX -> GREEN. Si puedo añadir un assert más a un test que ya existe lo hago, aunque no todos los bugs permiten hacer esto.
Solo hago unit test (que muchas veces no lo son) para cosas concretas en las que quiero testear edge-cases de cosas concretas o partes muy críticas.
No hago TDD. Lo intenté en su día (hace unos 8 años) y sería por mi poca experiencia, que no le puse mucho empeño, pero no lo vi claro o lo mismo es que ya odiaba el testing.
Intento usar los menos fuegos artificiales posibles para hacer los assert, esto es, todo el syntactic sugar que te dan frameworks como jasmine está muy bien, pero casi siempre sobra. Con un assert el 90% de las veces es mucho más que suficiente. Esto lo aprendes tras usarlos a muerte, actualizar la versión de jasmine (o tu sistema de testing favorito) y ver que lo han cambiado porque era mucho más guay.
A veces hago tests que varían en función de la máquina o que dependen de servicios externos. A veces merece la pena aunque terminan por machacar el sistema de integración continua.
(*) pongo el ejemplo de los suegros pero puedes poner ahí otro tópico cualquier, esta afirmación no representa de ninguna forma mi experiencia personal y espero que quieras muchísimo a tus suegros. Si eres suegro espero que no dejes de querer a tu yerno/nuera.