SlideShare ist ein Scribd-Unternehmen logo
1 von 73
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Ähnlich wie 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
 

Ähnlich wie 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?
 

Mehr von 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
 

Mehr von 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
 

Kürzlich hochgeladen

Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...Akihiro Suda
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 

Kürzlich hochgeladen (20)

Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
20240415 [Container Plumbing Days] Usernetes Gen2 - Kubernetes in Rootless Do...
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 

Why Your Test Suite Sucks