Introduction to testing with PHPUnit - Part 1

No image preview
Tutorials /
PHP Programming/

#php


Better test than sorry.

 

 

 

If you like to code I am sure you will want to write a couple of tests and learn something new if you have never before tested your code. We will use the popular PHPUnit framework for testing PHP applications.
 


First, we will install the necessary dependencies and set up a simple class that we will test on, and after that, we will demonstrate some configurations that can make your testing easier.

 

 

 

Installation

 

 

 

To install PHPUnit we use the composer and run the following commands in the terminal to install the PHPUnit framework and to check the framework version and $PATH. You can see that now in the ./root there is composer.json and composer.lock file and vendor folder.

 

 

 

composer require --dev phpunit/phpunit

./vendor/bin/phpunit --version

which ./vendor/bin/phpunit

 

 

 

Project structure

 

 

 

PHPUnits supports a test suite approach, which basically means it allows you to organize tests to be tested all at once or to be selected or excluded by suite or class.

For this, we need an organized folder structure, so we will keep all our tests in the ./tests/run folder and our application files will be in the ./src folder.


 

root/
    -src/
    -tests/
        -run/
    -vendor
    composer.json
    composer.lock

 



Now, why is this important? Because we will use this structure to explain to PHPUnit where to look for tests, when the framework looks in the /tests/run folder it will run every test that has the proper name and annotation. We will explain those things later.

In the ./src folder create your file with the class Article on which we will perform tests.

 

 

<?php


namespace App\Model;


class Article {

    protected $title;
    protected $category;
    protected $price;

 
    public function __construct($title, $category, $price)
    {
        $this->title = $title;
        $this->category = $category;
        $this->price = $price;
    }

   
    public function getTitle():string 
    {
        return $this->title;
    }


    public function getCategory(): string 
    {
        return $this->category;
    }


    public function getPrice(): float 
    {
        return $this->price;
    }


}


 

 

Now we need to register our namespace in composers autoload so its import would be resolved across the application. We can do that within the composer.json file.
Do not forget to refresh autoload with the composer dump command in the terminal after changing composer.json.

 

 

 

{
    "autoload": {
        "psr-4": {
            "App\\Model\\": "src/"
        }
    },
    "require-dev": {
        "phpunit/phpunit": "^10.0"
    }
}




Configure PHPUnit

 

First, we need to create a bootstrap.php file in the tests folder that will bootstrap all our dependencies to PHPUnit framework.

 

 

 

<?php

require __DIR__ . '/../vendor/autoload.php';

?>

 

 

 

And then we can create and define the phpunit.xml file in the root folder, this is our configuration file for the PHPUnit framework, here we will define the test suite and bootstrap dependencies provided with the bootstrap.php file. 



 

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/|version|/phpunit.xsd"
         bootstrap="./tests/bootstrap.php">
    <testsuites>
        <testsuite name="unit">
            <directory>tests/run</directory>
        </testsuite>
    </testsuites>
</phpunit>




Create the first test
 

 

 

Notice that there is a naming convention here, when naming a test class we should use the pattern ClassName+Test(ArticleTest), and when naming methods of test class we should add "test" as the prefix for every method. This ensures that PHPUnit can easily find your tests.


 

<?php
use PHPUnit\Framework\TestCase;

use App\Model\Article;

class  ArticleTest extends TestCase{

    function testgetName()
    {    
        $this->assertSame("Apple", (new Article("Apple", "Fruit", 2.99))->getTitle());
    }


    function testgetCategory()
    {
        $this->assertSame("Fruit", (new Article("Apple", "Fruit", 2.99))->getCategory());
    }


    function testgetPrice()
    {
        $this->assertSame(2.99, (new Article("Apple", "Fruit", 2.99))->getPrice());
    }
    
}




Now, run your first test in the console.



 

./vendor/bin/phpunit

 

PHPUnit 10.0.7 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.2.2
Configuration: /home/luka/DevGround/ftest/phpunit.xml

...                                                                 3 / 3 (100%)

Time: 00:00.049, Memory: 6.00 MB

OK (3 tests, 3 assertions)




We just run three successful tests, where we tested with the assertion that the data provided will be the same as data retrieved from Article methods.


If you want to learn more about testing with PHPUnit, like other types of assertions, what are test suits, annotations, and data providers please check PHPUnit Testing - Part 2.

[root@techtoapes]$ whoami
[root@techtoapes]$ Author Luka

Login to comment.