Thursday, October 18, 2012

DDD summary book

For those lazy or just struggling to find enough time for reading the full version of the DDD book find out this prune summary. The book is definitely worth reading for software engineers and architects. It describes the basics of modeling and how to model business processes with business goals in the first place. I consider it to be on the same shelf as Martin Fowler's book PEAA.

Wednesday, October 17, 2012

Tiny cucumber test issue

I was working on a project the other day, and out of the blue there was a failing test which was not failing before.

The cucumber test reads as follows:

Scenario: Index action (No filtering)
Given the following persons with time_submitted exist:

id email name time_submitted
1 person1@example.com person1 1347978729
2 person2@example.com person2 1346802773
When I visit "/index.json"
Then the JSON response should have 2 persons
And the JSON response at row 0:time_since_last_update should be approximately 3 week(s) ago
And the JSON response at row 1:time_since_last_update should be approximately 1 month(s) ago

The issue here is that we rely on the hardcoded value of the time submitted. And when we run out of the timeframe window the test starts failing.
To resolve the issue we need to come up with some dynamically evaluated value. Certainly, my initial attempt was to update the number with 2.weeks.ago. The test failed one more time claiming that the object is a string. That made me poke around the documentation a little bit. And what I came up is method send which allows you to execute method by name.

And so after refactoring my test input table looks so:

Scenario: Index action (No filtering)
Given the following persons with time_submitted exist:
id email name time_submitted period
1 person1@example.com person1 3 weeks
2 person2@example.com person2 1 months
When I visit "/index.json"
Then the JSON response should have 2 persons
And the JSON response at row 0:time_since_last_update should be approximately 3 week(s) ago
And the JSON response at row 1:time_since_last_update should be approximately 1 month(s) ago

and the code behind looks like
Given /the following persons with time_submitted exist:/ do |table|
  table.hashes.each do |hash|
    value = PersonAttributeRecord.new
    period = hash['period']
    number = hash['time_submitted'].to_i

// Here comes the magic
    value.submitted = number.send(period).ago

    Person.create ({:id => hash['id'], :email => hash['email'], :name => hash['name'], :time_submitted_db => value})
  end
end

So we parse the number from the table. And execute either months or weeks method (or whatever method we need) on it. And then subtract it from the current date.
That's it. Sometimes those tiny little tricks help a lot!
PS: Thanks to Kory Kraft who put a lot of effort into this little thing as well

Thursday, April 19, 2012

The good, the bad and the ugly user story.

Agile user stories
There was a great conversation on what agile user story is with one of customers last week. It's very important to be on the same page talking about user stories with a customer. A good user story gives enough information of customer's expectations to start implementing or estimating a feature. It is a manifest of an upfront conversation with a customer.

Story sections
Having that in mind let's see what a good user story should contain:
- user role (who)
- actions to perform (what)
- result achieved (why)









User role is a role of a person who will interact with a product. Say sales manager that interacts with the product will be able to sell items from the warehouse. Business owner will be able to see sales statistics and so on.

Actions to perform are actions to be performed by user to achieve expectations.
For instance: create new purchase order, edit existing line item.

Result achieved matches customer's expectations most of time. So it's what we are willing to reach.

Sample user story:
As a designer I want to be able to send arts to a customer so that a customer could examine if the job was done right and within a time frame.

Additional requirements
Based on customer's expectations we can add any additional comments or notes to the user story. We can refer to external documents from a user story as well. There are no restrictions on what should be covered in a story. People don't like some boring reading though. So I'm up to stay sharp and short writing ones.

Accomplishments
It's really important to have an acceptance criteria when you start estimation process. Such a criteria gives you a solid ground of what exactly should be delivered as an output. It can be a starting point to perform QA as well.

Tasks ordering
When we are done with user stories definition there is another thing to mention. User stories can be pulled from stack in any order. Some of stories are of higher value for a business and some are of low value. That's why it's a good practice to order user stories according to business value. Order of tasks defined by business allows to deliver the most critical tasks first.

Notes
We were able to reduce the amount of bugs created by our QA guys by 17% having development team involved in initial user stories discussion. We've pushed hard to make acceptance tests more precise as well.


User stories in agile methodology
All in all development in agile methodology starts with user stories which should provide minimal amount of information required. It's up to you what to include in a user story and what to exclude. I just wanted to provide you with a notion on what a good story should contain to make communication among parties proficient.

PS
It is really useful to have design and UX development done before actual code implementation phase.

For further reading
http://www.boost.co.nz/blog/agile/acceptance-criteria/
http://xprogramming.com/articles/expcardconversationconfirmation/
http://www.scrumalliance.org/articles/367-its-ordered--not-prioritized