Professional Documents
Culture Documents
GSyC!
2!
Contenidos!
Introduccin a Behavior Driven Design e Historias de usuarios (5.1)! Caractersticas deseables de las Historias de usuarios (5.2)! Introduccin a Cucumber y Capybara (5.3)! Ejemplo 1 de uso de Cucumber (5.4)! Bocetos de baja resolucin de la IU y Storyboards (5.5)! Ejemplo 2 de uso de Cucumber (5.6)! Requisitos explcitos vs. implcitos y Escenarios imperativos vs. declarativos (5.7)! Recomendaciones y Conclusiones (5.8-5.9)!
GSyC!
3!
Se tiene siempre un prototipo funcional al que se le van aadiendo nuevas funcionalidades en cada iteracin!
Habitualmente cada 1 o 2 semanas! En lugar de 5 fases de varios meses cada una!
GSyC!
6!
BDD se ocupa de la validacin del comportamiento de la aplicacin (QU tiene que hacer) y NO en la vericacin de la implementacin (CMO lo tiene que hacer)!
Test Driven Design (TDD) s testa la implementacin! En la prctica se va usando en cada iteracin BDD + TDD!
GSyC!
7!
empresa
El orden puede variar: Para que..Como un..Quiero! Al escribir una historia de usuario pensemos en ella como si fuera un futuro test de aceptacin que escribimos antes de programar el cdigo!
GSyC! 8!
GSyC!
11!
BDD trata de asegurarse de que el comportamiento de la aplicacin es el esperado, no de que la implementacin es la correcta BDD implica que no hay que escribir tests de aceptacin Esta es una User Story vlida: Buscar en TMDb (servicio de info sobre pelis) Quiero poder buscar en TMDb Como un aficionado al cine Para que yo pueda encontrar informacin de nuevas pelis
GSyC!
12!
SMART !
Specic (Especca) ! Measurable (Medible)! Achievable (Abordable, idealmente implementable en 1 iteracin)! Relevant (Relevante, que d respuesta a 5 por qu? relacionados con el negocio)! Timeboxed (Limitada en el tiempo: saber cundo abandonar la historia de usuario)!
GSyC! 14!
Especca!
Ejemplo de funcionalidad poco especca: El usuario puede buscar una pelcula! Ejemplo de funcionalidad especca: El usuario puede buscar una pelcula por su ttulo!
GSyC!
15!
Medible!
Medible para que cada escenario pueda ser testado!
Implica que debemos poder denir una salida esperable en funcin de una entrada correcta!
Ejemplo de funcionalidad no medible: La aplicacin debe tener un buen tiempo de respuesta! Ejemplo de funcionalidad especca: Al aadir una pelcula el 99% de las veces la pgina aparece en menos de 3 segundos!
GSyC! 16!
Abordable !
Si no se puede terminar una historia de usuario en una iteracin, se entrega un nmero menor de historias!
Siempre hay que tener como objetivo disponer de cdigo que haga algo (un subconjunto de historias) al nal de una iteracin!
17!
GSyC!
18!
Relevante: ejemplo!
Actor que responde: gerente de sala de cine! Historia de usuario: Mostrarle a un cliente sus amigos de Facebook! 1. Por qu tenemos que aadir esa funcionalidad? Como gerente de sala de cine, creo que ayudar a que ms gente venga con amigos al cine y disfruten ms de la peli! 2. Por qu importa que disfruten ms de la peli? Creo que as venderemos ms entradas! 3. Por qu quieres vender ms entradas? Porque as tenemos ms ingresos! 4. Por qu quiere tener ms ingresos el cine? Para no echar el cierre! 5. Por qu no queremos que cierre el cine? Porque si no, no tengo trabajo !
GSyC!
19!
Limitada en el tiempo!
Paramos el esfuerzo invertido en la implementacin de una historia cuando se excede el tiempo planicado para ella.!
O la abandonamos, o la dividimos en otras ms pequeas, o replanicamos el tiempo estimado.! Si dividirla no parece que ayude, hablamos con el cliente para ver qu partes son ms importantes.!
La razn para hacerlo as es que es fcil subestimar el esfuerzo del proyecto! Si no limitamos cada iteracin el proyecto global puede alargarse mucho en el tiempo, y llegar a abortarse. !
GSyC! 20!
Rotten Potatoes debe tener un tiempo de respuesta bajo Al aadir una peli, el 99% de las veces se tarda menos de 3 segundos Como cliente del cine, Quiero ver las 10 pelculas ms vendidas, ordenadas por precio, Para que yo pueda comprar las ms baratas
GSyC! 21!
Cucumber !
Herramienta SW que permite convertir las historias de usuario que pueden entender los clientes del proyecto en tests de aceptacin y de integracin!
Aceptacin: nos aseguramos de que el cliente est satisfecho! Integracin: nos aseguramos de que las interfaces entre mdulos tienen precondiciones consistentes, y se comunican correctamente. !
GSyC!
23!
GSyC!
25!
"
GSyC!
27!
Anlisis Rojo-
-Verde !
En cuanto tenemos una feature escriba ejecutamos Cucumber ! Cucumber colorea los pasos!
Verde si se ha pasado! si no est implementado todava! Rojo si ha fallado (los pasos posteriores aparecen en Blue)!
Capybara !
Cucumber usa capybara para ejecutar los tests! Capybara simula un browser!
Puede interaccionar con la aplicacin para recibir pginas! Procesa el HTML para comprobar el contenido de una pgina! Enva formularios como hara un usuario! Ejemplo de acciones: visit url, click_button, click_link, fill_in, check, uncheck, page.should ! Ver features/step_definitions/web_steps.rb
GSyC!
29!
http://pastebin.com/uzdSe9pQ :test do 'cucumber-rails' 'cucumber-rails-training-wheels' # some pre-fabbed step definitions 'database_cleaner' # to clear Cucumber's test database between runs 'capybara' # lets Cucumber pretend to be a web browser 'launchy' # a useful debugging aid for user stories rspec-expectations # for .should
Esto genera en el subdirectorio ! features/step_definitions/web_steps.rb varias deniciones de pasos (step denitions) que iremos extendiendo nosotros!
Para terminar, tenemos que inicializar, si no lo hubiramos hecho an, la base de datos de test:!
rake db:test:prepare
GSyC!
31!
Ejemplo 1 de uso de Cucumber Historia de usuario: El usuario puede aadir una peli (ELLS 5.4)!
Ejemplo !
Historia de usuario/feature: ! El usuario puede aadir una peli ! En realidad esta funcionalidad YA la hemos implementado!!
Lo hacemos para ilustrar el uso de Cucumber. Imagina que NO tenemos an implementada esa historia.!
http://pastebin.com/mqQncg1s
Scenario: Add a movie! Given I am on the RottenPotatoes home page! When I follow "Add new movie"! Then I should be on the Create New Movie page! When I fill in "Title" with "Men In Black"! And I select "PG-13" from "Rating"! And I press "Save Changes"! Then I should be on the RottenPotatoes home page! And I should see "Men In Black"!
Ejecutamos cucumber por primera vez (usamos bundle exec para que no haya interferencia con versiones de gemas externas al proyecto): bundle exec cucumber
GSyC! 34!
Given I am on the RottenPotatoes home page# features/step_definitions/web_steps.rb:44! Can't find mapping from "the RottenPotatoes home page" to a path.! Now, go and add a mapping in ./features/support/paths.rb (RuntimeError)!
./features/support/paths.rb:32:in `rescue in path_to'! ./features/support/paths.rb:26:in `path_to'! ./features/step_definitions/web_steps.rb:45:in `/^(?:|I )am on (.+)$/'! features/AddMovie.feature:4:in `Given I am on the RottenPotatoes home page'! When I follow "Add new movie" # features/step_definitions/web_steps.rb:56! Then I should be on the Create New Movie page # features/step_definitions/web_steps.rb:230! When I fill in "Title" with "Men In Black" # features/step_definitions/web_steps.rb:60! And I select "PG-13" from "Rating" # features/step_definitions/web_steps.rb:85! And I press "Save Changes" # features/step_definitions/web_steps.rb:52! Then I should be on the RottenPotatoes home page # features/step_definitions/web_steps.rb:230! And I should see "Men In Black" # features/step_definitions/web_steps.rb:105! Failing Scenarios:! cucumber features/AddMovie.feature:3 # Scenario: Add a movie! 1 scenario (1 failed)! 8 steps (1 failed, 7 skipped)! 0m1.213s!
GSyC!
35!
GSyC!
36!
Can't find mapping from "the Create New Movie page" to a path.!
Now, go and add a mapping in ./features/support/paths.rb (RuntimeError)! ./features/support/paths.rb:36:in `rescue in path_to'! ./features/support/paths.rb:30:in `path_to'! ./features/step_definitions/web_steps.rb:235:in `/^(?:|I )should be on (.+)$/'! features/AddMovie.feature:6:in `Then I should be on the Create New Movie page'! When I fill in "Title" with "Men In Black" # features/step_definitions/web_steps.rb:60! And I select "PG-13" from "Rating" # features/step_definitions/web_steps.rb:85! And I press "Save Changes" # features/step_definitions/web_steps.rb:52! Then I should be on the RottenPotatoes home page # features/step_definitions/web_steps.rb:230! And I should see "Men In Black" # features/step_definitions/web_steps.rb:105! Failing Scenarios:! cucumber features/AddMovie.feature:3 # Scenario: Add a movie! 1 scenario (1 failed)! 8 steps (1 failed, 5 skipped, 2 passed)! 0m1.730s!
GSyC!
37!
GSyC!
38!
GSyC!
39!
Una Feature tiene 1 User Stories, que estn compuestas de entre 3 y 8 Steps Los Steps utilizan Given para el estado actual, When para un evento/accin, y Then para las consecuencias de la accin Cucumber hace corresponder definiciones de steps con steps de un escenario usando expresiones regulares, y Capybara realiza el papel de un usuario que interacta con la aplicacin SaaS
GSyC! 40!
Se necesita el equivalente de las tarjetas 3x5 para negociar la IU! Bocetos (sketches): papel y bolgrafo, y quiz tijeras y pegamento: Lo-Fi UI o IU de baja resolucin!
GSyC!
42!
Ejemplo de Lo-Fi IU !
(Figura 5.3, Engineering Long Lasting Software by Armando Fox and David Patterson, Beta edition, 2012.)
GSyC!
43!
Storyboards !
Tambin necesitamos negociar con los clientes sobre la interaccin de los usuarios con la IU! Tambin del campo de la HCI (human computer interaction) => storyboards! !
Grafo de escenas/pantallas!
Ejemplo de Storyboard !
(Figura 5.4, Engineering Long Lasting Software by Armando Fox and David Patterson, Beta edition, 2012.)
GSyC!
45!
De Lo-Fi a HTML !
Es pesado hacer bocetos y storyboards, pero ms fcil que dibujar directamente HTML + CSS + Javascript !
Tambin menos intimidante para actores no tcnicos => Es ms probable que sugieran cambios a la IU si no hay que escribir cdigo ni HTML, lo pueden modicar con sus propias manos, o hacerlo t delante de ellos! Ms probable que acepten la IU que nalmente se programe!
GSyC!
46!
Ejemplo 2 de uso de Cucumber Historia de usuario: Integracin con The Movie Database (ELLS 5.6)!
Tenemos que aadir la bsqueda de pelis en TMDb a la pgina principal de Rotten Potatoes! Necesitamos escribir la feature para cucumber, un boceto de la IU LoFi y un Storyboard!
GSyC! 48!
Camino exitoso
Camino fallido
http://pastebin.com/hSgk0pEK
GSyC! 50!
Then I should see "Search TMDb for a movie # features/step_definitions/web_steps.rb:105 Failed assertion, no message given. (MiniTest::Assertion) ./features/step_definitions/web_steps.rb:109:in `/^(?:|I )should see "([^"]*)"$/' features/search_tmdb.feature:10:in `Then I should see "Search TMDb for a movie"'
When I fill in "Search Terms" with "Movie That Does Not Exist" And I press "Search TMDb" Then I should be on the RottenPotatoes home page And I should see "'Movie That Does Not Exist' was not found in TMDb." # # # # features/step_definitions/web_steps.rb:60 features/step_definitions/web_steps.rb:52 features/step_definitions/web_steps.rb:230 features/step_definitions/web_steps.rb:105
Failing Scenarios: cucumber features/search_tmdb.feature:7 # Scenario: Try to add nonexistent movie (sad path) 1 scenario (1 failed) 6 steps (1 failed, 4 skipped, 1 passed) 0m1.525s
GSyC!
51!
= form_tag :action => 'search_tmdb' do %label{:for => 'search_terms'} Search Terms = text_field_tag 'search_terms' = submit_tag 'Search TMDb'
http://pastebin.com/18yYBVbC
GSyC! 52!
El atributo for de la etiqueta label corresponde con el atributo id de la etiqueta input, que ha sido generado por el primer parmetro del tag helper text_field_tag Esta asociacin es la que permite a cucumber saber qu campo rellenar cuando en la feature escribimos: When I fill in "Search Terms" with
GSyC! 53!
GSyC!
54!
http:/pastebin.com/smwxv70i
GSyC! 56!
http://pastebin.com/FrfkF6pd
GSyC!
57!
GSyC!
58!
Cmo factorizamos? Recuerda, es bueno no repetirse (DRY -- Dont Repeat Yourself)! La seccin Background de una feature de cucumber tiene pasos comunes que se realizan antes de cada uno de los escenarios!
GSyC! 59!
http://pastebin.com/uU3fppG9
GSyC!
Scenario: Try to add existing movie (happy path) # features/search_tmdb.feature:19 When I fill in "Search Terms" with "Inception" # features/step_definitions/web_steps.rb:60 And I press "Search TMDb" # features/step_definitions/web_steps.rb:52
Then I should be on the "Search Results" page # features/step_definitions/web_steps.rb:230 Can't find mapping from "the "Search Results" page" to a path.
(RuntimeError)
GSyC!
61!
Resumen !
Nueva historia/feature (escribimos sus pasos) => IU para la feature => escribir nuevos step denitions, incluso escribir nuevos mtodos antes de que Cucumber acabe coloreando de verde los steps! La seccin Background de un escenario permite factorizar escenarios de la misma feature! Normalmente programamos antes los caminos exitosos!
aqu no lo hicimos as por razones pedaggicas! Con TDD/RSpec (prximo tema) implementamos mtodos que acaban haciendo que todos los test de validacin/integracin de Cucumber pasen!
Cierto o falso: ! ! Necesitas implementar todo el cdigo que se est testando antes de que Cucumber diga si se valida la historia de usuario
Cierto
Falso
GSyC!
64!
Requisitos explcitos vs. implcitos Escenarios imperativos vs. declarativos (ELLS 5.7)!
Los requisitos implcitos surgen como consecuencia lgica de los requisitos explcitos!
Ej: Le mostramos las pelculas en index ordenadas por precio, de menor a mayor! Cucumber genera test de integracin!
Escenarios Declarativos: hablan del comportamiento, el QU, tienen muchos menos pasos y menos genricos, relacionados con el dominio de la aplicacin! Veamos una feature como ejemplo: ! las pelis deben aparecer en orden alfabtico, no en el orden ! en el que se aadieron a la BD!
Escribiremos un escenario para esta feature: mostrar la lista de pelculas despus de aadir 2 pelculas!
GSyC! 67!
http://pastebin.com/Z7YbK8QK
GSyC!
http://pastebin.com/yL3SUraR
Necesitamos implementar las definiciones de los pasos declarativos nuevos (en rojo), antes de correr Cucumber
GSyC! 69!
Escenarios declarativos !
Los escenarios declarativos centran la atencin en el comportamiento, sus pasos tienen que ver con el dominio de la aplicacin, no con detalles de la interfaz diseada en el prototipo Los pasos declarativos son especficos a la aplicacin, no genricos, Los pasos declarativos consituyen un lenguaje de dominio de la aplicacin: I have added Zorro with rating PG-13, Veo antes Apocalypse Now que Zorro, frente a I press Save changes
GSyC! 70!
http://pastebin.com/rky95ycT
step y steps sirven para llamar a otros steps imperativos en los que nos apoyamos para implementar los steps declarativos Recuerda: %Q{xxx} == xxx Given = When = And = Then
GSyC! 71!
Then I should see "Apocalypse Now" before "Zorro" on the RottenPotatoes home page
# features/step_definitions/movie_steps.rb:10
content=\"text/html; charset=UTF-8\">\n<title>Rotten Potatoes!</title>\n<link href=\"/assets/application.css\" media=\"screen\" rel= \"stylesheet\" type=\"text/css\">\n<script src=\"/assets/application.js\" type=\"text/javascript\"></script>\n</ head>\n<body>\n<h2>All Movies</h2>\n<table id=\"movies\">\n<thead><tr>\n<th>Movie Title</th>\n<th>Rating</th> \n<th>Release Date</th>\n<th>More Info</th>\n</tr></thead>\n<tbody>\n<tr>\n<td> </td>\n<td>PG-13</td> \n<td>2012-10-16 00:00:00 UTC</td>\n<td><a href=\"/movies/1\">More about Zorro</a></td>\n</tr>\n<tr> \n<td>
Zorro
Apocalypse Now</td>
GSyC! 72!
Implementamos la ordenacin !
Ordenamos al mostrar en index.html.haml (hazlo t, es parte de la prctica :-) Ejecutamos de nuevo cucumber: bundle exec cucumber sorted_declarative.feature
Using the default profile... Feature: movies when added should appear in movie list Scenario: view movie list after adding 2 movies (declarative and DRY) # features/sorted_list_declarative.feature:3 Given I have added "Zorro" with rating "PG-13" # features/step_definitions/movie_steps.rb:1 And I have added "Apocalypse Now" with rating "R" # features/step_definitions/movie_steps.rb:1 And I am on the RottenPotatoes home page # features/step_definitions/web_steps.rb:44 Then I should see "Apocalypse Now" before "Zorro" on the RottenPotatoes home page # features/step_definitions/ movie_steps.rb:10 1 scenario (1 passed) 4 steps (4 passed) 0m1.864s
Cuidado !
No aadas funcionalidad atractiva para ti como desarrollador que no est claro si va a hacer que el producto sea ms exitoso para el cliente!
Los clientes del proyecto pueden rechazar lo que les gusta a los programadores! Las historias de usuarios ayudan a priorizar, reduciendo el esfuerzo invertido!
GSyC!
75!
Cuidado !
No intentes predecir con demasiada antelacin qu cdigo necesitas!
BDD+TDD: escribe los test antes de escribir el cdigo que necesitas, y despus escribes el cdigo que necesitas para pasar esos tests! As no necesitas predecir qu cdigo puede hacerte falta, y no escribes cdigo innecesario!
GSyC!
76!
Cuidado !
Mejor expresar pasos Then armativamente, no negativamente! Cuidado si escribes demasiadas veces Then I should not see.!
No se puede comprobar si la salida es la esperada, slo que no es la que queras! Hay demasiadas salidas que satisfacen un paso as declarado! Mejor incluir frases armativas para comprobar los resultados en un escenario: Then I should see !
GSyC! 77!
Un problema de BDD es tener que estar en contnuo contacto con los clientes, lo que no siempre es posible Un problema de BDD es que puede conducir a una arquitectura SW pobre, ya que el foco est en el comportamiento Ninguna es falsa, las tres son ciertas.
GSyC! 78!
Ventajas/Inconvenientes de BDD !
Ventaja: BDD/historias de usuarios proporciona un
lenguaje comn para todos los actores involucrados, tcnicos y no tcnicos!
Tarjetas 3x5! Bocetos Lo-Fi de la IU y storyboards! til para extraer requisitos: el cliente no siempre tiene claro qu quiere!
Inconveniente: Puede ser difcil mantener dilogo contnuo con el cliente! Inconveniente: Puede desembocar en una arquitectura
SW no muy buena!
Lo arreglaremos en parte con patrones y refactorizacin del cdigo!
GSyC! 79!
BDD !
(Figura 5.11, Engineering Long Lasting Software by Armando Fox and David Patterson, Beta edition, 2012.)
BDD+TDD no resulta natural al principio! Las herramientas de Rails hacen fcil seguir BDD+TDD! Cada vez ms gente en la industria utiliza TDD, BDD+TDD!
GSyC! 80!
Referencias !
http://cukes.info/!
GSyC!
81!