SlideShare a Scribd company logo
1 of 119
Download to read offline
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
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
This talk is not about
•

Greenfield projects

•

Solutions for everyone

•

How to write code
This talk is not about
•

Greenfield projects

•

Maintenance-mode projects

•

Solutions for everyone

•

How to write code (well, mostly)
Legacy projects
How most developers see
their next project
My next
project
My next
project

His actual next
project
Agile, TDD, BDD,
General QA, etc…

// TODO: refactor this
later
Is it really that bad?
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.
// TODO: refactor this
later
// TODO: refactor this
later
// TODO: refactor this
later
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.
The truth is:
You deliver value!
Just not as effectively as you could
Agile, TDD, BDD,
General QA, etc…

// TODO: refactor this
later
How?
Three options
1. Rewrite an entire application using “the right way”
2. Do functional refactoring
3. Do business-oriented rewrite using “BDD pipeline”
#1: Full Rewrite
#1: Full Rewrite
•

Scrum / Kanban

•

TDD / BDD / DDD / Pair-programming

•

New everything

•

Mirroring functionality
#1: Income
6 Months later…
#1: Almost there…
#1: Full Rewrite

Just spaghetti, please: 4 man years

Full London meal (TDD, BDD, Agile, QA): ??? man years
#2: FUNCTIONAL
Refactoring
#2: Functional Refactoring
•

Blackbox testing

•

New routing

•

New templating system

•

Migration of model layer (MySQL -> Mongo)
#2: Income
6 Months later…
#2: Ta-da!!!
“Exactly what did you do here?”

– Your client. (most likely)
#3: BDD PIPELINE
AKA Business-Oriented rewrite
Why do some legacy
projects suck?
Cost

Because of the
cost of change
Time
… Of change where?
Why do applications
change?
Welcome to the
wonderland
of Agile Business Analysis
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?
“BDD Pipeline”
1. Impact Mapping
2. Feature Mapping
3. Prioritisation
4. Example Workshop
5. Full-stack BDD
1. What is the Goal &
minimal valuable product?
Impact Mapping
“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.”
– Gojko Adzic
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?
MVP
impactmapping.org
2. What is the minimal set
of features to support it?
Feature Mapping
“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”
– Marcello Duarte
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?
Product Backlog
In order to buy more products
As a customer
I need to have a product autocompletion in the search field
3. Which features are
more likely to change?
Prioritisation workshop
In order to maintain my shopping history
As a site visitor
I need to be able to register on this site
In order to maintain my shopping history
As a site visitor
I need to be able to register on this site

benefit
!
actor
SELECT s.*
FROM backlog as s
ORDER BY s.role, s.benefit
LIMIT 25
4. How fully those features
should be implemented?
Example workshops
Three layers of a User-Story
•

Business rule(s)

•

Communication

•

Acceptance criteria
Three layers of a User-Story

•

Business rule(s) == Acceptance criteria

•

Communication
Three layers of a User-Story

•

Business rule(s) == Acceptance criteria

•

Communication == Examples
Three layers of a User-Story

•

Business rule(s)

•

Communication == Examples == Acceptance criteria
Feature: registration
in order to maintain my shopping history
as a site visitor
i need to be able to register on this site
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
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

Scenario: Unable to register when visitor misses required info
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

Scenario: Unable to register when visitor misses required info

Scenario: ...
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

Scenario: Unable to register when visitor misses required info

Scenario: ...
Scenario: ...
Scenario: ...
Scenario: ...
Scenario: ...
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
5. How to avoid
gold plating?
Delivery
Architecture
Architecture
HTTP layering
[GET] /products

Infrastructure

Legacy system
[GET] /products
[GET] /products/123

Infrastructure

Legacy system
[GET] /products
[GET] /products/123

New system

Infrastructure

Legacy system
[GET] /products
[GET] /products/123

New system

Infrastructure

Legacy system

New system
Implementation
Implementation
Full-stack BDD
Stories
Examples

Describe

Design

Implement
Stories
Examples

Describe

Scenario-BDD
Design

Implement
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
Feature:
in order
as a
i need

Scenario: Successful registration when visitor provides
Given I am on the
When
And I fill in
And I submit it
Then
And I should be on the homepage

What could be automated
should be automated
assertEquals(Your Feature, Your App)
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`
Feature Context
<?php
!
use BehatBehatContextClosuredContextInterface,
BehatBehatContextTranslatedContextInterface,
BehatBehatContextBehatContext,
BehatBehatExceptionPendingException;
use BehatGherkinNodePyStringNode,
BehatGherkinNodeTableNode;
!
class FeatureContext extends BehatContext
{
}
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();
}

...
Append snippets
$> bin/behat --append-snippets
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
Stories
Examples

Describe

Scenario-BDD
Design

Implement
Colour it Red
Colour it red
/**
* @Given /^I am on the homepage$/
*/
public function iAmOnTheHomepage()
{
$crawler = new SomeCrawlerLibCrawler();
$crawler->goto(“http://localhost:8080/”);
if (200 !== $crawler->getCurrentStatusCode())
{
throw new RuntimeException(‘Can not open homepage’);
}
}
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
Stories
Examples

Describe

Scenario-BDD
Design

Implement
Change the message
As quickly as possible
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
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
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
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
behat.org
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
Stories

Spec-BDD

Examples

Describe

Design

Implement
Setup

1. Install phpspec via composer
2. use it
Stories

Spec-BDD

Examples

Describe

Design

Implement
Prepare your first spec
$> bin/phpspec desc Acme/Userbase/User
Describe your first message
<?php
!

namespace specAcmeUserbase;
!

class User extends ObjectBehavior

{
function it_is_registered_by_default()
{
$this->shouldBeRegistered();
}
}
Colour it red
$> bin/phpspec
!
Class “AcmeUserbaseUser” does not exist. Create? [Y/n]
y
!
Method `AcmeUserbaseUser::isRegistered()` does not exist. Create? [Y/n]
y
Stories

Spec-BDD

Examples

Describe

Design

Implement
Stories

Spec-BDD

Examples

Describe

Design

Implement
Stories

Spec-BDD

Examples

Describe

Design

Implement
phpspec.net
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
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
Stories
Examples

Describe

Design

Implement
#3: Income
6 months later…
#3: Same ashtrays, better car
We do that for clients
http://

.com

We do that for clients
And teach others in those rare
moments when we don’t

More Related Content

What's hot

Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in Ruby
Wen-Tien Chang
 
Stop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principlesStop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principles
Edorian
 

What's hot (20)

How To Become A Good C# Programmer
How To Become A Good C# ProgrammerHow To Become A Good C# Programmer
How To Become A Good C# Programmer
 
Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.
Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.
Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.
 
Exception Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in RubyException Handling: Designing Robust Software in Ruby
Exception Handling: Designing Robust Software in Ruby
 
An Introduction to Behaviour Driven Development with Cucumber Java
An Introduction to Behaviour Driven Development with Cucumber JavaAn Introduction to Behaviour Driven Development with Cucumber Java
An Introduction to Behaviour Driven Development with Cucumber Java
 
Java script
Java scriptJava script
Java script
 
Java script
Java scriptJava script
Java script
 
TDD with phpspec2
TDD with phpspec2TDD with phpspec2
TDD with phpspec2
 
Working Effectively With Legacy Code
Working Effectively With Legacy CodeWorking Effectively With Legacy Code
Working Effectively With Legacy Code
 
Producing Testable Requirements
Producing Testable RequirementsProducing Testable Requirements
Producing Testable Requirements
 
Double Loop: TDD & BDD Done Right!
Double Loop: TDD & BDD Done Right!Double Loop: TDD & BDD Done Right!
Double Loop: TDD & BDD Done Right!
 
Code Quality Practice and Tools
Code Quality Practice and ToolsCode Quality Practice and Tools
Code Quality Practice and Tools
 
php_tizag_tutorial
php_tizag_tutorialphp_tizag_tutorial
php_tizag_tutorial
 
Java script Session No 1
Java script Session No 1Java script Session No 1
Java script Session No 1
 
Developing and testing ajax components
Developing and testing ajax componentsDeveloping and testing ajax components
Developing and testing ajax components
 
Stop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principlesStop wasting-time-by-applying-clean-code-principles
Stop wasting-time-by-applying-clean-code-principles
 
DDD with Behat
DDD with BehatDDD with Behat
DDD with Behat
 
Apigility – Lightning Fast API Development - OSSCamp 2014
Apigility – Lightning Fast API Development - OSSCamp 2014 Apigility – Lightning Fast API Development - OSSCamp 2014
Apigility – Lightning Fast API Development - OSSCamp 2014
 
Html JavaScript and CSS
Html JavaScript and CSSHtml JavaScript and CSS
Html JavaScript and CSS
 
Small Code - Ruby on Ales 2014
Small Code - Ruby on Ales 2014Small Code - Ruby on Ales 2014
Small Code - Ruby on Ales 2014
 
Eugene Andruszczenko: jQuery
Eugene Andruszczenko: jQueryEugene Andruszczenko: jQuery
Eugene Andruszczenko: jQuery
 

Viewers also liked

Devops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztekDevops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztek
Zsolt Takács
 

Viewers also liked (20)

Bdd for legacy system
Bdd for legacy systemBdd for legacy system
Bdd for legacy system
 
Legacy Code: Evolve or Rewrite?
Legacy Code: Evolve or Rewrite?Legacy Code: Evolve or Rewrite?
Legacy Code: Evolve or Rewrite?
 
DevsMeetUp Freiburg: Behavior Driven Development with Behat/Mink
DevsMeetUp Freiburg: Behavior Driven Development with Behat/MinkDevsMeetUp Freiburg: Behavior Driven Development with Behat/Mink
DevsMeetUp Freiburg: Behavior Driven Development with Behat/Mink
 
BDD in open source projects - Is it really beneficial?
BDD in open source projects - Is it really beneficial?BDD in open source projects - Is it really beneficial?
BDD in open source projects - Is it really beneficial?
 
Being effective with legacy projects
Being effective with legacy projectsBeing effective with legacy projects
Being effective with legacy projects
 
Modern Project Toolbox
Modern Project ToolboxModern Project Toolbox
Modern Project Toolbox
 
Enabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projectsEnabling agile devliery through enabling BDD in PHP projects
Enabling agile devliery through enabling BDD in PHP projects
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Moving away from legacy code with BDD
Moving away from legacy code with BDDMoving away from legacy code with BDD
Moving away from legacy code with BDD
 
BDD в PHP с Behat и Mink
BDD в PHP с Behat и MinkBDD в PHP с Behat и Mink
BDD в PHP с Behat и Mink
 
BDD для PHP проектов
BDD для PHP проектовBDD для PHP проектов
BDD для PHP проектов
 
Devops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztekDevops meetup - Automatizált tesztek
Devops meetup - Automatizált tesztek
 
PHP alapú keretrendszerek összehasonlítása - védés bemutató
PHP alapú keretrendszerek összehasonlítása - védés bemutatóPHP alapú keretrendszerek összehasonlítása - védés bemutató
PHP alapú keretrendszerek összehasonlítása - védés bemutató
 
Mobil Weekend - A tesztelői csapat evolúciója
Mobil Weekend - A tesztelői csapat evolúciójaMobil Weekend - A tesztelői csapat evolúciója
Mobil Weekend - A tesztelői csapat evolúciója
 
Magyar Attila - Kata és a TDD a dojoban
Magyar Attila - Kata és a TDD a dojobanMagyar Attila - Kata és a TDD a dojoban
Magyar Attila - Kata és a TDD a dojoban
 
Laravel for Dummies
Laravel for DummiesLaravel for Dummies
Laravel for Dummies
 
Modern Agile Project Toolbox
Modern Agile Project ToolboxModern Agile Project Toolbox
Modern Agile Project Toolbox
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Domain-Driven Design in legacy application
Domain-Driven Design in legacy applicationDomain-Driven Design in legacy application
Domain-Driven Design in legacy application
 
Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast Bridging The Communication Gap, Fast
Bridging The Communication Gap, Fast
 

Similar to Moving away from legacy code with BDD

C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2
Hammad Rajjoub
 
How TDD helps me design - A case study
How TDD helps me design - A case studyHow TDD helps me design - A case study
How TDD helps me design - A case study
Software Craftsmanship Alicante
 

Similar to Moving away from legacy code with BDD (20)

Behaviour Driven Development V 0.1
Behaviour Driven Development V 0.1Behaviour Driven Development V 0.1
Behaviour Driven Development V 0.1
 
Bridging the gap between business and technology - Behaviour Driven Developme...
Bridging the gap between business and technology - Behaviour Driven Developme...Bridging the gap between business and technology - Behaviour Driven Developme...
Bridging the gap between business and technology - Behaviour Driven Developme...
 
PHP CE 2018 - Building Symfony application with Ports and Adapters approach a...
PHP CE 2018 - Building Symfony application with Ports and Adapters approach a...PHP CE 2018 - Building Symfony application with Ports and Adapters approach a...
PHP CE 2018 - Building Symfony application with Ports and Adapters approach a...
 
Old code doesn't stink - Detroit
Old code doesn't stink - DetroitOld code doesn't stink - Detroit
Old code doesn't stink - Detroit
 
When e-commerce meets Symfony
When e-commerce meets SymfonyWhen e-commerce meets Symfony
When e-commerce meets Symfony
 
26 story slicing techniques for any scrum team
26 story slicing techniques for any scrum team26 story slicing techniques for any scrum team
26 story slicing techniques for any scrum team
 
Prashant technical practices-tdd for xebia event
Prashant   technical practices-tdd for xebia eventPrashant   technical practices-tdd for xebia event
Prashant technical practices-tdd for xebia event
 
Creating UI Marketers Won't F*Up
Creating UI Marketers Won't F*UpCreating UI Marketers Won't F*Up
Creating UI Marketers Won't F*Up
 
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For Youpnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
pnwphp - PHPSpec & Behat: Two Testing Tools That Write Code For You
 
Customer Automation Masterclass - Workshop 1: Data Enrichment using Clearbit
Customer Automation Masterclass - Workshop 1: Data Enrichment using ClearbitCustomer Automation Masterclass - Workshop 1: Data Enrichment using Clearbit
Customer Automation Masterclass - Workshop 1: Data Enrichment using Clearbit
 
Scrum Bangalore 13th meet up 13 june 2015 - behaviour driven development - vi...
Scrum Bangalore 13th meet up 13 june 2015 - behaviour driven development - vi...Scrum Bangalore 13th meet up 13 june 2015 - behaviour driven development - vi...
Scrum Bangalore 13th meet up 13 june 2015 - behaviour driven development - vi...
 
O365 Saturday - Deepdive SharePoint Client Side Rendering
O365 Saturday - Deepdive SharePoint Client Side RenderingO365 Saturday - Deepdive SharePoint Client Side Rendering
O365 Saturday - Deepdive SharePoint Client Side Rendering
 
Enterprise PHP (PHP London Conference 2008)
Enterprise PHP (PHP London Conference 2008)Enterprise PHP (PHP London Conference 2008)
Enterprise PHP (PHP London Conference 2008)
 
MongoDB.local Seattle 2019: MongoDB Stitch Tutorial
MongoDB.local Seattle 2019: MongoDB Stitch TutorialMongoDB.local Seattle 2019: MongoDB Stitch Tutorial
MongoDB.local Seattle 2019: MongoDB Stitch Tutorial
 
C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2
 
C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2C:\Fakepath\Combating Software Entropy 2
C:\Fakepath\Combating Software Entropy 2
 
An Introduction to Microservices
An Introduction to MicroservicesAn Introduction to Microservices
An Introduction to Microservices
 
Tweak Geeks #FOS15
Tweak Geeks #FOS15Tweak Geeks #FOS15
Tweak Geeks #FOS15
 
How TDD helps me design - A case study
How TDD helps me design - A case studyHow TDD helps me design - A case study
How TDD helps me design - A case study
 
Rails antipattern-public
Rails antipattern-publicRails antipattern-public
Rails antipattern-public
 

More from Konstantin Kudryashov

More from Konstantin Kudryashov (7)

Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Taking back BDD
Taking back BDDTaking back BDD
Taking back BDD
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Behat 3.0 meetup (March)
Behat 3.0 meetup (March)Behat 3.0 meetup (March)
Behat 3.0 meetup (March)
 
BDD in Symfony2
BDD in Symfony2BDD in Symfony2
BDD in Symfony2
 
LESS, SASS, HAML: 4 буквы, изменившие frontend development
LESS, SASS, HAML: 4 буквы, изменившие frontend developmentLESS, SASS, HAML: 4 буквы, изменившие frontend development
LESS, SASS, HAML: 4 буквы, изменившие frontend development
 
Автоматизируем деплоймент проекта с помощью Capistrano
Автоматизируем деплоймент проекта с помощью CapistranoАвтоматизируем деплоймент проекта с помощью Capistrano
Автоматизируем деплоймент проекта с помощью Capistrano
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Recently uploaded (20)

From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 

Moving away from legacy code with BDD