Story Driven Web Development

Preview:

DESCRIPTION

A presentation delivered to the open source developer conference in Sydney, December 2008

Citation preview

STORY DRIVENWEB DEVELOPMENT

MICHAEL KOUKOULLISPROGRAMMER

DESIGNBUILDWEB APPLICATIONS

STYLE OF DEVELOPMENTSET OF TOOLS

STORY DRIVEN DEVELOPMENTWE FIND USEFUL

CODERUBYRAILSCUCUMBERHAPPY HAPPY SAD

WHAT I REALLY WANT?WHY IT WORKS FOR US!

EVOLVING METHODDELIVERING BETTER SOFTWARE

ELEGANCEENJOYABLE

STANDS ON ITS FEETCREATIVE

FOCUS. PEOPLE. TOOLS.

ON WITH THE SHOWSTORY DRIVEN DEVELOPMENT

EXAMPLE. FEATURE.

Feature: Article tags In order to work with article tags As a site user I want to both create and delete tags

EXAMPLE. FEATURE.

Scenario: Creating a tag Given an article exists with no tags When I submit a new tag for the article Then the article should have one tag And I am redirected to the article

EXAMPLE. FEATURE.

Scenario: Creating a tag Given an article exists with no tags When I submit a new tag for the article Then the article should have one tag And I am redirected to the article Scenario: Deleting a tag Given an article exists with one tag When I delete the article tag Then the article should have no tags And I am redirected to the article

Feature: Article tags In order to work with article tags As a site user I want to both create and delete tags

Scenario: Creating a tag Given an article exists with no tags When I submit a new tag for the article Then the article should have one tag And I am redirected to the article Scenario: Deleting a tag Given an article exists with one tag When I delete the article tag Then the article should have no tags And I am redirected to the article

EXAMPLE. FEATURE.

DECLARATION OF INTENTIONNATURAL LANGUAGEIMMENSELY POWERFUL

BEST THING YOU CAN DO AS A PROGRAMMER?CODE LESS.

Feature: Article tags In order to work with article tags As a site user I want to both create and delete tags

Scenario: Creating a tag Given an article exists with no tags When I submit a new tag for the article Then the article should have one tag And I am redirected to the article Scenario: Deleting a tag Given an article exists with one tag When I delete the article tag Then the article should have no tags And I am redirected to the article

EXAMPLE. FEATURE.

WRITE PROSE

ITS EXECUTABLE!

AVOID GETTING PROGRAMMATICMAKE IT A ‘REAL’ STORY

WORKFLOWRUNNING THE STORY

FEATURE. RUNNER.

DEFINING. STEPS.

DEFINING. MODELS.

DEFINING. MODELS.class Article < ActiveRecord::Base has_many :taggings, :dependent => :destroy has_many :tags, :through => :taggings

def add_tag(value) new_tag = Tag.find_or_create_by_name(value) unless Tagging.exists?(:article_id => self.id, :tag_id => new_tag) taggings.create(:tag => new_tag) end endend

DEFINING. MODELS.class Article < ActiveRecord::Base has_many :taggings, :dependent => :destroy has_many :tags, :through => :taggings

def add_tag(value) new_tag = Tag.find_or_create_by_name(value) unless Tagging.exists?(:article_id => self.id, :tag_id => new_tag) taggings.create(:tag => new_tag) end endend

class Tagging < ActiveRecord::Base belongs_to :tag belongs_to :articleend

DEFINING. MODELS.class Article < ActiveRecord::Base has_many :taggings, :dependent => :destroy has_many :tags, :through => :taggings

def add_tag(value) new_tag = Tag.find_or_create_by_name(value) unless Tagging.exists?(:article_id => self.id, :tag_id => new_tag) taggings.create(:tag => new_tag) end endend

class Tagging < ActiveRecord::Base belongs_to :tag belongs_to :articleend

class Tag < ActiveRecord::Base has_many :taggingsend

RERUNNING. FEATURE.

DEFINING. ROUTES.

ActionController::Routing::Routes.draw do |map| map.home "", :controller => "pages", :action => "home" map.resources :articles do |article| article.resources :taggings endend

RERUNNING. FEATURE.

DEFINING. CONTROLERS.

class TaggingsController < ApplicationController def create article = Article.find(params[:article_id]) article.add_tag(params[:tags]) redirect_to article_path(article) end def destroy article = Article.find(params[:article_id]) tagging = article.taggings.find(params[:id]) tagging.destroy redirect_to article_path(article) endend

RERUNNING. FEATURE. SUCCESS!

JUST IN TIMEAPP DEVWORKFLOW

SHARED STEPSREGEXDRY IT UP

DRY IT UP. REGEX MATCHING.

Given /^an article exists with no tags$/ do @article = Article.create!(:title => "Beautiful Evidence")end

Given /^an article exists with one tag$/ do @article = Article.create!(:title => "Beautiful Evidence") @tag = Tag.create!(:name => "visualisation") @tagging = @article.taggings.create!(:tag => @tag)end

DRY IT UP. REGEX MATCHING.

Given /^an article exists with no tags$/ do @article = Article.create!(:title => "Beautiful Evidence")end

Given /^an article exists with one tag$/ do @article = Article.create!(:title => "Beautiful Evidence") @tag = Tag.create!(:name => "visualisation") @tagging = @article.taggings.create!(:tag => @tag)end

Given /^an article exists with (\d+) tags$/ do |num| @article = Article.create!(:title => "Beautiful Evidence") num.to_i.times do |num| @tag = Tag.create!(:name => "random-tag-#{num}") @tagging = @article.taggings.create!(:tag => @tag) endend

DRY IT UP. REGEX MATCHING.

Then /^the article should have one tag$/ do @article.taggings.length.should == 1end

Then /^the article should have no tags$/ do @article.taggings.length.should == 0end

DRY IT UP. REGEX MATCHING.

Then /^the article should have one tag$/ do @article.taggings.length.should == 1end

Then /^the article should have no tags$/ do @article.taggings.length.should == 0end

Then /^the article should have (\d+) tags$/ do |num| @article.taggings.length.should == num.to_iend

DRY IT UP. REGEX MATCHING.Feature: Article tags In order to work with article tags As a site user I want to both create and delete tags

Scenario: Creating a tag Given an article exists with no tags When I submit a new tag for the article Then the article should have one tag And I am redirected to the article Scenario: Deleting a tag Given an article exists with one tag When I delete the article tag Then the article should have no tags And I am redirected to the article

DRY IT UP. REGEX MATCHING.

Given an article exists with 0 tags

Given an article exists with 1 tags

Then the article should have 0 tags

Then the article should have 1 tags

WHAT ABOUT VIEWS?RESPONSE.SHOULDWEBRAT

VIEWS. RESPONSE.SHOULD

Feature: Viewing an article In order to read an article As a site user I want access the article Scenario: Viewing an article Given an article exists with 1 tags When I view the article Then I should see the page And I should see the article title And I should see the article tag

VIEWS. RESPONSE.SHOULDWhen /^I view the article$/ do get article_path(@article)end

Then /^I should see the page$/ do response.should be_successend

Then /^I should see the article title$/ do response.should include_text(@article.title)end

Then /^I should see the article tag$/ do response.should include_text(@tag.name)end

VIEWS. WEBRATScenario: Submitting the add tag form Given an article exists with 0 tags When I visit the article page And I submit the tag form with 'edward' Then I am redirected to the article And the article should have 1 tags And the article should be tagged with 'edward'

VIEWS. WEBRATScenario: Submitting the add tag form Given an article exists with 0 tags When I visit the article page And I submit the tag form with 'edward' Then I am redirected to the article And the article should have 1 tags And the article should be tagged with 'edward'

When /^I visit the article page$/ do visit article_path(@article)end

When /^I submit the tag form with '(\w+)'$/ do |value| fill_in "tags", :with => value click_button "submit"end

Then /^the article should be tagged with '(\w+)'$/ do |value| @article.tags.map(&:name).include?(value).should be_trueend

STORY DRIVEN DEVELOPMENTNATURAL LANGUAGE SPECSELEGANTCHANCE TO CODE LESSENJOYABLE

YOUTHANK

MICHAEL KOUKOULLIStwitter: koukyemail : m@agencyrainford.com

Recommended