Archive for August, 2009

Agile development process in Rails crash course

Posted in Uncategorized, rails on August 17th, 2009 by Marcelo de Moraes Serpa – Be the first to comment

In 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 “/”
end

Then “I should see \”Welcome to the Jungle\”" do
response.should contain(“Welcome to the Jungle”)
end

When “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).

Mocks and stubs demystified

Posted in Uncategorized on August 12th, 2009 by Marcelo de Moraes Serpa – Be the first to comment

My co-worker and good friend of mine, Ignácio de La Madrid, just pointed out a very concise definition of Mocks and Stubs he saw in the “How I learned to love testing” presentation from the guys at RailsEnvy.

So, they put it as:

Stub: A function with a canned response
Mock: An object with canned responses.

Couldn’t get any simpler than that.

It’s worth it to view the presentation. The definition you see here is presented at around 26″ minutes in the video.

Handling agile shared lists efficiently

Posted in Uncategorized, café on August 12th, 2009 by Marcelo de Moraes Serpa – Be the first to comment

In the project I am working on I saw a task in acunote that said something like:

“Create the new roles in the database.”

Might seem reasonable, but, what roles? Why create these roles? What is the business value of that? If it doesn’t have a direct business value, what feature has this action as a child? Does it have value to have this item in this shared list, or in other words, is it worth it to communicate to other team members this item or can I handle it in my personal todo list?

You could, of course, put sub-actions such as
– create the admin role
– create the client role
(…)

But this would be micro-managing, and micro-managing is not good in an agile environment. We don’t want that!

This is a pattern I have been seeing across shared lists everywhere. There are lists of stories, then sub-stories and actions (solid, visible, tangible actions) spread around, without any seemingly structure.

Too much structure is not good, but not structure is no good either.

I’m not saying this is wrong. I’m a GTD proponent and I like the idea of having a pre-processed/pre-organized list of next actions to work upon. The thing is that GTD is a model for personal information management system’s implementation, and when we are talking about a shared list of items in the context of an agile software project, do the same rules apply?

I don’t think so…

I’m still not sure what is the best way of even if there is a best way. But I feel that, in “agile shared lists” (like acunote) you should have only list of epics and features. Actions like “Create database…”, “Talk to…” might be there (even though I would prefer not to have them there), but only as a sub-item of a feature. It’s all about context.

And it gets even more complicated in the sense that if you are following BDD, you won’t want to pre-process like you do with GTD — because you will discover your next steps as you go through the BDD process.

A feature is a project in the GTD sense, but GTD is a model for personal productivity system, and BDD is a development process. Software development is too dynamic and complex to try to have all the pre-processed actions beforehand, there are variables and constants that are very different from the ones that apply to GTD.

So, what I am saying is that, since the acunote shared-lists (backlog, sprints) are components of the agile development methodology, we should be using agile and its components as a base for rules on how to structure/define its items. They are not a simple todo list, per se.

I think that, GTD and Agile dev. process/project management are in different levels of abstraction, and can be used in parallel.

But this is open to discussion, I would really like to know the opinion from other knowledge workers/developers around!