1. CURSO DE TESTING OSL
12 – 16 DE ABRIL 2010
Test Driven Development – TDD
(Desarrollo dirigido por pruebas)
Alberto Perdomo
Web: http://albertoperdomo.net
Email: alberto.perdomo@aentos.es
Twitter: @albertoperdomo http://www.aentos.com
2. DESARROLLO WEB ÁGIL
FUNCIONALIDAD n FUNCIONALIDAD n+1
DISEÑO DISEÑO
IMPLEMENTACIÓN IMPLEMENTACIÓN
PRUEBAS / VALIDACIÓN PRUEBAS / VALIDACIÓN
DESPLIEGUE DESPLIEGUE
3. TDD: EL ORÍGEN
→ El test-driven development es un concepto estrechamente
relacionado con el extreme programming, que emerge en
1999.
→ Recientemente ha obtenido atención como técnica
individual.
→ Creador: Kent Beck, uno de los frmantes originales del
Manifesto Ágil
5. PROBLEMAS DE ESCRIBIR LAS
PRUEBAS DESPUÉS DEL
CÓDIGO I
→ Sabemos cómo está escrito el código y por lo tanto estamos
viciados a la hora de probarlo
→ Pensamos en probar cómo está implementado y no en
probar cómo debería funcionar desde la perspectiva del
usuario
6. EJEMPLO
Implementación
class User < ActiveRecord::Base
def full_name
first_name + " " + last_name
end Para una instancia del modelo User
con atributos frst_name “Alberto”
y last_name “Perdomo” el método
end
full_name debe devolver “Alberto
Perdomo”
Test
def test_full_name
person = User.new(:first_name => "Alberto", :last_name => "Perdomo")
assert_equal "Alberto Perdomo", user.full_name
end
7. PROBLEMAS DE ESCRIBIR LAS
PRUEBAS DESPUÉS DEL
CÓDIGO II
Estamos viciados con la implementación
→ Pruebas inadecuadas
→ Pruebas que no funcionan
→ Pruebas frágiles basadas en la implementación, no en el
comportamiento
8. EJEMPLO
Implementación
class User < ActiveRecord::Base
def full_name
first_name + " " + last_name
end
end El test nunca dará error aunque el
método deje de funcionar
correctamente
Test
def test_full_name
person = User.new(:first_name => "Alberto", :last_name => "Perdomo")
#assert_equal "Alberto Perdomo", user.full_name
end
9. DESARROLLO TDD
FUNCIONALIDAD n FUNCIONALIDAD n+1
DISEÑO DISEÑO
PRUEBAS / VALIDACIÓN PRUEBAS / VALIDACIÓN
IMPLEMENTACIÓN IMPLEMENTACIÓN
DESPLIEGUE DESPLIEGUE
10. TDD: PASO 1
Escribir un test automatizado que defna la mejora o nueva
funcionalidad
→ Esta prueba debe fallar, ya que aún no hemos
implementado el código
→ FAILURE
11. EJEMPLO PASO 1: ESCRIBIR
PRUEBA
def test_full_name_without_first_name
person = User.new(:first_name => nil, :last_name => "Perdomo")
assert_equal "Perdomo", user.full_name
end
def test_full_name_without_last_name
person = User.new(:first_name => "Alberto", :last_name => nil)
assert_equal "Alberto", user.full_name
end
def test_full_name
person = User.new(:first_name => "Alberto", :last_name => "Perdomo")
assert_equal "Alberto Perdomo", user.full_name
end
def test_full_name_anonymous
person = User.new(:first_name => nil, :last_name => nil)
assert_equal "", user.full_name
end
12. TDD: PASO 2
Implementar el código para satisfacer la prueba
→ Al fnalizar este paso la prueba debe pasar con éxito
→ OK
13. EJEMPLO PASO 2: IMPLEMENTAR
class User < ActiveRecord::Base
def full_name
if first.name.nil? && last.name.nil?
""
elsif first.name.nil?
last_name
elsif last.name_nil?
first_name
else
first_name + " " + last_name
end
end
end
14. TDD: PASO 3
Refactorizamos el código manteniendo el comportamiento
Al fnal de este paso la prueba debe seguir pasando con éxito
→ OK
15. EJEMPLO PASO 3:
REFACTORIZAR
class User < ActiveRecord::Base
def full_name
[first_name, last_name].join(" ").strip
end
end