SlideShare a Scribd company logo
1 of 73
Download to read offline
Why$Your$Test$Suite$Sucks
(and%what%you%can%do%about%it)
by#Ciaran&McNulty#at#PHPUK&2015
It’s%not%working%for%me
===
TDD#must#suck1
1
"BIT.LY/1LEF0GI"&"BIT.LY/1SLFGTQ"
The$problem$is$not$TDD
The$problem$is$your%suite
Value!=!Benefits!)!Costs
Suites'suck'when'you'aren’t'ge)ng'
all'the'benefits'of'TDD
Suites'suck'when'the'tests'are$hard$
to$maintain
Reason'1:
You$don't$have$a$test$suite
The$Evolu*on$of$a$TDD$Team
Maturity(model
• Manual"tes&ng
• Automated"tes&ng
• Test.first"development
• Test.driven"development
Manual&tes*ng
• Design"an"implementa+on
• Implement"that"design
• Manually"test
Growing(from(Manual(to(Automated
• “When'we'make%changes,'it'breaks'things!”
• “We'spend'a%lot%of%/me'on'manual'tes:ng”
• “Bugs'keep'making'it'into'produc:on”
Enabled(by:
+(Tutorials,(training
+(Team(policies
Automated)tes+ng
• Design"an"implementa+on
• Implement"that"design
• Write.tests"to"verify"it
Growing(from(Automated(to(Test3first
• “It’s'a'pain'having'to'write'tests'once'I’m'done”
• “My'test'suite'is'bri'le”
• “Maintaining'the'suite'is'hard”'
• ”TDD/Doesn’t/Work!”
Supported)by:
-)Coaching,)pairing
-)Leadership
Test%first(development
• Design"an"implementa+on
• Write*tests"to"verify"that"implementa+on
• Implement"that"design
Growing(from(Test/first(to(Test/driven
• “Test'suite'is's"ll'bri,le”
• “Maintaining'the'suite'is's"ll'hard”'
• ”TDD'Doesn’t'Work!”
Supported)by:
-)Prac1ce
Test%driven+development
• Write&tests"that"describe"behaviour
• Implement"a"system"that"has"that"behaviour
Problems:
*+“I+don’t+know+what+to+do+with+all+this+spare&'me!”
*+“Where+should+we+keep+this+extra&money?”
Reason'2:
You$are$tes*ng$implementa*on
Problem:)Mocking)Queries
• A#query#is#a#method#that#returns'a'value'without'side'effects#
• We#shouldn’t'care#how#many#4mes#(if#any)#a#query#is#called
• Specifying#that#detail#makes'change'harder
function testItGreetsPeopleByName()
{
$user = $this->getMock('User');
$user->expects($this->once())
->method('getName')
->willReturn('Ciaran');
$greeting = $this->greeter->greet($user);
$this->assertEquals('Hello, Ciaran!', $greeting);
}
function testItGreetsPeopleByName()
{
$user = $this->getMock('User');
$user->method('getName')
->willReturn('Ciaran');
$greeting = $this->greeter->greet($user);
$this->assertEquals('Hello, Ciaran!', $greeting);
}
Don’t&mock&queries,"just"use"stubs
Do#you#really#care#how#many#/mes#it's#called?
Problem:)Tes,ng)the)sequence)of)calls
• Most&of&the&*me&we&don’t&care&what%order%calls%are%made%in
• Tes*ng&the&sequence&makes&it&hard%to%change
public function testBasketTotals()
{
$priceList = $this->getMock('PriceList');
$priceList->expect($this->at(0))
->method('getPrices')
->willReturn(120);
$priceList->expect($this->at(1))
->method('getPrices')
->willReturn(200);
$this->basket->add('Milk', 'Bread');
$total = $this->basket->calculateTotal();
$this->assertEqual(320, $total);
}
public function testBasketTotals()
{
$priceList = $this->getMock('PriceList');
$priceList->method('getPrices')
->will($this->returnValueMap([
['Milk', 120],
['Bread', 200]
]));
$this->basket->add('Milk', 'Bread');
$total = $this->basket->calculateTotal();
$this->assertEqual(320, $total);
}
Test%behaviour%you%care%about,"
don’t"test"implementa/on
PROTIP:!The!best!way!to!do!this!is!to!not!
have!an!implementa3on!yet
Reason'3:
Because'your'design'sucks
Problem:)Too)many)Doubles
• It$is$painful$to$have$to$double,lots,of,objects$in$your$test
• It$is$a$signal$your$object,has,too,many,dependencies$
public function setUp()
{
$chargerules = $this->getMock('ChargeRules');
$chargetypes = $this->getMock('ChargeTypes');
$notifier = $this->getMockBuilder('Notifier')
->disableOriginalConstructor()->getMock();
$this->processor = new InvoiceProcessor(
$chargerules, $chargetypes, $notifier
);
}
class InvoiceProcessor
{
public function __construct(
ChargeRules $chargeRules,
ChargeTypes $chargeTypes,
Notifier $notifier
)
{
$this->chargeRules = $chargeRules;
$this->chargeTypes = $chargeTypes;
$this->notifier = $notifier;
}
// …
Too#many#doubles!in!your!test!mean!
your!class!has!too#many#
dependencies
Problem:)Stubs)returning)stubs
• A#related#painful#issue#is#stubs%returning%a%stubs
• It#is#a#signal#our#object#does%not%have%the%right%dependencies
public function it_notifies_the_user(
User $user,
Contact $contact,
Email $email,
Emailer $emailer
)
{
$this->beConstructedWith($emailer);
$user->getContact()->willReturn($contact);
$contact->getEmail()->willReturn($email);
$this->notify($user);
$emailer->sendTo($email)->shouldHaveBeenCalled();
}
class Notifier
{
public function __construct(Emailer $emailer)
{
// …
}
public function notify(User $user)
{
$email = $user->getContact()->getEmail()
$this->emailer->sendTo($email);
}
}
class Notifier
{
public function __construct(Emailer $emailer)
{
// …
}
public function notify(User $user)
{
$this->emailer->sendTo($user);
}
}
class Notifier
{
public function __construct(Emailer $emailer)
{
// …
}
public function notify(Email $email)
{
$this->emailer->sendTo($email);
}
}
public function it_notifies_the_user(
Email $email,
Emailer $emailer
)
{
$this->beConstructedWith($emailer);
$this->notify($email);
$emailer->sendTo($email)->shouldHaveBeenCalled();
}
Stubs&returning&stubs&indicate&
dependencies(are(not(correctly(
defined
Problem:)Par+ally)doubling)the)object)under)
test
• A#common%ques*on#is#“how#can#I#mock#methods#on#the#SUT?”#
• Easy#to#do#in#some#tools,#impossible%in%others
• It#is#a#signal#our%object%has%too%many%responsibili*es
class Form
{
public function handle($data)
{
if ($this->validate($data)) {
return 'Valid';
}
return 'Invalid';
}
protected function validate($data)
{
// do something complex
}
}
function testItOutputsMessageOnValidData()
{
$form = $this->getMock('Form', ['validate']);
$form->method('validate')->willReturn(true);
$result = $form->handle([]);
$this->assertSame('Valid', $result);
}
class Form
{
protected function __construct(Validator $validator)
{
// …
}
public function handle($data)
{
if ($this->validator->validate($data)) {
return 'Valid';
}
return 'Invalid';
}
}
function testItOutputsMessageOnValidData()
{
$validator = $this->getMock(‘Validator’);
$validator->method('validate')->willReturn(true);
$form = new Form($validator);
$result = $form->handle([]);
$this->assertSame('Valid', $result);
}
If#you#want#to#mock#part#of#the#SUT#
it#means#you$should$really$have$
more$than$one$object
How$to$be$a$be)er$so,ware$designer:
• Stage&1:#Think#about#your#code#before#you#write#it#
• Stage&2:#Write#down#those#thoughts
• Stage&3:#Write#down#those#thoughts#as#code#
How$long$will$it$take$without$TDD?
• 1"hour"thinking"about"how"it"should"work"
• 30"mins"Implemen6ng"it
• 30"mins"Checking"it"works"
How$long$will$it$take$with$TDD?
• 1"hour"Thinking"in"code"about"how"it"should"work
• 30"mins"Implemen8ng"it
• 1"min"Checking"it"works"
Use$your$test$suite$as$a$way$to$
reason'about'the'code
Customers)should)not)dictate)your)
design'process
Reason'4:
You$are$unit$tes,ng$across$domain$
boundaries
Problem:)Tes,ng)3rd)party)code
• When&we&extend&a&library&or&framework&we&use$other$people’s$
code
• To&test&our&code&we&end&up&tes.ng$their$code&too
• This&:me&is&wasted&–&we&should&trust&their&code&works&
class UserRepository extends FrameworkRepository
{
public function findByEmail($email)
{
$this->find(['email' => $email]);
}
}
public function it_finds_the_user_by_email(
FrameworkDatabaseConnection $db,
FrameworkSchemaCreator $schemaCreator,
FrameworkSchema $schema,
User $user
)
{
$this->beConstructedWith($db, $schemaCreator);
$schemaCreator->getSchema()->willReturn($schema);
$schema->getMappings()->willReturn('email'=>'email');
$user = $this->findByEmail('bob@example.com');
$user->shouldHaveType('User');
}
class UserRepository
{
private $repository;
public function __construct(FrameworkRepository $repository)
{
$this->repository = $repository;
}
public function findByEmail($email)
{
return $this->repository->find(['email' => $email]);
}
}
public function it_finds_the_user_by_email(
Repository $repository,
User $user
)
{
$this->beConstructedWith($repository);
$repository->find(['email' => 'bob@example.com')
->willReturn($user);
$this->findByEmail('bob@example.com');
->shouldEqual($user);
}
When%you%extend%third%party%code,%
you%take%responsibility%for%its%
design%decisions
Favour'composi'on'over'
inheritance
Problem:)Doubling)3rd)party)code
• Test&Doubles&(Mocks,&Stubs,&Fakes)&are&used&to&test&
communica(on&between&objects&
• Tes:ng&against&a&Double&of&a&3rd&party&object&does,not,give,us,
confidence&that&we&have&described&the&communica:on&correctly
class FileHandlerSpec extends ObjectBehaviour
{
public function it_uploads_data_to_the_cloud_when_valid(
CloudApi $client, FileValidator $validator, File $file
)
{
$this->beConstructedWith($client, $validator);
$validator->validate($file)->willReturn(true);
$client->startUpload()->shouldBeCalled();
$client->uploadData(Argument::any())->shouldBeCalled();
$client->uploadSuccessful()->willReturn(true);
$this->process($file)->shouldReturn(true);
}
}
Coupled(architecture
Coupled(architecture
Layered'architecture
Tes$ng'layered'architecture
class FileHandlerSpec extends ObjectBehaviour
{
public function it_uploads_data_to_the_cloud_when_valid(
FileStore $filestore, FileValidator $validator, File $file
)
{
$this->beConstructedWith($filestore, $validator);
$validator->validate($file)->willReturn(true);
$this->process($file);
$filestore->store($file)->shouldHaveBeenCalled();
}
}
Tes$ng'layered'architecture
class CloudFilestoreTest extends PHPUnit_Framework_TestCase
{
function testItStoresFiles()
{
$testCredentials = …
$file = new File(…);
$apiClient = new CloudApi($testCredentials);
$filestore = new CloudFileStore($apiClient);
$filestore->store($file);
$this->assertTrue($apiClient->fileExists(…));
}
}
Tes$ng'layered'architecture
Don’t&test&other&people’s&code
You$don't$know$how$it's$supposed$to$behave
Don’t&test&how&you&talk&to&other&
people’s&code
You$don't$know$how$it's$supposed$to$respond
Pu#ng&it&all&together
• Use%TDD%to%drive&development
• Use%TDD%to%replace&exis1ng&prac1ces,%not%as%a%new%extra%task%
Pu#ng&it&all&together
Don’t&ignore&tests&that&suck,&improve&them:&
• Is$the$test$too$!ed$to$implementa!on?
• Does$the$design$of$the$code$need$to$improve?$
• Are$you$tes!ng$across$domain$boundaries?$
Image&credits
• Human&Evolu+on"by"Tkgd2007
h-p://bit.ly/1DdLvy1"(CC"BY=SA"3.0)
• Oops"by"Steve"and"Sara"Emry"
h-ps://flic.kr/p/9Z1EEd"(CC"BY=NC=SA"2.0)
• Blueprints&for&Willborough&Home"by"Brian"Tobin"
h-ps://flic.kr/p/7MP9RU"(CC"BY=NC=ND"2.0)
• Border"by"Giulia"van"Pelt"
h-ps://flic.kr/p/9YT1c5"(CC"BY=NC=ND"2.0)
Thank&you!
h"ps://joind.in/13393
h"ps://github.com/ciaranmcnulty
h"p://www.slideshare.net/CiaranMcNulty
@ciaranmcnulty

More Related Content

Similar to Why Your Test Suite Sucks

Creating testing tools to support development
Creating testing tools to support developmentCreating testing tools to support development
Creating testing tools to support developmentChema del Barco
 
Testing Sap: Modern Methodology
Testing Sap: Modern MethodologyTesting Sap: Modern Methodology
Testing Sap: Modern MethodologyEthan Jewett
 
Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...
Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...
Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...UserZoom
 
Fundamentals of testing 1
Fundamentals of testing 1Fundamentals of testing 1
Fundamentals of testing 1Hoang Nguyen
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015CiaranMcNulty
 
Cucumber Presentation Kiev Meet Up
Cucumber Presentation Kiev Meet UpCucumber Presentation Kiev Meet Up
Cucumber Presentation Kiev Meet Updimakovalenko
 
Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011dimakovalenko
 
Why Your Selenium Tests are so Dang Brittle, and What to Do About It
Why Your Selenium Tests are so Dang Brittle, and What to Do About ItWhy Your Selenium Tests are so Dang Brittle, and What to Do About It
Why Your Selenium Tests are so Dang Brittle, and What to Do About ItJay Aho
 
Prioritization 301 - Advanced Roadmapping Class, Bruce McCarthy
Prioritization 301 - Advanced Roadmapping Class, Bruce McCarthyPrioritization 301 - Advanced Roadmapping Class, Bruce McCarthy
Prioritization 301 - Advanced Roadmapping Class, Bruce McCarthyProductCamp Boston
 
Prioritization 301: An Advanced Roadmapping Class for Product People
Prioritization 301: An Advanced Roadmapping Class for Product PeoplePrioritization 301: An Advanced Roadmapping Class for Product People
Prioritization 301: An Advanced Roadmapping Class for Product PeopleUpUp Labs
 
Turbocharge your automated tests with ci
Turbocharge your automated tests with ciTurbocharge your automated tests with ci
Turbocharge your automated tests with ciOpenSource Connections
 
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011TEST Huddle
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Developmentpmanvi
 
Communication and Testing: Why You Have Been Wrong All Along!
Communication and Testing: Why You Have Been Wrong All Along!Communication and Testing: Why You Have Been Wrong All Along!
Communication and Testing: Why You Have Been Wrong All Along!TechWell
 
Continuous Deployment at Etsy
Continuous Deployment at EtsyContinuous Deployment at Etsy
Continuous Deployment at EtsyPremshree Pillai
 
Seven Keys to Navigating Your Agile Testing Transition
Seven Keys to Navigating Your Agile Testing TransitionSeven Keys to Navigating Your Agile Testing Transition
Seven Keys to Navigating Your Agile Testing TransitionTechWell
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareChris Weldon
 
Better Quality through Scrum (2011)
Better Quality through Scrum (2011)Better Quality through Scrum (2011)
Better Quality through Scrum (2011)Dominik Jungowski
 
Value Engineering, What's not to love?
Value Engineering, What's not to love?Value Engineering, What's not to love?
Value Engineering, What's not to love?Nick Grant
 

Similar to Why Your Test Suite Sucks (20)

Creating testing tools to support development
Creating testing tools to support developmentCreating testing tools to support development
Creating testing tools to support development
 
Testing Sap: Modern Methodology
Testing Sap: Modern MethodologyTesting Sap: Modern Methodology
Testing Sap: Modern Methodology
 
Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...
Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...
Demystifying Sample Size - How Many Participants Do You Really Need for UX Re...
 
Fundamentals of testing 1
Fundamentals of testing 1Fundamentals of testing 1
Fundamentals of testing 1
 
Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015Why Your Test Suite Sucks - PHPCon PL 2015
Why Your Test Suite Sucks - PHPCon PL 2015
 
Cucumber Presentation Kiev Meet Up
Cucumber Presentation Kiev Meet UpCucumber Presentation Kiev Meet Up
Cucumber Presentation Kiev Meet Up
 
Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011Selenium and Cucumber Selenium Conf 2011
Selenium and Cucumber Selenium Conf 2011
 
Why Your Selenium Tests are so Dang Brittle, and What to Do About It
Why Your Selenium Tests are so Dang Brittle, and What to Do About ItWhy Your Selenium Tests are so Dang Brittle, and What to Do About It
Why Your Selenium Tests are so Dang Brittle, and What to Do About It
 
Prioritization 301 - Advanced Roadmapping Class, Bruce McCarthy
Prioritization 301 - Advanced Roadmapping Class, Bruce McCarthyPrioritization 301 - Advanced Roadmapping Class, Bruce McCarthy
Prioritization 301 - Advanced Roadmapping Class, Bruce McCarthy
 
Prioritization 301: An Advanced Roadmapping Class for Product People
Prioritization 301: An Advanced Roadmapping Class for Product PeoplePrioritization 301: An Advanced Roadmapping Class for Product People
Prioritization 301: An Advanced Roadmapping Class for Product People
 
Turbocharge your automated tests with ci
Turbocharge your automated tests with ciTurbocharge your automated tests with ci
Turbocharge your automated tests with ci
 
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
James Whittaker - Pursuing Quality-You Won't Get There - EuroSTAR 2011
 
Test Driven Development
Test Driven DevelopmentTest Driven Development
Test Driven Development
 
Communication and Testing: Why You Have Been Wrong All Along!
Communication and Testing: Why You Have Been Wrong All Along!Communication and Testing: Why You Have Been Wrong All Along!
Communication and Testing: Why You Have Been Wrong All Along!
 
Continuous Deployment at Etsy
Continuous Deployment at EtsyContinuous Deployment at Etsy
Continuous Deployment at Etsy
 
Seven Keys to Navigating Your Agile Testing Transition
Seven Keys to Navigating Your Agile Testing TransitionSeven Keys to Navigating Your Agile Testing Transition
Seven Keys to Navigating Your Agile Testing Transition
 
Beyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver SoftwareBeyond TDD: Enabling Your Team to Continuously Deliver Software
Beyond TDD: Enabling Your Team to Continuously Deliver Software
 
Better Quality through Scrum (2011)
Better Quality through Scrum (2011)Better Quality through Scrum (2011)
Better Quality through Scrum (2011)
 
Python and test
Python and testPython and test
Python and test
 
Value Engineering, What's not to love?
Value Engineering, What's not to love?Value Engineering, What's not to love?
Value Engineering, What's not to love?
 

More from CiaranMcNulty

Greener web development at PHP London
Greener web development at PHP LondonGreener web development at PHP London
Greener web development at PHP LondonCiaranMcNulty
 
Doodle Driven Development
Doodle Driven DevelopmentDoodle Driven Development
Doodle Driven DevelopmentCiaranMcNulty
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with SymfonyCiaranMcNulty
 
Behat Best Practices
Behat Best PracticesBehat Best Practices
Behat Best PracticesCiaranMcNulty
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with SymfonyCiaranMcNulty
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through ExamplesCiaranMcNulty
 
Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016CiaranMcNulty
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through ExamplesCiaranMcNulty
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobCiaranMcNulty
 
Conscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPConscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPCiaranMcNulty
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016CiaranMcNulty
 
Fly In Style (without splashing out)
Fly In Style (without splashing out)Fly In Style (without splashing out)
Fly In Style (without splashing out)CiaranMcNulty
 
Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015CiaranMcNulty
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through ExamplesCiaranMcNulty
 
Driving Design with PhpSpec
Driving Design with PhpSpecDriving Design with PhpSpec
Driving Design with PhpSpecCiaranMcNulty
 
Using HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationUsing HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationCiaranMcNulty
 

More from CiaranMcNulty (19)

Greener web development at PHP London
Greener web development at PHP LondonGreener web development at PHP London
Greener web development at PHP London
 
Doodle Driven Development
Doodle Driven DevelopmentDoodle Driven Development
Doodle Driven Development
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with Symfony
 
Behat Best Practices
Behat Best PracticesBehat Best Practices
Behat Best Practices
 
Behat Best Practices with Symfony
Behat Best Practices with SymfonyBehat Best Practices with Symfony
Behat Best Practices with Symfony
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016Modelling by Example Workshop - PHPNW 2016
Modelling by Example Workshop - PHPNW 2016
 
Conscious Coupling
Conscious CouplingConscious Coupling
Conscious Coupling
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Finding the Right Testing Tool for the Job
Finding the Right Testing Tool for the JobFinding the Right Testing Tool for the Job
Finding the Right Testing Tool for the Job
 
Conscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHPConscious Decoupling - Lone Star PHP
Conscious Decoupling - Lone Star PHP
 
TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016TDD with PhpSpec - Lone Star PHP 2016
TDD with PhpSpec - Lone Star PHP 2016
 
Fly In Style (without splashing out)
Fly In Style (without splashing out)Fly In Style (without splashing out)
Fly In Style (without splashing out)
 
Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015Driving Design through Examples - PhpCon PL 2015
Driving Design through Examples - PhpCon PL 2015
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
TDD with PhpSpec
TDD with PhpSpecTDD with PhpSpec
TDD with PhpSpec
 
Driving Design through Examples
Driving Design through ExamplesDriving Design through Examples
Driving Design through Examples
 
Driving Design with PhpSpec
Driving Design with PhpSpecDriving Design with PhpSpec
Driving Design with PhpSpec
 
Using HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless IntegrationUsing HttpKernelInterface for Painless Integration
Using HttpKernelInterface for Painless Integration
 

Recently uploaded

Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024MulesoftMunichMeetup
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationElement34
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In hararekasambamuno
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIInflectra
 
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Lisi Hocke
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfICS
 
Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14VMware Tanzu
 
Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...
Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...
Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...Abortion Clinic
 
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...OnePlan Solutions
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acres
^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acres^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acres
^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acreskasambamuno
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksJinanKordab
 
What is a Recruitment Management Software?
What is a Recruitment Management Software?What is a Recruitment Management Software?
What is a Recruitment Management Software?NYGGS Automation Suite
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AIAGATSoftware
 
Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024Chirag Panchal
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdfSelfMade bd
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...naitiksharma1124
 
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypseTomasz Kowalczewski
 
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdfStrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdfsteffenkarlsson2
 
Lessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfLessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfSrushith Repakula
 

Recently uploaded (20)

Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test Automation
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
^Clinic ^%[+27788225528*Abortion Pills For Sale In harare
 
From Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST APIFrom Theory to Practice: Utilizing SpiraPlan's REST API
From Theory to Practice: Utilizing SpiraPlan's REST API
 
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
Team Transformation Tactics for Holistic Testing and Quality (NewCrafts Paris...
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdf
 
Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14Spring into AI presented by Dan Vega 5/14
Spring into AI presented by Dan Vega 5/14
 
Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...
Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...
Sinoville Clinic ](+27832195400*)[🏥Abortion Pill Prices Sinoville ● Women's A...
 
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
 
^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acres
^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acres^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acres
^Clinic ^%[+27788225528*Abortion Pills For Sale In birch acres
 
Transformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with LinksTransformer Neural Network Use Cases with Links
Transformer Neural Network Use Cases with Links
 
What is a Recruitment Management Software?
What is a Recruitment Management Software?What is a Recruitment Management Software?
What is a Recruitment Management Software?
 
BusinessGPT - Security and Governance for Generative AI
BusinessGPT  - Security and Governance for Generative AIBusinessGPT  - Security and Governance for Generative AI
BusinessGPT - Security and Governance for Generative AI
 
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
Abortion Clinic Pretoria ](+27832195400*)[ Abortion Clinic Near Me ● Abortion...
 
Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024Food Delivery Business App Development Guide 2024
Food Delivery Business App Development Guide 2024
 
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
Auto Affiliate  AI Earns First Commission in 3 Hours..pdfAuto Affiliate  AI Earns First Commission in 3 Hours..pdf
Auto Affiliate AI Earns First Commission in 3 Hours..pdf
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
 
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
[GeeCON2024] How I learned to stop worrying and love the dark silicon apocalypse
 
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdfStrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
 
Lessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfLessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdf
 

Why Your Test Suite Sucks