php-testing-en-php-con-phpunit-y-pest

Testing in PHP with PHPUnit and Pest

  • 3 min

An automated test is code that executes a part of the application and checks that it produces the expected result.

So far, your “testing” method has probably been:

Write code.

Go to the browser.

Press F5.

Manually test if the form works.

This is called Manual Testing and it has a problem: it’s slow and prone to human error. If you change something on the Login page, do you remember to re-test the Registration to see if it broke? Probably not.

Automated Testing is about writing code that tests your code. You run a command and within 1 second, 500 functions of your website are checked. If something fails, a red light comes on.

What is a “unit test”?

It is the most basic test. It consists of isolating a small piece of code (usually a function or method of a class) and checking that:

  • Given an input X (Input).
  • An output Y (Output) is obtained.

We follow the AAA pattern:

  1. Arrange: Prepare the data.
  2. Act: Execute the function.
  3. Assert: Check if the result is the expected one.

The standard tool: PHPUnit

PHPUnit is the industry standard. Almost all frameworks (Laravel, Symfony) use it under the hood. It is installed via Composer (composer require --dev phpunit/phpunit).

Imagine you have this simple class:

src/Calculadora.php

class Calculadora {
    public function sumar($a, $b) {
        return $a + $b;
    }
}
Copied!

This is how you write its test in PHPUnit:

tests/CalculadoraTest.php

use PHPUnit\Framework\TestCase;

class CalculadoraTest extends TestCase {
    
    // Tests must start with the word "test"
    public function testSumaCorrectamente() {
        // 1. ARRANGE
        $calc = new Calculadora();
        
        // 2. ACT
        $resultado = $calc->sumar(2, 3);
        
        // 3. ASSERT (The key part)
        // We say: "I expect $resultado to be equal to 5"
        $this->assertEquals(5, $resultado);
    }
}
Copied!

When you run the test in the console, you will see a GREEN bar (Passed). If you change the sum function to subtract, you will see a RED bar (Failed) and you will know that you broke something.

The modern alternative: Pest

Pest is a newer tool that is becoming very popular, especially in the Laravel ecosystem. Pest runs on top of PHPUnit, but with a much cleaner syntax closer to human language.

The same test as before, written in Pest:

test('the calculator can add two numbers', function () {
    $calc = new Calculadora();
    
    // Fluent syntax: "Expect that sumar(2,3) is 5"
    expect($calc->sumar(2, 3))->toBe(5);
});
Copied!

Why should you start testing?

  1. You sleep soundly: If all your tests are green before deploying to production, you know you haven’t broken anything critical.
  2. Living documentation: A test perfectly explains what your code does and how it is used.
  3. Refactoring without fear: You can clean up and improve your old code. If you break something, the test will warn you immediately.