Top Banner
Moving away from legacy code with BDD
119

Moving away from legacy code with BDD

Sep 08, 2014

Download

Technology

Greenfield projects are awesome – you can develop highest quality application using best practices on the market. But what if your bread actually is Legacy projects? Does it mean that you need to descend into darkness of QA absence? This talk will show you how to be successful even with the oldest legacy projects out there through the introduction of Agile processes and tools like Behat.
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Moving away from legacy code with BDD

Moving away from legacy code

with BDD

Page 2: Moving away from legacy code with BDD

Who?!

BDD Evangelist !

BDD Practice Manager @Inviqa !

Creator of Behat, Mink, PhpSpec2, Prophecy

!Contributor to Symfony2, Composer

!Host of the “Elephant in the Room”

podcast

Page 3: Moving away from legacy code with BDD

This talk is about

• Solving purely technical “TCIAM” problem with agile business analysis and discovery processes

• Building a delivery strategy on the idea of constant change

• Real-life experience

Page 4: Moving away from legacy code with BDD

This talk is not about

• Greenfield projects

• Solutions for everyone

• How to write code

Page 5: Moving away from legacy code with BDD

This talk is not about

• Greenfield projects

• Maintenance-mode projects

• Solutions for everyone

• How to write code (well, mostly)

Page 6: Moving away from legacy code with BDD

Legacy projects

Page 7: Moving away from legacy code with BDD

How most developers see their next project

Page 8: Moving away from legacy code with BDD

My next project

Page 9: Moving away from legacy code with BDD

My next project

His actual next project

Page 10: Moving away from legacy code with BDD

Agile, TDD, BDD, General QA, etc…

// TODO: refactor this later

Page 11: Moving away from legacy code with BDD

Is it really that bad?

Page 12: Moving away from legacy code with BDD

If the project can afford at least one full-time specialist on a payroll that whines how horrible this project is, then surely it did something right.

Page 13: Moving away from legacy code with BDD

// TODO: refactor this later

Page 14: Moving away from legacy code with BDD

// TODO: refactor this later

Page 15: Moving away from legacy code with BDD

// TODO: refactor this later

Page 16: Moving away from legacy code with BDD

This world is full of brilliant projects that nobody wants to whine about. Sadly, it’s often simply because there’s no one left to pay for that.

Page 17: Moving away from legacy code with BDD

The truth is: You deliver value!

Just not as effectively as you could

Page 18: Moving away from legacy code with BDD

// TODO: refactor this later

Agile, TDD, BDD, General QA, etc…

Page 19: Moving away from legacy code with BDD

How?

Page 20: Moving away from legacy code with BDD

Three options

1. Rewrite an entire application using “the right way”

2. Do functional refactoring

3. Do business-oriented rewrite using “BDD pipeline”

Page 21: Moving away from legacy code with BDD

#1: Full Rewrite

Page 22: Moving away from legacy code with BDD

#1: Full Rewrite

• Scrum / Kanban

• TDD / BDD / DDD / Pair-programming

• New everything

• Mirroring functionality

Page 23: Moving away from legacy code with BDD

#1: Income

Page 24: Moving away from legacy code with BDD

6 Months later…

Page 25: Moving away from legacy code with BDD

#1: Almost there…

Page 26: Moving away from legacy code with BDD

#1: Full Rewrite

Just spaghetti, please: 4 man years

Full London meal (TDD, BDD, Agile, QA): ??? man years

Page 27: Moving away from legacy code with BDD

#2: FUNCTIONAL Refactoring

Page 28: Moving away from legacy code with BDD

#2: Functional Refactoring

• Blackbox testing

• New routing

• New templating system

• Migration of model layer (MySQL -> Mongo)

Page 29: Moving away from legacy code with BDD

#2: Income

Page 30: Moving away from legacy code with BDD

6 Months later…

Page 31: Moving away from legacy code with BDD

#2: Ta-da!!!

Page 32: Moving away from legacy code with BDD

– Your client. (most likely)

“Exactly what did you do here?”

Page 33: Moving away from legacy code with BDD

#3: BDD PIPELINEAKA Business-Oriented rewrite

Page 34: Moving away from legacy code with BDD

Why do some legacy projects suck?

Page 35: Moving away from legacy code with BDD

Cost

Time

Because of the cost of change

Page 36: Moving away from legacy code with BDD

… Of change where?

Page 37: Moving away from legacy code with BDD

Why do applications change?

Page 38: Moving away from legacy code with BDD

Welcome to the wonderland

of Agile Business Analysis

Page 39: Moving away from legacy code with BDD

Questionnaire

1. What is the goal and minimal valuable product?

2. What is the minimal set of features to support it?

3. Which features are more likely to change?

4. How fully those features should be implemented?

5. How to avoid gold plating?

Page 40: Moving away from legacy code with BDD

“BDD Pipeline”

1. Impact Mapping

2. Feature Mapping

3. Prioritisation

4. Example Workshop

5. Full-stack BDD

Page 41: Moving away from legacy code with BDD

1. What is the Goal & minimal valuable product?

Impact Mapping

Page 42: Moving away from legacy code with BDD

– Gojko Adzic

“Impact mapping is a strategic planning technique that prevents organisations from getting lost

while building products and delivering projects, by clearly communicating assumptions, helping teams align their activities with overall business objectives and make better roadmap decisions.”

Page 43: Moving away from legacy code with BDD

Four levels of Impact Map

1. Why? are we doing all this (rewrite)? What is the goal we’re trying to achieve?

2. Who? will be impacted by it?

3. How? can they help us to achieve the goal?

4. What? can we do to support them?

Page 44: Moving away from legacy code with BDD
Page 45: Moving away from legacy code with BDD

MVP

Page 46: Moving away from legacy code with BDD

impactmapping.org

Page 47: Moving away from legacy code with BDD

2. What is the minimal set of features to support it?

Feature Mapping

Page 48: Moving away from legacy code with BDD

– Marcello Duarte

“Feature mapping is a backlog grooming technique. It is a graphical process which helps teams in finding features that are necessary to

support discovered MVP”

Page 49: Moving away from legacy code with BDD

Three levels of feature map

1. What? is the minimal marketable feature?

2. Who? will be impacted by this feature?

3. What? particular parts of this feature do they need to create this impact?

Page 50: Moving away from legacy code with BDD
Page 51: Moving away from legacy code with BDD

Product Backlog

Page 52: Moving away from legacy code with BDD
Page 53: Moving away from legacy code with BDD

In order to buy more products As a customer I need to have a product autocompletion in the search field

Page 54: Moving away from legacy code with BDD

3. Which features are more likely to change?

Prioritisation workshop

Page 55: Moving away from legacy code with BDD

In order to maintain my shopping history As a site visitor I need to be able to register on this site

Page 56: Moving away from legacy code with BDD

In order to maintain my shopping history As a site visitor I need to be able to register on this site

benefit !actor

Page 57: Moving away from legacy code with BDD

SELECT s.* FROM backlog as s ORDER BY s.role, s.benefit LIMIT 25

Page 58: Moving away from legacy code with BDD

4. How fully those features should be implemented?

Example workshops

Page 59: Moving away from legacy code with BDD

Three layers of a User-Story

• Business rule(s)

• Communication

• Acceptance criteria

Page 60: Moving away from legacy code with BDD

Three layers of a User-Story

• Business rule(s) == Acceptance criteria

• Communication

Page 61: Moving away from legacy code with BDD

Three layers of a User-Story

• Business rule(s) == Acceptance criteria

• Communication == Examples

Page 62: Moving away from legacy code with BDD

Three layers of a User-Story

• Business rule(s)

• Communication == Examples == Acceptance criteria

Page 63: Moving away from legacy code with BDD

in order to maintain my shopping history as a site visitor i need to be able to register on this site

Feature: registration

Page 64: Moving away from legacy code with BDD

in order to maintain my shopping history as a site visitor i need to be able to register on this site

Feature: registration

Scenario: Successful registration when visitor provides all the required info

Page 65: Moving away from legacy code with BDD

in order to maintain my shopping history as a site visitor i need to be able to register on this site

Feature: registration

Scenario: Successful registration when visitor provides all the required info

Scenario: Unable to register when visitor misses required info

Page 66: Moving away from legacy code with BDD

in order to maintain my shopping history as a site visitor i need to be able to register on this site

Feature: registration

Scenario: Successful registration when visitor provides all the required info

Scenario: Unable to register when visitor misses required info

Scenario: ...

Page 67: Moving away from legacy code with BDD

Scenario: ...

Scenario: ...

Scenario: ...

Scenario: ...

in order to maintain my shopping history as a site visitor i need to be able to register on this site

Feature: registration

Scenario: Successful registration when visitor provides all the required info

Scenario: Unable to register when visitor misses required info

Scenario: ...

Page 68: Moving away from legacy code with BDD

in order to maintain my shopping history as a site visitor i need to be able to register on this site

Feature: registration

Scenario: Successful registration when visitor provides all the required info

Given I am on the homepage When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 69: Moving away from legacy code with BDD

5. How to avoid gold plating?

Delivery

Page 70: Moving away from legacy code with BDD

Architecture

Page 71: Moving away from legacy code with BDD

ArchitectureHTTP layering

Page 72: Moving away from legacy code with BDD

Legacy system

Infrastructure

[GET] /products

Page 73: Moving away from legacy code with BDD

Legacy system

Infrastructure

[GET] /products

[GET] /products/123

Page 74: Moving away from legacy code with BDD

Legacy system

Infrastructure

[GET] /products

[GET] /products/123

New system

Page 75: Moving away from legacy code with BDD

Legacy system

Infrastructure

[GET] /products

[GET] /products/123

New system

New system

Page 76: Moving away from legacy code with BDD

Implementation

Page 77: Moving away from legacy code with BDD

ImplementationFull-stack BDD

Page 78: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Page 79: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Scenario-BDD

Page 80: Moving away from legacy code with BDD

in order to maintain my shopping history as a site visitor i need to be able to register on this site

Feature: registration

Scenario: Successful registration when visitor provides all the required info

Given I am on the homepage When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 81: Moving away from legacy code with BDD

in orderas ai need

Feature:

Scenario: Successful registration when visitor provides

Given I am on the When And I fill in And I submit itThen And I should be on the homepage

What could be automated should be automated

Page 82: Moving away from legacy code with BDD
Page 83: Moving away from legacy code with BDD

assertEquals(Your Feature, Your App)

Page 84: Moving away from legacy code with BDD

Setup

1. Dump your sprint features into text files

2. Put those text files into the `features/` folder inside project

3. Install behat (via composer or behat.phar)

4. Initialize behat test suite by running `bin/behat —init`

Page 85: Moving away from legacy code with BDD

Feature Context<?php !use Behat\Behat\Context\ClosuredContextInterface, Behat\Behat\Context\TranslatedContextInterface, Behat\Behat\Context\BehatContext, Behat\Behat\Exception\PendingException; use Behat\Gherkin\Node\PyStringNode, Behat\Gherkin\Node\TableNode; !class FeatureContext extends BehatContext { }

Page 86: Moving away from legacy code with BDD

First run$> bin/behat ... You can implement step definitions for undefined steps with these snippets: ! /** * @Then I should see :arg1 */ public function iShouldSee($arg1) { throw new PendingException(); }

...

Page 87: Moving away from legacy code with BDD

Append snippets$> bin/behat --append-snippets

Page 88: Moving away from legacy code with BDD

Feedback loop$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage TODO: write pending definition When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 89: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Scenario-BDD

Page 90: Moving away from legacy code with BDD

Colour it Red

Page 91: Moving away from legacy code with BDD

Colour it red /** * @Given /^I am on the homepage$/ */ public function iAmOnTheHomepage() { $crawler = new \Some\Crawler\Lib\Crawler(); $crawler->goto(“http://localhost:8080/”); if (200 !== $crawler->getCurrentStatusCode()) { throw new RuntimeException(‘Can not open homepage’); } }

Page 92: Moving away from legacy code with BDD

Colour it red$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage Can not open homepage (RuntimeException) When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 93: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Scenario-BDD

Page 94: Moving away from legacy code with BDD

Change the messageAs quickly as possible

Page 95: Moving away from legacy code with BDD

Change the message$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage Can not open homepage (RuntimeException) When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 96: Moving away from legacy code with BDD

Change the message$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage Route … not found (FrameworkException) When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 97: Moving away from legacy code with BDD

Change the message$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage Template … not found (FrameworkException) When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 98: Moving away from legacy code with BDD

Change the message$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage When I follow “sign up” TODO: write pending definition And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 99: Moving away from legacy code with BDD

behat.org

Page 100: Moving away from legacy code with BDD

Change the message$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered Object `User` and its method `isRegistered` does not exist (RuntimeException) And I should be on the homepage again

Page 101: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Spec-BDD

Page 102: Moving away from legacy code with BDD
Page 103: Moving away from legacy code with BDD

Setup

1. Install phpspec via composer

2. use it

Page 104: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Spec-BDD

Page 105: Moving away from legacy code with BDD

Prepare your first spec$> bin/phpspec desc Acme/Userbase/User

Page 106: Moving away from legacy code with BDD

Describe your first message<?php !namespace spec\Acme\Userbase; !class User extends ObjectBehavior{ function it_is_registered_by_default() { $this->shouldBeRegistered(); } }

Page 107: Moving away from legacy code with BDD

Colour it red$> bin/phpspec !Class “Acme\Userbase\User” does not exist. Create? [Y/n] y !Method `Acme\Userbase\User::isRegistered()` does not exist. Create? [Y/n] y

Page 108: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Spec-BDD

Page 109: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Spec-BDD

Page 110: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Spec-BDD

Page 111: Moving away from legacy code with BDD

phpspec.net

Page 112: Moving away from legacy code with BDD

Verify feature$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 113: Moving away from legacy code with BDD

Verify feature$> bin/behat !Feature: registration in order to maintain my shopping history as a site visitor i need to be able to register on this site ! Scenario: Successful registration when visitor provides all the required info Given I am on the homepage When I follow “sign up” And I fill in registration form And I submit it Then I should be successfully registered And I should be on the homepage again

Page 114: Moving away from legacy code with BDD

Stories

Examples

Describe

ImplementDesign

Page 115: Moving away from legacy code with BDD

#3: Income

Page 116: Moving away from legacy code with BDD

6 months later…

Page 117: Moving away from legacy code with BDD

#3: Same ashtrays, better car

Page 118: Moving away from legacy code with BDD

We do that for clients

Page 119: Moving away from legacy code with BDD

We do that for clientsAnd teach others in those rare

moments when we don’t

http:// .com