Más allá del testing

2,706 views

Published on

Ponencia sobre buenas prácticas de testing en la Conferencia Rails '2007 (Madrid 22 y 23 de noviembre), por Sergio Gil y Christos Zisopoulos

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,706
On SlideShare
0
From Embeds
0
Number of Embeds
54
Actions
Shares
0
Downloads
49
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Más allá del testing

  1. 1. Más allá del testing Sergio Gil Christos Zisopoulos
  2. 2. Estrategias de testing
  3. 3. DDT: Development Driven Testing
  4. 4. DDT: Development Driven Testing Escribir los tests después de la primera iteración del código
  5. 5. Por qué
  6. 6. Por qué • A veces la especificación no existe es difusa, y hay poco tiempo
  7. 7. Por qué • A veces la especificación no existe es difusa, y hay poco tiempo • Es más fácil para empezar
  8. 8. Por qué • A veces la especificación no existe es difusa, y hay poco tiempo • Es más fácil para empezar • Si tienes código ya escrito sin tests, es la única manera de que los tenga =;-)
  9. 9. Por qué
  10. 10. Por qué • Si tu código (ya existente) no está escrito con TDD/BDD en mente, es más fácil el DDT
  11. 11. Por qué • Si tu código (ya existente) no está escrito con TDD/BDD en mente, es más fácil el DDT • Es mucho mejor que NO testear
  12. 12. Por qué • Si tu código (ya existente) no está escrito con TDD/BDD en mente, es más fácil el DDT • Es mucho mejor que NO testear • Es lo que hace DHH =;-)
  13. 13. TDD: Test Driven Development
  14. 14. TDD: Test Driven Development Escribir los tests antes de implementar el código
  15. 15. Por qué
  16. 16. Por qué • Te fuerza a pensar en el código y en su diseño antes de escribirlo
  17. 17. Por qué • Te fuerza a pensar en el código y en su diseño antes de escribirlo • Te fuerza tener contratos de interacción concretos entre los componentes de tu código
  18. 18. Por qué • Te fuerza a pensar en el código y en su diseño antes de escribirlo • Te fuerza tener contratos de interacción concretos entre los componentes de tu código • Escribir un método cuyos resultados ya conoces es más fácil que escribirlo y luego imaginar cuál será su salida
  19. 19. Por qué • Te fuerza a pensar en el código y en su diseño antes de escribirlo • Te fuerza tener contratos de interacción concretos entre los componentes de tu código • Escribir un método cuyos resultados ya conoces es más fácil que escribirlo y luego imaginar cuál será su salida • Si quieres refactorizar un método, te asegura que no vas a romper nada
  20. 20. BDD: Behaviour Driven Testing
  21. 21. BDD: Behaviour Driven Testing Escribir, antes de implementar, especificaciones que luego sirvan para testear
  22. 22. Por qué
  23. 23. Por qué • Es descriptivo
  24. 24. Por qué • Es descriptivo • Sirve de documentación (es legible por humanos normales)
  25. 25. Por qué • Es descriptivo • Sirve de documentación (es legible por humanos normales) • Ayuda a crear mejores modelos y mejores interacciones entre ellos
  26. 26. Por qué • Es descriptivo • Sirve de documentación (es legible por humanos normales) • Ayuda a crear mejores modelos y mejores interacciones entre ellos • Es más fácil de escribir
  27. 27. Patrones y buenas prácticas
  28. 28. El buen código es fácil de testear
  29. 29. El buen código es fácil de testear El código fácil de testear es bueno
  30. 30. El buen código es fácil de testear El código fácil de testear es bueno
  31. 31. Números mágicos
  32. 32. Números mágicos • Hasta 7 acciones por controlador
  33. 33. Números mágicos • Hasta 7 acciones por controlador • Hasta 10 líneas por acción
  34. 34. Números mágicos • Hasta 7 acciones por controlador • Hasta 10 líneas por acción • Si te hace falta más, sepáralo, te falta algo: • Un modelo • Un controlador • Una librería
  35. 35. Ley de Deméter
  36. 36. Ley de Deméter • “Habla sólo con tus inmediatos amigos”
  37. 37. Ley de Deméter • “Habla sólo con tus inmediatos amigos” • Un objeto debería asumir lo mínimo posible acerca de la estructura o propiedades de nada más, incluyendo sus subcomponentes
  38. 38. post.comments.map(&:owner).map(&:email) post.comments.map(&:owner_email) post.commentator_emails
  39. 39. post.comments.map(&:owner).map(&:email) post.comments.map(&:owner_email) post.commentator_emails ¡Más fácil de mockear!
  40. 40. # Mal: # # post # post.coments # post.comments.map(&:owner) # post.comments.map(&:owner).map(&:email) before(:each) do @owner = User.new @owner.stubs(:email).returns('christos@the-cocktail.com') @comment = Comment.new @comment.stubs(:owner).returns(@owner) @post = Post.new @post.stubs(:comments).returns([@comment]) end specify 'should return a list of comentator emails' do post.comments.map(&:owner).map(&:email).should.equal ['christos@the-cocktail.com'] end
  41. 41. # Bien: # # comment.owner_emails -> owners.map(&:email) # post.commentator_emails -> comments.map(&:owner_emails) # before(:each) do @post = Post.new @post.stubs.(:commentator_emails).returns(['christos@the- cocktail.com']) end specify 'should return a list of comentator emails' do post.commentator_emails.should.equal ['christos@the-cocktail.com'] end
  42. 42. @@valid_model_attributes
  43. 43. @@valid_model_attributes # en test_helper.rb @@valid_post_attributes = { :title => 'Más allá del testing', :created_at => Time.now, :text => 'Bla, bla, bla...' }
  44. 44. @@valid_model_attributes # en test_helper.rb @@valid_post_attributes = { :title => 'Más allá del testing', :created_at => Time.now, :text => 'Bla, bla, bla...' } it 'should be invalid without title' do @post = Post.new(@@valid_post_attributes.except(:title)) @post.should.not.validate end
  45. 45. La decisión es QUÉ testear
  46. 46. La decisión es QUÉ testear • No testees ActiveRecord
  47. 47. La decisión es QUÉ testear • No testees ActiveRecord • Testea las validaciones
  48. 48. La decisión es QUÉ testear • No testees ActiveRecord • Testea las validaciones • Testea las interacciones entre modelos (teniendo en cuenta la Ley de Deméter)
  49. 49. La decisión es QUÉ testear
  50. 50. La decisión es QUÉ testear • Testea siempre los casos límite
  51. 51. La decisión es QUÉ testear • Testea siempre los casos límite • Testea las vistas puntualmente
  52. 52. La decisión es QUÉ testear • Testea siempre los casos límite • Testea las vistas puntualmente • Testea los controladores teniendo en cuenta la Ley de Deméter
  53. 53. La decisión es QUÉ testear • Testea siempre los casos límite • Testea las vistas puntualmente • Testea los controladores teniendo en cuenta la Ley de Deméter • Un controlador debería manejar sólo su propio modelo
  54. 54. Algunas herramientas chulas
  55. 55. Rcov
  56. 56. Rcov
  57. 57. Rcov
  58. 58. Rcov • No es la panacea
  59. 59. Rcov • No es la panacea • Pero mola
  60. 60. Rcov • No es la panacea • Pero mola • Uso:
  61. 61. Rcov • No es la panacea • Pero mola • Uso: • Gema
  62. 62. Rcov • No es la panacea • Pero mola • Uso: • Gema • Plugin
  63. 63. Rcov • No es la panacea • Pero mola • Uso: • Gema • Plugin • Rake
  64. 64. Ojo: el test coverage despista a veces Combínalo con cosas como heckle (¡¡metatesting!!)
  65. 65. Integración contínua
  66. 66. Integración contínua • Si tienes buenos tests, tardan un rato =;-)
  67. 67. Integración contínua • Si tienes buenos tests, tardan un rato =;-) • Durante el desarrollo, sólo ejecutas los tests del código que tocas
  68. 68. Integración contínua • Si tienes buenos tests, tardan un rato =;-) • Durante el desarrollo, sólo ejecutas los tests del código que tocas • Para todo lo demás, CruiseControl.rb
  69. 69. Integración contínua
  70. 70. ¿Preguntas?
  71. 71. Muchas gracias sergio.gil@the-cocktail.com christos@the-cocktail.com the-cocktail.com

×