Use phpunit to test your PHP project

Mar 17, 2024 by Thibault Debatty | 813 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

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 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:

./vendor/bin/phpunit

Code coverage

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

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:

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

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

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:

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

Fully customizable emails using Laravel 9
With the release of Laravel 9, the Swift Mailer (that is no longer maintained) has been replaced by the Symfony Mailer. You can already find some useful information about this change along all the other ones in the Upgrade Guide from Laravel 8.x to 9.0. However this guide does not contain enough information if you want to send fully customized emails. This blog post proposes you a solution coming directly from the Symfony documentation!
SQL injection with SQLMap
Code injection is one of the most critical web application vulnerabilities. Indeed, the consequences of code injection can be dramatic (impact). Moreover, still today a lot of web applications are vulnerable to code injection (frequency). Finally, some tools like SQLMap allow to automatically detect and use these vulnerabilities (exploitation). For this reason, the vulnerability is listed in the top 10 published by the Open Web Application Security Project (OWASP) [1]. In this blog post, we will present one type of code injection, called SQL injection, and we will show how to perform a SQL injection attack with SQLMap.
Filter USB devices with udev (and some PHP code)
USB devices can be a liability : they can be used to exfiltrate data from a computer or server, to plug a hardware keylogger, or to plant a malware. Hence on a managed computer, USB devices should be filtered and whitelisted. In this blog post we show how this can be achieved thanks to udev, and some PHP code.