why your test suite sucks - phpcon pl 2015
TRANSCRIPT
![Page 1: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/1.jpg)
Why Your Test Suite Sucks(and what you can do about it)
by Ciaran McNulty at PHPCon Poland 2015
![Page 2: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/2.jpg)
It’s not working for me
===
TDD must suck1
1 BIT.LY/1LEF0GI & BIT.LY/1SLFGTQ
![Page 3: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/3.jpg)
The problem is not TDD
![Page 4: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/4.jpg)
The problem is your suite
![Page 5: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/5.jpg)
Value = Benefits - Costs
![Page 6: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/6.jpg)
Suites suck when you aren’t ge)ng all the benefits of TDD
![Page 7: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/7.jpg)
Suites suck when the tests are hard to maintain
![Page 8: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/8.jpg)
Reason 1:You don't have a test suite
![Page 9: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/9.jpg)
The Evolu*on of a TDD Team
![Page 10: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/10.jpg)
Maturity model
• Manual tes&ng
• Automated tes&ng
• Test-first development
• Test-driven development
![Page 11: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/11.jpg)
Manual tes*ng
• Design an implementa+on
• Implement that design
• Manually test
![Page 12: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/12.jpg)
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
![Page 13: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/13.jpg)
Automated tes+ng
• Design an implementa+on
• Implement that design
• Write tests to verify it
![Page 14: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/14.jpg)
Growing from Automated to Test-first
• “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
![Page 15: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/15.jpg)
Test-first development
• Design an implementa+on
• Write tests to verify that implementa+on
• Implement that design
![Page 16: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/16.jpg)
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
![Page 17: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/17.jpg)
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?”
![Page 18: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/18.jpg)
Reason 2:You are tes*ng implementa*on
![Page 19: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/19.jpg)
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
![Page 20: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/20.jpg)
function testItGreetsPeopleByName(){ $user = $this->getMock('User');
$user->expects($this->once()) ->method('getName') ->willReturn('Ciaran');
$greeting = $this->greeter->greet($user);
$this->assertEquals('Hello, Ciaran!', $greeting);}
![Page 21: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/21.jpg)
function testItGreetsPeopleByName(){ $user = $this->getMock('User');
$user->method('getName') ->willReturn('Ciaran');
$greeting = $this->greeter->greet($user);
$this->assertEquals('Hello, Ciaran!', $greeting);}
![Page 22: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/22.jpg)
Don’t mock queries, just use stubsDo you really care how many /mes it's called?
![Page 23: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/23.jpg)
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
![Page 24: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/24.jpg)
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);}
![Page 25: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/25.jpg)
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);}
![Page 26: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/26.jpg)
Test behaviour you care about, don’t test implementa/on
PROTIP: The best way to do this is to not have an implementa3on yet
![Page 27: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/27.jpg)
Reason 3:Because your design sucks
![Page 28: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/28.jpg)
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
![Page 29: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/29.jpg)
public function setUp(){ $chargerules = $this->getMock('ChargeRules'); $chargetypes = $this->getMock('ChargeTypes'); $notifier = $this->getMockBuilder('Notifier') ->disableOriginalConstructor()->getMock();
$this->processor = new InvoiceProcessor( $chargerules, $chargetypes, $notifier ); }
![Page 30: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/30.jpg)
class InvoiceProcessor{ public function __construct( ChargeRules $chargeRules, ChargeTypes $chargeTypes, Notifier $notifier ) { $this->chargeRules = $chargeRules; $this->chargeTypes = $chargeTypes; $this->notifier = $notifier; }
// …
![Page 31: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/31.jpg)
Too many doubles in your test mean your class has too many
dependencies
![Page 32: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/32.jpg)
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
![Page 33: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/33.jpg)
public function testItNotifiesTheUser(){ $user = $this->getMock(User::class); $contact = $this->getMock(Contact::class); $email = $this->getMock(Email::class); $emailer = $this->getMock(Emailer::class);
$user->method('getContact')->willReturn($contact); $contact->method('getEmail')->willReturn($email); $emailer->expects($this->once) ->method('sendTo') ->with($this->equalTo($email));
(new Notifier($emailer))->notify($user);}
![Page 34: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/34.jpg)
class Notifier{ public function __construct(Emailer $emailer) { // … }
public function notify(User $user) { $email = $user->getContact()->getEmail()
$this->emailer->sendTo($email); }}
![Page 35: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/35.jpg)
class Notifier{ public function __construct(Emailer $emailer) { // … }
public function notify(User $user) { $this->emailer->sendTo($user); }}
![Page 36: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/36.jpg)
class Notifier{ public function __construct(Emailer $emailer) { // … }
public function notify(Email $email) { $this->emailer->sendTo($email); }}
![Page 37: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/37.jpg)
public function testItNotifiesTheUser(){ $email = $this->getMock(Email::class); $emailer = $this->getMock(Emailer::class);
$emailer->expects($this->once) ->method('sendTo') ->with($this->equalTo($email));
(new Notifier($emailer))->notify($user);}
![Page 38: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/38.jpg)
Stubs returning stubs indicate dependencies are not correctly
defined
![Page 39: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/39.jpg)
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
![Page 40: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/40.jpg)
class Form{ public function handle($data) { if ($this->validate($data)) { return 'Valid'; }
return 'Invalid'; }
protected function validate($data) { // do something complex }}
![Page 41: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/41.jpg)
function testItOutputsMessageOnValidData(){ $form = $this->getMock('Form', ['validate']); $form->method('validate')->willReturn(true);
$result = $form->handle([]);
$this->assertSame('Valid', $result);}
![Page 42: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/42.jpg)
class Form{ protected function __construct(Validator $validator) { // … }
public function handle($data) { if ($this->validator->validate($data)) { return 'Valid'; }
return 'Invalid'; }}
![Page 43: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/43.jpg)
function testItOutputsMessageOnValidData(){ $validator = $this->getMock(‘Validator’); $validator->method('validate')->willReturn(true);
$form = new Form($validator);
$result = $form->handle([]);
$this->assertSame('Valid', $result);}
![Page 44: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/44.jpg)
If you want to mock part of the SUT it means you should really have
more than one object
![Page 45: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/45.jpg)
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
![Page 46: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/46.jpg)
How long will it take without TDD?
• 1 hour thinking about how it should work
• 30 mins Implemen6ng it
• 30 mins Checking it works
![Page 47: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/47.jpg)
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
![Page 48: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/48.jpg)
Use your test suite as a way to reason about the code
![Page 49: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/49.jpg)
Customers should not dictate your design process
![Page 50: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/50.jpg)
Reason 4:You are unit tes,ng across domain
boundaries
![Page 51: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/51.jpg)
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
![Page 52: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/52.jpg)
class UserRepository extends \Framework\Repository{ public function findByEmail($email) { $this->find(['email' => $email]); }}
![Page 53: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/53.jpg)
public function testItFindsTheUserByEmail(){ $db = $this->getMock(\Framework\DatabaseConnection::class); $schemaCreator = $this->getMock(\Framework\SchemaCreator::class); $schema = $this->getMock(\Framework\Schema::class);
$schemaCreator->method('getSchema')->willReturn($schema); $schema->method('getMappings')->willReturn(['email'=>'email']); $db->method('query')->willReturn(['email'=>'[email protected]');
$repo = new UserRepository($db, $schemaCreator);
$user = $repo->findByEmail('[email protected]');
$this->assertType(User::class, $user);}
![Page 54: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/54.jpg)
class UserRepository{ private $repository;
public function __construct(\Framework\Repository $repository) { $this->repository = $repository; }
public function findByEmail($email) { return $this->repository->find(['email' => $email]); }}
![Page 55: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/55.jpg)
public function testItFindsTheUserByEmail(){ $fwRepo = $this->getMock(\Framework\Repository::class); $user = $this->getMock(User::class);
$repository = new UserRepository($fwRepo);
$fwRepo->method('find') ->with(['email' => '[email protected]') ->willReturn($user);
$actualUser = $repository->findByEmail('[email protected]');
$this->assertEqual($user, $actualUser);}
![Page 56: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/56.jpg)
When you extend third party code, you take responsibility for its
design decisions
![Page 57: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/57.jpg)
Favour composi'on over inheritance
![Page 58: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/58.jpg)
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
![Page 59: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/59.jpg)
public function testItUploadsValidDataToTheCloud(){ $validator = $this->getMock(FileValidator::class); $client = $this->getMock(\Cloud\Api::class); $file = $this->getMock(File::class);
$validator->method('validate') ->with($this->equalTo($file)) ->willReturn(true);
$validator->expects($this->once())->method('startUpload'); $client->expects($this->once())->method('uploadData'); $client->expects($this->once()) ->method('uploadSuccessful') ->willReturn(true);
(new FileHandler($client, $validator))->process($file);}
![Page 60: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/60.jpg)
Coupled architecture
![Page 61: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/61.jpg)
Coupled architecture
![Page 62: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/62.jpg)
Layered architecture
![Page 63: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/63.jpg)
Tes$ng layered architecture
![Page 64: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/64.jpg)
public function testItUploadsValidDataToTheCloud(){ $fileStore = $this->getMock(FileStore::class); $file = $this->getMock(File::class);
$validator->method('validate') ->with($this->equalTo($file)) ->willReturn(true);
(new FileHandler($fileStore, $validator))->process($file);}
![Page 65: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/65.jpg)
Tes$ng layered architecture
![Page 66: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/66.jpg)
class CloudFilestoreTest extends PHPUnit_Framework_TestCase{ /** @group integration */ function testItStoresFiles() { $testCredentials = … $file = new File(…);
$apiClient = new \Cloud\Api($testCredentials); $filestore = new CloudFileStore($apiClient);
$filestore->store($file);
$this->assertTrue($apiClient->fileExists(…)); }}
![Page 67: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/67.jpg)
Tes$ng layered architecture
![Page 68: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/68.jpg)
Don’t test other people’s codeYou don't know how it's supposed to behave
![Page 69: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/69.jpg)
Don’t test how you talk to other people’s code
You don't know how it's supposed to respond
![Page 70: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/70.jpg)
Pu#ng it all together
• Use TDD to drive development
• Use TDD to replace exis1ng prac1ces, not as a new extra task
![Page 71: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/71.jpg)
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?
![Page 72: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/72.jpg)
Image credits
• Human Evolu+on by Tkgd2007h-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)
![Page 73: Why Your Test Suite Sucks - PHPCon PL 2015](https://reader036.vdocuments.site/reader036/viewer/2022062503/587f3d2e1a28ab43318b4f3f/html5/thumbnails/73.jpg)
Thank you!
h"ps://joind.in/16248
@ciaranmcnulty