SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
STORY DRIVEN
WEB DEVELOPMENT
MICHAEL KOUKOULLIS
PROGRAMMER
DESIGN
BUILD
WEB APPLICATIONS
STYLE OF DEVELOPMENT
SET OF TOOLS
WE FIND USEFUL
STORY DRIVEN DEVELOPMENT
CODE
RUBY
RAILS
CUCUMBER
HAPPY HAPPY SAD
WHAT I REALLY WANT?
WHY IT WORKS FOR US!
EVOLVING METHOD
DELIVERING BETTER SOFTWARE
ELEGANCE
ENJOYABLE
CREATIVE
STANDS ON ITS FEET
FOCUS. PEOPLE. TOOLS.
ON WITH THE SHOW
STORY 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
EXAMPLE. FEATURE.
 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
DECLARATION OF INTENTION
NATURAL LANGUAGE
IMMENSELY POWERFUL
BEST THING YOU CAN DO AS A
PROGRAMMER?
CODE LESS.
EXAMPLE. FEATURE.
 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
WRITE PROSE
AVOID GETTING PROGRAMMATIC
MAKE IT A ‘REAL’ STORY
ITS EXECUTABLE!
WORKFLOW
RUNNING 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
  end
end
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
  end
end

class Tagging < ActiveRecord::Base
  belongs_to :tag
  belongs_to :article
end
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
  end
end

class Tagging < ActiveRecord::Base
  belongs_to :tag
  belongs_to :article
end

class Tag < ActiveRecord::Base
  has_many :taggings
end
RERUNNING. FEATURE.
DEFINING. ROUTES.
ActionController::Routing::Routes.draw do |map|
  map.home quot;quot;, :controller => quot;pagesquot;, :action => quot;homequot;

  map.resources :articles do |article|
    article.resources :taggings
  end
end
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)
  end
end
RERUNNING. FEATURE. SUCCESS!
JUST IN TIME
APP DEV
WORKFLOW
SHARED STEPS
REGEX
DRY IT UP
DRY IT UP. REGEX MATCHING.
Given /^an article exists with no tags$/ do
  @article = Article.create!(:title => quot;Beautiful Evidencequot;)
end

Given /^an article exists with one tag$/ do
  @article = Article.create!(:title => quot;Beautiful Evidencequot;)
  @tag = Tag.create!(:name => quot;visualisationquot;)
  @tagging = @article.taggings.create!(:tag => @tag)
end
DRY IT UP. REGEX MATCHING.
Given /^an article exists with no tags$/ do
  @article = Article.create!(:title => quot;Beautiful Evidencequot;)
end

Given /^an article exists with one tag$/ do
  @article = Article.create!(:title => quot;Beautiful Evidencequot;)
  @tag = Tag.create!(:name => quot;visualisationquot;)
  @tagging = @article.taggings.create!(:tag => @tag)
end
Given /^an article exists with (d+) tags$/ do |num|
  @article = Article.create!(:title => quot;Beautiful Evidencequot;)
  num.to_i.times do |num|
    @tag = Tag.create!(:name => quot;random-tag-#{num}quot;)
    @tagging = @article.taggings.create!(:tag => @tag)
  end
end
DRY IT UP. REGEX MATCHING.
Then /^the article should have one tag$/ do
  @article.taggings.length.should == 1
end

Then /^the article should have no tags$/ do
  @article.taggings.length.should == 0
end
DRY IT UP. REGEX MATCHING.
Then /^the article should have one tag$/ do
  @article.taggings.length.should == 1
end

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

Then /^the article should have (d+) tags$/ do |num|
  @article.taggings.length.should == num.to_i
end
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

  Then the article should have 1 tags




  Given an article exists with 1 tags

  Then the article should have 0 tags
WHAT ABOUT VIEWS?
RESPONSE.SHOULD
WEBRAT
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.SHOULD
When /^I view the article$/ do
  get article_path(@article)
end

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

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. WEBRAT
Scenario: 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. WEBRAT
Scenario: 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 quot;tagsquot;, :with => value
  click_button quot;submitquot;
end

Then /^the article should be tagged with '(w+)'$/ do |value|
  @article.tags.map(&:name).include?(value).should be_true
end
STORY DRIVEN DEVELOPMENT
NATURAL LANGUAGE SPECS
ELEGANT
CHANCE TO CODE LESS
ENJOYABLE
THANK
YOU
MICHAEL KOUKOULLIS
twitter: kouky
email : m@agencyrainford.com

Mais conteúdo relacionado

Mais procurados

Take a stand_citingsources
Take a stand_citingsourcesTake a stand_citingsources
Take a stand_citingsourceshmfowler
 
How to build testable UIs
How to build testable UIsHow to build testable UIs
How to build testable UIsShi Ling Tai
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsEPAM Systems
 
Introduction to Ruby On Rails
Introduction to Ruby On RailsIntroduction to Ruby On Rails
Introduction to Ruby On RailsPiotr Imbierowicz
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with RailsJames Gray
 
Haml, Sass and Compass for Sane Web Development
Haml, Sass and Compass for Sane Web DevelopmentHaml, Sass and Compass for Sane Web Development
Haml, Sass and Compass for Sane Web Developmentjeremyw
 
Double page spread screenshots
Double page spread screenshotsDouble page spread screenshots
Double page spread screenshotsmichodgo
 
Build and deploy Python Django project
Build and deploy Python Django projectBuild and deploy Python Django project
Build and deploy Python Django projectXiaoqi Zhao
 

Mais procurados (9)

Take a stand_citingsources
Take a stand_citingsourcesTake a stand_citingsources
Take a stand_citingsources
 
How to build testable UIs
How to build testable UIsHow to build testable UIs
How to build testable UIs
 
Jquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript BasicsJquery Complete Presentation along with Javascript Basics
Jquery Complete Presentation along with Javascript Basics
 
Introduction to Ruby On Rails
Introduction to Ruby On RailsIntroduction to Ruby On Rails
Introduction to Ruby On Rails
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with Rails
 
Haml, Sass and Compass for Sane Web Development
Haml, Sass and Compass for Sane Web DevelopmentHaml, Sass and Compass for Sane Web Development
Haml, Sass and Compass for Sane Web Development
 
Double page spread screenshots
Double page spread screenshotsDouble page spread screenshots
Double page spread screenshots
 
Build and deploy Python Django project
Build and deploy Python Django projectBuild and deploy Python Django project
Build and deploy Python Django project
 
Anchors!
Anchors!Anchors!
Anchors!
 

Semelhante a Story Driven Web Development

Advanced Views with Erector
Advanced Views with ErectorAdvanced Views with Erector
Advanced Views with ErectorAlex Chaffee
 
Markdown tutorial how to add markdown to rails app using redcarpet and codera...
Markdown tutorial how to add markdown to rails app using redcarpet and codera...Markdown tutorial how to add markdown to rails app using redcarpet and codera...
Markdown tutorial how to add markdown to rails app using redcarpet and codera...Katy Slemon
 
Powerful Generic Patterns With Django
Powerful Generic Patterns With DjangoPowerful Generic Patterns With Django
Powerful Generic Patterns With DjangoEric Satterwhite
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubclammyhysteria698
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubclammyhysteria698
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubludicrousexcerp10
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsuccessfuloutdo12
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsomberfan2012
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubludicrousexcerp10
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsomberfan2012
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsomberfan2012
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsuccessfuloutdo12
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsuccessfuloutdo12
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubclammyhysteria698
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsomberfan2012
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubflagrantlawsuit53
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubsomberfan2012
 
django-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Indexdjango-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Indexflagrantlawsuit53
 

Semelhante a Story Driven Web Development (20)

Advanced Views with Erector
Advanced Views with ErectorAdvanced Views with Erector
Advanced Views with Erector
 
Markdown tutorial how to add markdown to rails app using redcarpet and codera...
Markdown tutorial how to add markdown to rails app using redcarpet and codera...Markdown tutorial how to add markdown to rails app using redcarpet and codera...
Markdown tutorial how to add markdown to rails app using redcarpet and codera...
 
Powerful Generic Patterns With Django
Powerful Generic Patterns With DjangoPowerful Generic Patterns With Django
Powerful Generic Patterns With Django
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
idlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHubidlesign/django-sitecats · GitHub
idlesign/django-sitecats · GitHub
 
Tfbyoweb.4.9.17
Tfbyoweb.4.9.17Tfbyoweb.4.9.17
Tfbyoweb.4.9.17
 
Tfbyoweb.4.9.17
Tfbyoweb.4.9.17Tfbyoweb.4.9.17
Tfbyoweb.4.9.17
 
django-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Indexdjango-sitecats 0.4.0 : Python Package Index
django-sitecats 0.4.0 : Python Package Index
 

Último

The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 

Último (20)

The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 

Story Driven Web Development

  • 3.
  • 5. STYLE OF DEVELOPMENT SET OF TOOLS WE FIND USEFUL STORY DRIVEN DEVELOPMENT
  • 7. WHAT I REALLY WANT? WHY IT WORKS FOR US!
  • 9.
  • 12. ON WITH THE SHOW STORY DRIVEN DEVELOPMENT
  • 13. EXAMPLE. FEATURE. Feature: Article tags In order to work with article tags As a site user I want to both create and delete tags
  • 14. 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
  • 15. 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
  • 16. EXAMPLE. FEATURE. 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
  • 17. DECLARATION OF INTENTION NATURAL LANGUAGE IMMENSELY POWERFUL
  • 18. BEST THING YOU CAN DO AS A PROGRAMMER? CODE LESS.
  • 19. EXAMPLE. FEATURE. 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
  • 20. WRITE PROSE AVOID GETTING PROGRAMMATIC MAKE IT A ‘REAL’ STORY ITS EXECUTABLE!
  • 25. 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 end end
  • 26. 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 end end class Tagging < ActiveRecord::Base belongs_to :tag belongs_to :article end
  • 27. 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 end end class Tagging < ActiveRecord::Base belongs_to :tag belongs_to :article end class Tag < ActiveRecord::Base has_many :taggings end
  • 29. DEFINING. ROUTES. ActionController::Routing::Routes.draw do |map| map.home quot;quot;, :controller => quot;pagesquot;, :action => quot;homequot; map.resources :articles do |article| article.resources :taggings end end
  • 31. 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) end end
  • 33. JUST IN TIME APP DEV WORKFLOW
  • 35. DRY IT UP. REGEX MATCHING. Given /^an article exists with no tags$/ do @article = Article.create!(:title => quot;Beautiful Evidencequot;) end Given /^an article exists with one tag$/ do @article = Article.create!(:title => quot;Beautiful Evidencequot;) @tag = Tag.create!(:name => quot;visualisationquot;) @tagging = @article.taggings.create!(:tag => @tag) end
  • 36. DRY IT UP. REGEX MATCHING. Given /^an article exists with no tags$/ do @article = Article.create!(:title => quot;Beautiful Evidencequot;) end Given /^an article exists with one tag$/ do @article = Article.create!(:title => quot;Beautiful Evidencequot;) @tag = Tag.create!(:name => quot;visualisationquot;) @tagging = @article.taggings.create!(:tag => @tag) end Given /^an article exists with (d+) tags$/ do |num| @article = Article.create!(:title => quot;Beautiful Evidencequot;) num.to_i.times do |num| @tag = Tag.create!(:name => quot;random-tag-#{num}quot;) @tagging = @article.taggings.create!(:tag => @tag) end end
  • 37. DRY IT UP. REGEX MATCHING. Then /^the article should have one tag$/ do @article.taggings.length.should == 1 end Then /^the article should have no tags$/ do @article.taggings.length.should == 0 end
  • 38. DRY IT UP. REGEX MATCHING. Then /^the article should have one tag$/ do @article.taggings.length.should == 1 end Then /^the article should have no tags$/ do @article.taggings.length.should == 0 end Then /^the article should have (d+) tags$/ do |num| @article.taggings.length.should == num.to_i end
  • 39. 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
  • 40. DRY IT UP. REGEX MATCHING. Given an article exists with 0 tags Then the article should have 1 tags Given an article exists with 1 tags Then the article should have 0 tags
  • 42. 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
  • 43. VIEWS. RESPONSE.SHOULD When /^I view the article$/ do get article_path(@article) end Then /^I should see the page$/ do response.should be_success end 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
  • 44. VIEWS. WEBRAT Scenario: 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'
  • 45. VIEWS. WEBRAT Scenario: 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 quot;tagsquot;, :with => value click_button quot;submitquot; end Then /^the article should be tagged with '(w+)'$/ do |value| @article.tags.map(&:name).include?(value).should be_true end
  • 46. STORY DRIVEN DEVELOPMENT NATURAL LANGUAGE SPECS ELEGANT CHANCE TO CODE LESS ENJOYABLE
  • 48. MICHAEL KOUKOULLIS twitter: kouky email : m@agencyrainford.com