Agile development process in Rails crash course
Posted in Uncategorized, rails on August 17th, 2009 by Marcelo de Moraes Serpa – Be the first to commentIn sum:
- Functional Specs/Requirements -> GUI/User Interaction Mockups/Prototypes -> Stories + Scenarios -> BDD cycle (outside-in).
The BDD cycle is:
- We have a story. We create a new feature file, and a happy-path scenario. Here, ideally, we should already have at least the acceptance criteria from the client for the scenario(s).
- In this step, the agile developer should think about the story/feature and the scenarios and steps and make his judgement. If he/she thinks something is awkward, go back to the stakeholder(s) and discuss it. The story, scenarios and the acceptance criteria for each scenario are poweful tools for communicating between stakeholders and developers and they will essentially drive the development of the whole application, this is one of the most important aspects of it (Remember, the agile development process is all about *constant* communication/collaboration/feedback).
- Now, considering we have enough information to keep going and everyone is on the same page, the developer should start with the most important scenario (usually the “happy-path”) and focus on *one step at a time*. Now we are back into the BDD cycle — we run this feature with cucumber, watch the step fail and the others are skipped.
Acceptance Criteria dirty simple sample:
Scenario: Anonymous user sign ups succesfully
Given I am not logged in
And I am on the home-page
When I press sign-up
Then I should be on the sign-up page
And I should see “Please Signup!”
(…)
- If the step is non-existent, we should define it. This is the bridge between the domain language of the business and the ruby code that will build up the application. In short, a *step definition* is a method call that accepts a block of ruby code that will then use rspec/rspec-rails/webrat/selenium to setup expectations, trigger specific events or make assertions. Here are some samples:
Given “I am on the home page” do
visit “/”
endThen “I should see \”Welcome to the Jungle\”" do
response.should contain(“Welcome to the Jungle”)
endWhen “I click the signup button” do
#We can use selenium from here!
selenium.click “signup”
selenium.wait_for_popup(“popup_handler”,1000)
(…)
end
- What matters for the business analyst/stakeholders are the steps (acceptance criteria), not the step definitions, which are the developer’s responsibility.
- In the step definition we use artifacts we wish we had. We don’t have to worry about not having a specific class in the application or an element in the page, a missing route, view or page. Cucumber will tell us about missing artifacts — this is the whole point of BDD.
- So, after defining the needed step, we run cucumber again. The step probably fail, because we are exercising code that is non-existent. Take the “When I click the signup button” step. When we run it, Cucumber will try to find a “signup” anchor in the page, and and considering we are doing BDD, it won’t be there — BDD will drive us to the implementation. So the test will fail, we then add only the necessary code for it to pass. But, before that, we jump to the unit-test level. In this case, we would jump to the view spec, and add a spec that that would say something like “it should have a signup link” for the view of the homepage. We then run rspec, watch it fail, add the only the code for the example to pass. Spec is passing? Run Cucumber, is it passing? Go to the next step in the scenario. At this point, if we have a clearer understanding of what we are doing, we can refactor the code, following the same process. It is known as the “Red->Green->Refactor” mantra.
That’s it. BDD drives the creation of (almost) every artifact in the application, and in the end we have only — no more no less — what is really needed, driven from client expectations/real business value, and for free, we have a suite of automated tests (integration, functional and unit-tests) that can be used to keep the sanity of the team and the project.
Important: When a specific scenario or feature is done (All green) and the developer thinks it is in the deliverable state, ALL the tests should then be run (since when we are developing, we are usually running only the features/scenarios/specs related to what we are working on) to check if what we have done didn’t break anything else in the system. If it broke, we need to check why, touch base with the team to see how to refactor it and ALWAYS, always drive the development from the outside-in (tests->implementation).
