SlideShare a Scribd company logo
Getting Started with Test-Driven
Development
Scott Keck-Warren
Longhorn PHP 2023
@scottKeckWarren@phpc.social
https://tinyurl.com/tdd-longhorn-2023
Change
Change
Is Scary
Change
Is Stressful
Change
“Breaks” Production
“Don’t Push on Friday”
Testing “Goals” Module
7 Steps X 2 Users X 2 Modes = 10+ Minutes To Test
Testing “Goals” Module
• Brittle
• Lots of time consuming testing
• Annoyed Scott
I Needed Confidence
Automated Tests = Confidence
Test-Driven Development
Getting Started with Test-Driven
Development
Scott Keck-Warren
Longhorn PHP 2023
@scottKeckWarren@phpc.social
Scott Keck-Warren
Director of Technology
@ WeCare Connect
Scott Keck-Warren
PHP Developer
Scott Keck-Warren
Director of Technology
@ WeCare Connect
Scott Keck-Warren
Host
@ PHP[Architect] YouTube
Channel
Getting Started with Test-Driven Development at Longhorn PHP 2023
https://www.youtube.com/phparch
Agenda
Agenda
1. What Is Test-Driven Development?
2. Why You Should Be Using Test-Driven
Development?
3. How To Do Test-Driven Development?
4. Unit and Feature Testing
5. What is Code Coverage?
What is Test-Driven
Development (TDD)?
TDD:
A test-first software development
process that uses short
development cycles to write very
specific test cases and then modify
our code so the tests pass.
What is Test-Driven Development?
• Short cycles of 5 phases
• Less Minute
• Dozens/hundreds of cycles each day
Add A
New Test
Run All
Tests to
See
Failures
Make a
change
Run Tests
to See
Success
Refactor
Why Use Test-Driven
Development?
Why Use Test-Driven Development?
• Using TDD generate Automated Test Suite
• Infinitely repeatable
• Automated Test Suite Gives Us Confidence!
Why Use Test-Driven Development?
7 Steps X 2 Users X 2 Modes = 10+ Minutes To Test
Manual
Why Use Test-Driven Development?
7 Steps X 2 Users X 2 Modes = 10+ Minutes To Test
200+ Automated Tests
Why Use Test-Driven Development?
7 Steps X 2 Users X 2 Modes = < 2 Minutes To Test
200+ Automated Tests
Why Use Test-Driven Development?
Cycle Type: 2 Days
Why Use Test-Driven Development?
Cycle Type: 2 Days
Why Use Test-Driven Development?
Cycle Type: 2 Days
2 Hours
How Do You Do Test Driven
Development?
Add A
New Test
Run All Tests to
See Failures
Make a change
Run Tests to
See Success
Refactor
Add A
New Test
Run All
Tests to
See
Refactor
Add A
New Test
Run All
Tests to
See
Failures
or
Add A
New Test
Run All
Tests to
See
Failures
or
Failures
Make a
change
Run Tests
to See
Success
Failures
Make a
change
Run Tests
to See
Success
Add A
New Test
R
T
F
Refactor
Refactor:
Restructure so as to improve operation
without altering functionality
#5. Refactor
TDD + Refactoring
=
No Happy Accidents
Add A
New Test
R
T
F
Refactor
Add A
New Test
Run All
Tests to
See
Failures
Make a
change
Run Tests
to See
Success
Refactor
Unit Test Example
Unit Tests:
Test single class/module in
isolation
Getting Started with Test-Driven Development at Longhorn PHP 2023
Value Objects in
About a Minute
Value Objects
1.Structural Equality
2.Immutability
3.Self-validation
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
src/Location/City.php
Testing Framework/Tool
PHPUnit
PHPUnit
• Testing Framework
• All tests are written in PHP
PHPUnit
• Organization is easy
• Test files inside a tests folder
• A PHP class groups similar tests together
• A test is a PHP class method
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
./vendor/bin/phpunit
./vendor/bin/phpunit tests/Location/CityTest.php
./vendor/bin/phpunit —filter User
Framework + IDE = More Efficiency
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
./vendor/bin/phpunit tests/Location/CityTest.php
Unit Test Example
Add A
New Test
src/Location/City.php
tests/Location/City.php
tests/Location/CityTest.php
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Run All
Tests to
See
Failures
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Make a
change
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Run Tests
to See
Success
Getting Started with Test-Driven Development at Longhorn PHP 2023
Refactor
Another Day Another Test
Add A
New Test
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Run All
Tests to
See
Failures
Getting Started with Test-Driven Development at Longhorn PHP 2023
Make a
change
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Run Tests
to See
Success
Getting Started with Test-Driven Development at Longhorn PHP 2023
Refactor
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
isNotEmpty()
vs
Add A
New Test
Getting Started with Test-Driven Development at Longhorn PHP 2023
Run All
Tests to
See
Failures
Getting Started with Test-Driven Development at Longhorn PHP 2023
Make a
change
Getting Started with Test-Driven Development at Longhorn PHP 2023
Run Tests
to See
Success
Getting Started with Test-Driven Development at Longhorn PHP 2023
Refactor
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Unit Test Example
Feature Test Example
Feature Test
Tests application as user would interact with it
Getting Started with Test-Driven Development at Longhorn PHP 2023
Pest
PHPUnit
Pest
• Test files inside a tests/unit or tests/feature folder
• A test is a PHP function
• A “.php” file groups common tests
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
./vendor/bin/pest
./vendor/bin/pest tests/Unit/Location/CityTest.php
./vendor/bin/pest —filter User
Getting Started with Test-Driven Development at Longhorn PHP 2023
As a user, provide a page that lists all GitHub repositories the user has
access to
Feature Test Example
User
User Server
Server
GitHub
GitHub
/repositories/all
API Call
JSON
HTML
Feature Test Example
User
User Server
Server
GitHub
GitHub
/repositories/all
API Call
JSON
HTML
AppServiceGitHub
AppProvidersAppServiceProvider
Add A
New Test
Getting Started with Test-Driven Development at Longhorn PHP 2023
RepositoryControllerTest.php
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
RepositoryControllerTest.php
RepositoryControllerTest.php
RepositoryControllerTest.php
RepositoryControllerTest.php
Run All
Tests to
See
Failures
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Make a
change
Getting Started with Test-Driven Development at Longhorn PHP 2023
routes/auth.php
Getting Started with Test-Driven Development at Longhorn PHP 2023
RepositoryController.php
RepositoryController.php
Run Tests
to See
Success
Getting Started with Test-Driven Development at Longhorn PHP 2023
Refactor
Feature Test Example
User
User Server
Server
GitHub
GitHub
/repositories/all
API Call
JSON
HTML
Add A
New Test
RepositoryControllerTest.php
Run All
Tests to
See
Failures
Getting Started with Test-Driven Development at Longhorn PHP 2023
Make a
change
RepositoryController.php
RepositoryController.php
RepositoryController.php
RepositoryController.php
AppServiceGitHub
AppServiceGitHub
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Feature Test Example
User
User Server
Server
GitHub
GitHub
/repositories/all
API Call
JSON
HTML
Options?
1. Ignore It and Hope for the Best
2. Give my access token to the tests
3. Mock it!
Mocking:
Help isolate the external
dependency to make it easier to
test
Mockery_2_App_Service_GitHub
Mocking
AppServiceGitHub
getAllRepositoriesForCurrentUser()
isAuthenticated()
getAllRepositoriesForCurrentUser()
RepositoryControllerTest.php
RepositoryControllerTest.php
RepositoryControllerTest.php
RepositoryControllerTest.php
RepositoryControllerTest.php
RepositoryControllerTest.php
RepositoryControllerTest.php
Run Tests
to See
Success
Getting Started with Test-Driven Development at Longhorn PHP 2023
Getting Started with Test-Driven Development at Longhorn PHP 2023
Refactor
Feature Test Example
What is Code Coverage?
Code Coverage:
A software testing metric that
determines how much of your
code is run during your test
process.
What is Code Coverage?
Executed Lines / Total Lines * 100
What is Code Coverage?
What is Code Coverage?
What is Code Coverage?
What is Code Coverage?
What is Code Coverage?
What is Code Coverage?
Executed / Total * 100
What is Code Coverage?
1 / Total * 100
What is Code Coverage?
1 / 2 * 100
What is Code Coverage?
50%
What is Code Coverage?
What is Code Coverage?
XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text
What is Code Coverage?
What's a Good Coverage
Number?
“It depends”
What's a Good Coverage Number?
75-90%
What's a Good Coverage Number?
< 75 => no confidence
What's a Good Coverage Number?
> 90 fragile, expensive
What's a Good Coverage Number?
Overall: 80%+
What's a Good Coverage Number?
Billing: 95%+
What is Code Coverage?
What is Code Coverage?
Getting Started with Test-Driven Development at Longhorn PHP 2023
What You Need to Know
What You Need to Know
• TDD: test-first software development process
• Gives us confidence to make changes
• Five short phases
• Each of the phases happens very quickly
• Don’t neglect to refactor
What You Need to Know
Add A
New Test
Run All
Tests to
See
Failures
Make a
change
Run Tests
to See
Success
Refactor
What You Need to Know
• Use a testing framework like PHPUnit/Pest
• Write clear and concise tests
• Unit tests: tests code in isolation
• Feature tests: tests code as user interacts with it
• Code coverage determines if our code has enough tests
Thank The Sponsors!
Thank The Sponsors!
Thank The Organizers!
Thank The Speakers!
Thank Scott!
• Feedback on joind.in
• Follow me on my socials
• @scottkeckwarren@phpc.social
• scottkeckwarren on:
• TikTok/Twitch/X
• Subscribe to YouTube Channel
Questions?
• Scott Keck-Warren
• Resources:
• https://tinyurl.com/tdd-longhorn-2023

More Related Content

Similar to Getting Started with Test-Driven Development at Longhorn PHP 2023 (20)

ODP
Tdd in php a brief example
Jeremy Kendall
 
PDF
Intro to PHP Testing
Ran Mizrahi
 
PPT
Test Driven Development using QUnit
satejsahu
 
PPTX
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
Iranian Domain-Driven Design Community
 
PPT
Test Driven Development and Automation
Mahesh Salaria
 
PDF
Unit testing in PHP
Chonlasith Jucksriporn
 
PDF
Test Driven Development - Workshop
Anjana Somathilake
 
PDF
Introducing TDD to your project
Bastian Feder
 
PPTX
PHPUnit: from zero to hero
Jeremy Cook
 
PDF
Test driven development - Zombie proof your code
Pascal Larocque
 
PDF
It's all about behaviour, also in php - phpspec
Giulio De Donato
 
PPTX
Unit Testing talk
Sergei Kukharev
 
PPT
Test Driven Development with PHPUnit
Tuan Nguyen
 
PDF
Test driven development : software process
Amin Taheri
 
PPTX
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
PDF
Test Driven Development Methodology and Philosophy
Vijay Kumbhar
 
PDF
Test Drive Development
satya sudheer
 
PPTX
Advanced Test Driven-Development @ php[tek] 2024
Scott Keck-Warren
 
PPT
Test driven-development
David Paluy
 
PPTX
Introduction to test driven development
Brian Hogg
 
Tdd in php a brief example
Jeremy Kendall
 
Intro to PHP Testing
Ran Mizrahi
 
Test Driven Development using QUnit
satejsahu
 
Ian Cooper webinar for DDD Iran: Kent beck style tdd seven years after
Iranian Domain-Driven Design Community
 
Test Driven Development and Automation
Mahesh Salaria
 
Unit testing in PHP
Chonlasith Jucksriporn
 
Test Driven Development - Workshop
Anjana Somathilake
 
Introducing TDD to your project
Bastian Feder
 
PHPUnit: from zero to hero
Jeremy Cook
 
Test driven development - Zombie proof your code
Pascal Larocque
 
It's all about behaviour, also in php - phpspec
Giulio De Donato
 
Unit Testing talk
Sergei Kukharev
 
Test Driven Development with PHPUnit
Tuan Nguyen
 
Test driven development : software process
Amin Taheri
 
Unit Testng with PHP Unit - A Step by Step Training
Ram Awadh Prasad, PMP
 
Test Driven Development Methodology and Philosophy
Vijay Kumbhar
 
Test Drive Development
satya sudheer
 
Advanced Test Driven-Development @ php[tek] 2024
Scott Keck-Warren
 
Test driven-development
David Paluy
 
Introduction to test driven development
Brian Hogg
 

More from Scott Keck-Warren (8)

PPTX
Reducing Bugs With Static Code Analysis php tek 2025
Scott Keck-Warren
 
PPTX
SQL Database Design For Developers at PhpTek 2025.pptx
Scott Keck-Warren
 
PPTX
SQL Database Design For Developers - Cascadia PHP 2024.pptx
Scott Keck-Warren
 
PPTX
Time, Why You Punish Me - Cascadia PHP 2024
Scott Keck-Warren
 
PPTX
SQL Database Design For Developers at php[tek] 2024
Scott Keck-Warren
 
PPTX
Static Code Analysis PHP[tek] 2023
Scott Keck-Warren
 
PPTX
Developing a Culture of Quality Code at Givelify (Tech Talk)
Scott Keck-Warren
 
PPT
Developing a Culture of Quality Code (Midwest PHP 2020)
Scott Keck-Warren
 
Reducing Bugs With Static Code Analysis php tek 2025
Scott Keck-Warren
 
SQL Database Design For Developers at PhpTek 2025.pptx
Scott Keck-Warren
 
SQL Database Design For Developers - Cascadia PHP 2024.pptx
Scott Keck-Warren
 
Time, Why You Punish Me - Cascadia PHP 2024
Scott Keck-Warren
 
SQL Database Design For Developers at php[tek] 2024
Scott Keck-Warren
 
Static Code Analysis PHP[tek] 2023
Scott Keck-Warren
 
Developing a Culture of Quality Code at Givelify (Tech Talk)
Scott Keck-Warren
 
Developing a Culture of Quality Code (Midwest PHP 2020)
Scott Keck-Warren
 
Ad

Recently uploaded (20)

PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
Empowering Cloud Providers with Apache CloudStack and Stackbill
ShapeBlue
 
PPTX
✨Unleashing Collaboration: Salesforce Channels & Community Power in Patna!✨
SanjeetMishra29
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
Windsurf Meetup Ottawa 2025-07-12 - Planning Mode at Reliza.pdf
Pavel Shukhman
 
PDF
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
PDF
Women in Automation Presents: Reinventing Yourself — Bold Career Pivots That ...
DianaGray10
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
PDF
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
PPT
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PPTX
Top iOS App Development Company in the USA for Innovative Apps
SynapseIndia
 
PDF
NewMind AI Journal - Weekly Chronicles - July'25 Week II
NewMind AI
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
Empowering Cloud Providers with Apache CloudStack and Stackbill
ShapeBlue
 
✨Unleashing Collaboration: Salesforce Channels & Community Power in Patna!✨
SanjeetMishra29
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
Windsurf Meetup Ottawa 2025-07-12 - Planning Mode at Reliza.pdf
Pavel Shukhman
 
Human-centred design in online workplace learning and relationship to engagem...
Tracy Tang
 
Women in Automation Presents: Reinventing Yourself — Bold Career Pivots That ...
DianaGray10
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
Apache CloudStack 201: Let's Design & Build an IaaS Cloud
ShapeBlue
 
Interview paper part 3, It is based on Interview Prep
SoumyadeepGhosh39
 
July Patch Tuesday
Ivanti
 
Why Orbit Edge Tech is a Top Next JS Development Company in 2025
mahendraalaska08
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
SWEBOK Guide and Software Services Engineering Education
Hironori Washizaki
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
Top iOS App Development Company in the USA for Innovative Apps
SynapseIndia
 
NewMind AI Journal - Weekly Chronicles - July'25 Week II
NewMind AI
 
Ad

Getting Started with Test-Driven Development at Longhorn PHP 2023

Editor's Notes

  • #4: As humans, change can be scary
  • #5: My grocery store changed layout and couldn’t find coffee for three weeks
  • #6: As developers, we know that change breaks production No mater how small the change I’ve fixed a spelling error in a string and created a bug That leads to…<click>
  • #7: Whose heard this one before <slide> That’s way my mantra because I don’t want to have to boot my work computer up on Sunday
  • #8: Maintained a module to set professional development goals Process had seven steps <click> Alternated between supervisor and direct <click> Two “modes” <click> Testing took a minimum of 10 minutes<click> Manual so Error prone. Sometimes I would make a mistake in step 2 and not realize to step 6 and have to start over God forbid I was on vacation and someone else made the change
  • #9: Because there we so many moving parts: <slide> Someone would say can we add a new feature I would say yes very reluctantly and then tell them 2 days minimum
  • #10: Confidence that I could make changes Not break anything Hard to do with all the manual testing Looked for a solution
  • #11: How do we create automated tests Lots of options
  • #12: Cloud image in the back TDD gave me that confidence
  • #14: For those of you who haven’t met me my name is …
  • #15: Professional PHP Developer for 15 years // team lead/CTO role for 10 of those 15
  • #16: Currently Director of Technology at WeCare Connect Survey solutions to improve employee and resident retention at skilled nursing facilities Use PHP for our backend Also …
  • #17: Create Educational Videos on PHPArchitect YouTube
  • #18: Discuss topics helpful for PHP developers If you want more content like this session follow me on social media and subscriber to our channel
  • #19: Found at youtube.com/phparch
  • #20: Could spend hours discussing automated testing with you all. It’s one of my favorite PHP adjacent topics but we only have 50 minutes. My goals are to always have you leave one of my sessions with something you can use the next day you’re going to work and how you can implement this with your team
  • #24: TDD consists of five phases that we will repeat as we modify our code. Each of the phases happens very quickly and we might go through all five phases in less than a minute.
  • #27: Back to our goals module from before Problem was on this side because it was manual <click>
  • #28: Wrote 200+ automated tests for Goals Module Still had that complexity but I didn’t care
  • #29: Was 10 minutes now less 2 minutes Wasn’t even 2 active minutes I could step away from my computer Could confidently make a changes Didn’t forget steps Cycle time dropped from days to hours
  • #30: Cycle time dropped from days
  • #31: To
  • #32: Hours
  • #33: Abstract then concrete
  • #34: TDD consists of 5 SHORT phases < ten new lines of code being modified. If we find ourselves doing more than that we're working on too large a change and we need to break it into smaller pieces.
  • #35: The first thing we're going to do is write a failing test. We'll use this failing test to help determine when we've achieved our expected functionality.
  • #36: 2. Run all tests and see the new one fail In this step, we're going to run the test to make sure our test fails before we move on to the next phase. It's very easy to write a test that doesn't fail so we **always** run our test to verify it's failing before moving to the next phase. If it’s not failing we don’t know if our change actually did anything
  • #37: As a small aside, the wording for this phase says "run all the tests" but as our test suite (a collection of tests) grows this will take an unproductively large amount of time. Current code base takes 25 minutes to run whole suite. We'll want to short circuit this and only run the test file or just our new test.
  • #38: 3. Make a little change Now our goal is to change the smallest amount of code possible to get that test to pass. We don't want to change any more than is necessary because that extra bit of change wasn't made using TDD and is potentially not tested. We don't need perfect code in this phase we just need code that makes the test pass. It's very easy to get caught up in making sure everything is perfect but that's not the goal here. Perfect comes later.
  • #39: 4. Run all tests and see them all succeed Now that we've made our change we can run our test and see that it passes new test and any other tests. If it doesn't then we just jump back to phase #3 and keep making small changes until it does.
  • #40: 5. Refactor to remove duplication Now that we have our tests passing we're going to take a break and inspect both our test code and our code under test to see where we can make changes so it's easier for future developers to read, understand, and maintain.
  • #41: This is called Refactoring and it’s: restructure code so as to improve operation without altering functionality.
  • #42: We're using TDD so changes are painless because we can quickly run our unit tests again to make sure we didn't make a mistake.
  • #43: Now that we've completed a single TDD cycle we can start back at the beginning with a new test.
  • #44: If you google TDD There’s also a three phase version Called Red, green, refactor Red and green come from colored messages we get from our testing tool Basically group phases 1 and 2 and 3 and 4. I like 5 phases because it gives explicit steps
  • #45: This has been all very abstract so lets make it more concrete
  • #46: Fast Good starting point for new classes
  • #47: Been working on an open source project for the YouTube Channel Value objects
  • #48: Did a whole video on how awesome value objects are Nee
  • #49: Custom classes for each domain type in our application Provide three things
  • #50: Problem they solve is this Have a function to recreate user Need first, last, email
  • #51: Later call the function Made an Oops <click>
  • #52: Should be <comment order> Did email first Tricky kind of bug Dare you to find this in code review
  • #54: Now I can’t mess up calling this And Helper functions
  • #56: before we go further This is a contrived example Feel free to roll your eyes as I’m doing stupid things to make my point Don’t use this as evidence for a future job
  • #57: I have this value object class to track a City Only important thing is that we’re storing our information in $value property Want to add more functionality using TDD
  • #58: First thing we need is a <slide>
  • #59: This example uses PHPUnit to run our tests as the project is already using phpunit Talk about the other framework later
  • #60: In case you don’t know Testing Framework All tests are written in PHP so we don’t need to learn anything new
  • #61: Organization is easy All test files are placed inside a tests folder at the root of the project A test is a PHP class method
  • #62: Each test function starts with “test” or …
  • #63: uses the @test annotation This is a personal preference thing. I learned PHPUnit before annoation option so I default to prefixing tests with test. Also uses less vertical space which helpful for presentations
  • #64: Might notice assert function calls Each test function contains one or more asserts
  • #65: Asserts tell PHPUnit to compare an expected value to the value we got from our codeEach test contains one or more asserts Compare output values <click> Compare expected value vs output <click> Check for greater than or equal <click>
  • #66: Command line tool Super powerful
  • #67: Run a single file
  • #68: Use filter to reduce runs Example anything that involves users
  • #72: Our examples today mostly command line Running using ./vendor/bin/phpunit tests/FileTest.php
  • #74: 1. Add a new test
  • #75: No tests for City because there wasn’t any logic to test First step is to create the test file <screen> is current file
  • #76: Swap tests for src
  • #77: And append test That way can easily find tests for city class
  • #78: Start with our blank file
  • #79: Create class Class name needs to match the file name -> new PHPunit doesn’t like mismatch
  • #80: Extends PHPUnit\Framework\TestCase . TestCase class gives us asserts and setup logic we need This is just boiler plate so far Remember this when we talk about Pest
  • #81: Let’s remember what we want to do because I’ve rambled Not sure how I want to do this so let’s start coding and figure it out
  • #82: Create the test function. We’re going to name the function based on what we’re testing to it’s easier to understand when future us comes back to it.
  • #83: Create Our Initial Conditions
  • #84: Run the code we’re going to test
  • #85: Assert the results Don’t like the useless variable here so we’ll get rid of it
  • #86: Notice how small the actual test is. We're giving the test a very specific functionality to test and we're only asserting one thing. If we have more than one assert per test we run the risk of making it difficult to debug later when something breaks.
  • #87: 2. Run all tests and see the new one fail
  • #88: Now we'll run PHPUnit to see that we do indeed get a failing test.
  • #89: In this case, we haven't yet defined the method so we get an "undefined method" error. Red message -> in an error state like we saw in red/green/refactor
  • #90: 3. Make a little change To reiterate, our goal in this phase is to make the smallest change we can to allow our tests to pass. Two options here: <click>
  • #91: add in the obvious implementation Obvious means is a few lines that we can’t possibility mess up the logic for This case just call to mb_strlen
  • #92: 2 - Make the smallest possible change by returning true always. It doesn't cover all the possible inputs but the goal in this step isn't to cover all the inputs it's to get our test to pass. We'll cover more inputs later.
  • #93: We’re going to want to show another cycle of TDD so we’re going to just return true
  • #94: 4. Run all tests and see them all succeed
  • #95: Now we run our test and verify that our test passes. Notice green from red/green/refactor
  • #96: 5. Refactor
  • #97: Our simple implementation of `somefunction()` is going to be wrong most of the time because of its current implementation. Now we need to add another test that checks for other cases where the string isn't empty. As a general rule, it's a good idea to have tests for normal input, the extremes of inputs (very large or very small), and spots where we can think of oddities happening obviously very domain specific We’re going to check for a case where the string isn’t empty to add an addition testing point
  • #98: 1. Add a new test
  • #99: Add a new test What we have currently
  • #100: Add in the opposite
  • #101: 2. Run all tests and see the new one fail
  • #102: This time we get a failure assertion that true is false
  • #103: 3. Make a little change
  • #104: Look at our original code Could change to return false but that would cause other tests to fail
  • #105: Back to the obvious implementation we had before
  • #106: 4. Run all tests and see them all succeed
  • #108: 5. Refactor
  • #109: We have working code that fulfills the requirements Right? Done? Maybe? Let’s look at how this looks in usage
  • #110: Basic if block I’m going to come across someFunction and have no idea what it is Going to slow me down and that’s annoying Excellent time to refactor and pick a new name Lots of options
  • #111: Don’t like this because its a verb so we could be performing an action
  • #112: isEmpty sounds good to me Sounds like a sentence
  • #113: Back to our code now
  • #114: After refactor Subjectively better?
  • #115: No happy accidents
  • #116: Starting to get the hang of this Adding a test now to check for a string that isn’t empty.
  • #117: Could do !isEmpty() but isNotEmpty is actually easier for us to process as programmers so it’s nice to have Also contrived example
  • #118: 1. Add a new test
  • #119: Again small Again written so we know what’s going on quickly
  • #120: 2. Run all tests and see the new one fail
  • #122: 3. Make a little change
  • #123: In this case instead of returning `false` and then creating another test so we can write the functionality by going through all the TDD steps, we're just going to trust ourselves and create the obvious implementation of the `isNotEmpty()` function.
  • #124: 4. Run all tests and see them all succeed
  • #125: Oh good we didn’t make any mistakes
  • #126: 5. Refactor to remove duplication Now here is where it gets interesting.
  • #127: The last two times we've hit this step we haven't had anything to do but now look at our `isEmpty()` and `isNotEmpty()` functions.
  • #128: We can see some minor duplication in the two calls to `mb_strlen($this->string)`. Now we just need to determine how we want to resolve this. 2 options: Option 1 is to extract that duplication into a new function.
  • #129: Call it length and copy duplication into body Extracting a new function is favorite refactor because it makes the code more readable and because we'll most likely need the same logic again.
  • #130: Now The replace the calls with the new function
  • #131: The second option is to realize that `isNotEmpty()` returns the boolean opposite of `isEmpty()` and just use it
  • #132: If I hadn’t been working through this example just to get to this who cares example I think I would have done this automatically. The first option gives us the best flexibility for future expansion but second less code. Always a fond of less code
  • #133: Finally, we need to run our tests again to verify that no accidents crept into our code as we made these changes.
  • #134: That’s how we do unit tests Until today this is where the “coding” piece ended Someone on joind.in gave me feedback that it was too simple so
  • #135: In our example, we worked out an example of tests where we only tested a single class. Generally that’s where these presentations stop but we can do better right
  • #136: Slower than unit tests Working with local databases and services Great for high coverage (discuss later)
  • #137: Over on my Twitch stream slowly working on this Tool to help with Pull Requests Lots of ideas on what to do Time to tackle another item off my backlog
  • #138: Wanted to use all the newest/greatest projects in PHP space for this project so using Pest Testing Framework <click>Built on top of PHPUnit Can use with existing PHPunit tests There are some differences
  • #139: Organization is easy All test files are placed inside a tests folder at the root of the project A test is a PHP function
  • #140: Uses expectation API
  • #141: Built on top of PHPUnit so we can still use assertion api I love how expressive the expectation API is but tend to fall back to assertions
  • #142: Command line tool Super powerful Again run with not parameters to run all tests
  • #143: Run a single file
  • #144: Use filter to reduce runs Example anything that involves users
  • #147: Maybe this is more complicated? Let’s look at a flow diagram of what we’re doing <Click through steps> It’s a lot right? Don’t feel like I can write an easy test for this
  • #148: Tackle one small piece only First test: Can access /organizations/all
  • #149: Only thing that exists now: GitHub service Takes the current user’s OAuth token and creates a connection to GitHub using 3rd party package
  • #150: Only thing that exists now: GitHub service Takes the current user’s OAuth token and creates a connection to GitHub
  • #151: 1. Add a new test
  • #160: 2. Run all tests and see the new one fail
  • #163: 3. Make a little change To reiterate, our goal in this phase is to make the smallest change we can to allow our tests to pass. Two options here: <click>
  • #168: It doesn’t do anything but again smallest amount of code possible
  • #169: 4. Run all tests and see them all succeed
  • #171: 5. Refactor to remove duplication Kept it DRY to start so we’re good
  • #172: Second test the rest?
  • #173: 1. Add a new test
  • #175: 2. Run all tests and see the new one fail
  • #177: 3. Make a little change To reiterate, our goal in this phase is to make the smallest change we can to allow our tests to pass. Two options here: <click>
  • #179: I’m going to ignore creating the blade file here because it’s not interesting and hard to read
  • #181: getAllRepositoriesForCurrentUser
  • #183: Break with process and see actually results
  • #184: Uggg, look at all the abandoned side projects <click> But do see ScottsValueObjects
  • #186: External Dependency Have zero control over it Data might change Worse it requires: login active connection to internet
  • #188: Use a library This case we’re using Mockery library Allows us to specify return values from functions
  • #190: Pest has support to override the service container for our mock
  • #197: 4. Run all tests and see them all succeed
  • #199: Uggg, look at all the abandoned side projects But do see ScottsValueObjects
  • #200: 5. Refactor to remove duplication Again dry code so no refactoring
  • #201: That’s a feature test Small amount of testing code tests large amount of user land code Allows for high code coverage
  • #204: The "total number of lines of code" only includes lines that are performing operations and not declarations and white space.
  • #205: As an example, this class
  • #206: Single test to see that we can initialize our class
  • #207: Let’s see what our coverage is
  • #208: Only two lines are executable
  • #209: Only the assignment is actually run during this test
  • #210: Calcaluation on the board to help us
  • #213: <result> Manual isn’t going to work because our code is always changing
  • #214: Thankfully
  • #215: Need to also have XDEBUG or another tool installed SET mode to coverage
  • #216: Spits out same result
  • #220: < 75% -> hard to feel confident making changes
  • #221: > 90% -> fragile, expensive tests
  • #222: Personally my team targets 80%
  • #223: Missing critical stuff we target 95% Want to make this part of our
  • #224: Running at the command line also is a little rough so I like to include it in my CI/CD runs Like to use Codecov but there’s a million of these SaaS companies that do this
  • #225: Spits out results in our PR
  • #226: Also shows lines that aren’t being covered by a test
  • #229: 1. Add a new test 2. Run all tests and see the new one fail 3. Make a little change 4. Run all tests and see them all succeed 5. Refactor to remove duplication
  • #232: Add QR code here
  • #236: Add QR code here