Longhorn PHP 2025 Day 3
Scott Keck-Warren • October 28, 2025
AssertTrue(isDecoupled("my tests"))
values of tests = cost of bugs found by tests - cost of test suite
Coupling: the amount of knowledge A knows about B A (application code) has thin later to connect to B (send emails) Test Doubles looks like B but isn't Problems with Tight Coupling
Page Object
Provides a cleaner interface to run tests
Test -> Page Object --> Software Under Test Page object can change without changing
To reduce coupling futher we can add a DSL Layer
Test -> DSL Layer -> Page Objects --> Software Under Test Multiple tests -> multiple DSL Layers -> Multiple Systems -> Software Under test
Use interfaces to define how business logic acts with framework/outside Use interfaces to create mocks/test doubles
Building Data Services
"Hand building":
// this eveywhere
$this->userService->registerUser....
Object Mother
$user = $this->userObjectMother->getAnna();
Test Builder
$userBuilder = new UserBuilder() $userBuilder = $user->builder // stuff ->create()
Combo Object Mothers/Test Builders for building data structures
From PHP 5.3 to PHP 8: Conquering Legacy Code Migration Under Deadline Pressure
Work Smarter: Code Like a Musician
Set and Setting - what's your mind set and where are you?
Set yourself up for success mentally and physically
Problem Solving Stategies
Break it down Try multiple ideas Work in reverse Ask for help Time box
Dealing with Failure
Know your role
Disagree Graciously
Commnicate to Empower
Use the senior-php-software-engineer subagent to get the tests in @tests/Unit/Events/PodcastEpisodeCreatedTest.php to pass
Always require approval before making changes. Use TDD to first create tests before creating the application code, use @phpcs.xml coding standard, and make sure make test passes.