SlideShare una empresa de Scribd logo
1 de 48
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

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
 

La actualidad más candente (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!
 

Similar 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
 

Similar 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

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
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxfnnc6jmgwh
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
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
 
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
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
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
 
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
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
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
 

Último (20)

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
 
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptxGenerative AI - Gitex v1Generative AI - Gitex v1.pptx
Generative AI - Gitex v1Generative AI - Gitex v1.pptx
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
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
 
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...
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
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
 
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
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
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...
 

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