Use phpunit to test your PHP project

Mar 17, 2024 by Thibault Debatty | 1482 views

PHP GitLab

https://cylab.be/blog/329/use-phpunit-to-test-your-php-project

So you are developing some PHP code? Beter make sure it works as expected! In this blog post we will show how to quickly get started with phpunit to automatically test your code…

software-testing.jpg

For the examples below, we assume that:

  1. you are using composer to manage your dependencies and
  2. your code is located in the src directory.

Installation

Installing phpunit is done easily with

composer require --dev phpunit/phpunit

A first test

Now let’s create a simple test…

First, create a directory to store all your tests:

mkdir tests

Now create the file tests/ExampleTest.php with the following content:

<?php

use PHPUnit\Framework\TestCase;

class ExampleTest extends TestCase
{
    public function testTrueIsTrue(): void
    {
        $this->assertTrue(true);
    }
}

You can now run your test with

./vendor/bin/phpunit tests
```

![phpunit.png](/storage/blog/329/files/XS6xNvq9Sn1tOgYw/phpunit.png)

See that (for now) you must at least provide the directory as argument...

## Assertions

In the example above we use the assertion `assertTrue`. Phpunit provides **a lot** of other useful assertions, for example:

* `assertEquals`
* `assertSame` : test if parameters have same value **and type**. So `assertSame(123, "123")` will fail;
* `assertTrue`
* `assertFalse`
* `assertNull`
*  `assertInstanceOf` 
* `assertContains` : test if an array contains a value
* `assertArrayHasKey`

You can find the complete list in the documentation of PHPUnit:

https://docs.phpunit.de/en/11.0/assertions.html

## Configuration file

PHPUnit has a lot of options and configuration parameters. To define these, it's easier to create a configuration file **phpunit.xml**:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"

  backupGlobals="false" 
  backupStaticAttributes="false" 
  colors="true" 
  convertErrorsToExceptions="true" 
  convertNoticesToExceptions="true" 
  convertWarningsToExceptions="true" 
  processIsolation="false" 
  stopOnFailure="false">

  <!-- where test code is located -->
  <testsuites>
    <testsuite name="Unit">
      <directory suffix="Test.php">./tests</directory>
    </testsuite>
  </testsuites>

  <!-- to compute code coverage -->
  <coverage processUncoveredFiles="true">
    <include>
      <directory suffix=".php">./src</directory>
    </include>
  </coverage>

  <!-- if needed, define additional env variables -->
  <php>
    <env name="APP_ENV" value="testing"/>
  </php>
</phpunit>
```

See that, for example, the directory containing the tests is defined in the configuration file. So now you can run phpunit wihout specifying the tests directory:

```bash
./vendor/bin/phpunit
```

## Code coverage

PHPUnit can also compute the coverage of your code. This requires to install `xdebug`:

```bash
sudo apt install php-xdebug php-mbstring php-xml 
```

`xdebug` has multiple working modes. To enable code coverage, you must add the line `xdebug.mode=coverage` to your PHP configuration. In my case I'm using PHP 8.3, so here is how to do it on the command line:

```bash
echo "xdebug.mode=coverage" | sudo tee -a /etc/php/8.3/cli/conf.d/20-xdebug.ini 
```

You can now run PHPUnit and compute code coverage with

```bash
./vendor/bin/phpunit --coverage-text
```

![phpunit-coverage.png](/storage/blog/329/files/za5JX3Efcx3WVbz2/phpunit-coverage.png)

## GitLab

Finally, if you are using GitLab to manage your code, you can run PHPUnit automatically by adding the following block to your **.gitlab-ci.yml**:

```yaml
test:php8.1:
  image: cylab/php:8.1
  before_script:
    - COMPOSER_CACHE_DIR=composer-cache composer install
  script:
    - vendor/bin/phpunit --coverage-text
```

This blog post is licensed under CC BY-SA 4.0

This website uses cookies. More information about the use of cookies is available in the cookies policy.
Accept