public function testAddReturnsCorrectSum(): void
{
$calculator = new Calculator();
$this->assertEquals(5, $calculator->add(2, 3));
}
Topics
46
Arrays in PHP
Asynchronous PHP (ReactPHP & Swoole)
Basics & Types
Caching Strategies in PHP
Closures & Anonymous Functions
Composer
Constants & Superglobals
Date & Time Handling
Dependency Injection & Service Containers
Deployment & Hosting for PHP Applications
Design Patterns in PHP
Eloquent ORM & Doctrine ORM
Email Sending in PHP (PHPMailer & SMTP)
Error & Exception Handling
File Handling & File System Functions
File Upload Handling
Form Handling & Validation
Functions & Scope
Generators & Iterators
Interfaces & Abstract Classes
JSON Handling in PHP
Laravel Framework Essentials
Magic Methods
MVC Architecture in PHP
Namespaces & Autoloading
OOP
Package Development & Publishing with Composer
PDO & Databases
Performance Optimization & OPcache
PHP 8 Features (Attributes, Enums, Match, Nullsafe Operator)
PHP CLI Scripting
PHP with Docker
Regular Expressions in PHP
RESTful API Development with PHP
Routing & Middleware
Security
Sessions & Cookies
Static Analysis (PHPStan & Psalm)
Strings & String Functions
Symfony Framework Essentials
Template Engines (Blade & Twig)
Traits
Type Declarations & Strict Types
Unit Testing with PHPUnit
WordPress Plugin & Theme Development
XML Handling in PHP
Unit Testing with PHPUnit
7 questions found
PHPUnit is the most widely used testing framework in the PHP ecosystem, providing the tools needed to write, organize, and run automated tests against your code, and a unit test specifically focuses on verifying that one small, isolated piece of code, typically a single function or method, behaves exactly as expected when given a specific set of inputs, checking that it produces the correct output or correctly performs the expected action, without needing to manually and repeatedly test that same logic by hand every single time a change is made.
Real-world example
A developer writes a unit test verifying that a Calculator class's add method correctly returns five when given the inputs two and three, and can now run that same test automatically at any time to instantly confirm that behavior still works correctly.
Static Analysis (PHPStan & Psalm);Functions & Scope
What are assertions in PHPUnit, and how do commonly used assertions like assertEquals and assertTrue let you verify expected behavior within a test?
BeginnerAn assertion is a statement within a test that checks whether an actual value matches an expected value, and if that check fails, the entire test is immediately marked as failed with a clear message describing exactly what was expected versus what was actually received, and PHPUnit provides a large number of built in assertion methods covering many common comparison needs, including assertEquals to check that two values are equal, assertTrue and assertFalse to check a boolean condition, and assertCount to check the exact number of items within an array.
public function testUserIsActiveByDefault(): void
{
$user = new User('Sarah');
$this->assertTrue($user->isActive());
}
Real-world example
A test verifying that a newly created User object is active by default uses the assertTrue assertion to directly check the boolean result returned by calling the isActive method on that new object.
Type Declarations & Strict Types;OOP
What is the arrange act assert pattern, and how does structuring a test around these three distinct steps make tests clearer and easier to understand?
IntermediateThe arrange act assert pattern is a widely recommended way to structure the internal logic of an individual test, first arranging any necessary setup, such as creating the objects and data the test will need, then performing the single specific action being tested, such as calling the particular method under test, and finally asserting that the actual resulting outcome matches what was genuinely expected, and consistently following this three step structure across every test makes each individual test easier to read and understand at a glance, even for someone unfamiliar with that specific piece of code.
public function testDiscountIsAppliedCorrectly(): void
{
// Arrange
$cart = new ShoppingCart();
$cart->addItem('Book', 20.00);
// Act
$cart->applyDiscount(0.10);
// Assert
$this->assertEquals(18.00, $cart->getTotal());
}
Real-world example
A test verifying a shopping cart's discount logic clearly separates the setup of adding an item, the actual action of applying a ten percent discount, and the final assertion checking the resulting total, making the test's intent immediately obvious to anyone reading it.
Functions & Scope;Design Patterns in PHP
What are mock objects in PHPUnit, and why are they useful when testing a piece of code that depends on an external service, such as sending an email or calling a third party API?
IntermediateA mock object is a fake, controlled substitute for a real dependency, created specifically for use within a test, and using a mock instead of the actual real dependency lets you test a piece of code in complete isolation without needing to genuinely send a real email, make an actual external API call, or hit a real database, while also letting you precisely control exactly what that fake dependency returns and verify exactly how many times and with what specific arguments it was actually called, which makes tests significantly faster, more reliable, and fully repeatable regardless of the availability of any real external service.
public function testOrderConfirmationEmailIsSent(): void
{
$mailer = $this->createMock(MailerInterface::class);
$mailer->expects($this->once())->method('send');
$orderService = new OrderService($mailer);
$orderService->confirmOrder($order);
}
Real-world example
A test verifying that placing an order triggers a confirmation email uses a mock mailer object instead of an actual real mailer, confirming the send method was called exactly once without ever genuinely sending a real email during the test run.
Email Sending in PHP (PHPMailer & SMTP);Dependency Injection & Service Containers
What is test coverage, and why should achieving a high test coverage percentage not necessarily be treated as the sole ultimate goal of a testing strategy?
IntermediateTest coverage measures what percentage of a codebase's actual lines or branches of code are executed at least once while running the full test suite, and while reasonably high test coverage is generally a positive sign, it should not be treated as the sole measure of genuine test quality, since a test can technically execute a line of code without actually verifying that the code produced the correct result, meaning a codebase could show high coverage while still containing weak, ineffective tests that would fail to actually catch a real bug if one were introduced.
vendor/bin/phpunit --coverage-html coverage-report
Real-world example
A team notices their codebase shows ninety five percent test coverage but still experiences frequent production bugs, and upon investigation discovers many of their existing tests execute the relevant code without actually asserting anything meaningful about its correctness.
Static Analysis (PHPStan & Psalm);Design Patterns in PHP
How do data providers in PHPUnit let you run the exact same test logic repeatedly against many different sets of input data, without duplicating the test method itself?
AdvancedA data provider is a separate method that returns a collection of different input and expected output combinations, and by associating a test method with a data provider, PHPUnit will automatically run that same single test method once for every individual data set the provider returns, which avoids writing many nearly identical, separate test methods that only differ in their specific input values, and makes it very easy to thoroughly test a piece of logic against a wide range of different scenarios, including various edge cases, all through one single, reusable test method.
public function additionProvider(): array
{
return [[1, 1, 2], [2, 3, 5], [-1, 1, 0]];
}
/** @dataProvider additionProvider */
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertEquals($expected, (new Calculator())->add($a, $b));
}
Real-world example
A test verifying an addition method uses a data provider supplying several different pairs of numbers along with their correctly expected sums, running the exact same underlying test logic automatically against each individual data set without needing to write several nearly duplicate test methods.
Type Declarations & Strict Types;Functions & Scope
How does test driven development, commonly abbreviated as TDD, change the typical order in which tests and actual implementation code are written, and what benefits does this workflow claim to offer?
AdvancedTest driven development inverts the usual order most developers are accustomed to, by first writing a failing test that clearly describes the exact expected behavior of a piece of functionality that does not yet exist at all, then writing just enough actual implementation code to make that specific failing test pass, and finally refactoring that implementation to improve its internal quality while continuously confirming the test still passes throughout, and proponents argue this disciplined workflow naturally results in more thoroughly tested code, more focused and minimal implementations, and a design that is inherently easier to test from the very beginning, since testability is considered from the very first step rather than added on afterward.
// Step 1: Write a failing test
public function testCalculatesShippingCost(): void
{
$this->assertEquals(5.99, (new ShippingCalculator())->calculate(2.5));
}
// Step 2: Write minimal code to make it pass
// Step 3: Refactor while keeping the test passing
Real-world example
A developer building a new shipping cost calculation feature writes a failing test describing the exact expected cost for a given package weight before writing any actual implementation code at all, then implements just enough logic to make that test pass.
Functions & Scope;Design Patterns in PHP