How to test procedural functions with PHPUnit
Published on 2021-03-30. Modified on 2021-03-31.
Some people argue that you cannot test procedural PHP code, but that is not true. In this small tutorial I am going to show you how you can use PHPUnit to test your procedural functions.
Take a look at the documentation for relevant information about how to use PHPUnit.
All official releases of code distributed by the PHPUnit Project are signed by the release manager for the release. PGP signatures and SHA256 hashes are available for verification on phar.phpunit.de
In this simple example I am going to use the phar version of PHPUnit.
We start by downloading phpunit.phar
as well as its detached PGP signature phpunit.phar.asc
:
$ wget https://phar.phpunit.de/phpunit-9.5.phar $ wget https://phar.phpunit.de/phpunit-9.5.phar.asc
In order to proceed with the verification we need to retrieve the release manager's public key from a key server:
$ curl --silent https://sebastian-bergmann.de/gpg.asc | gpg --import
Then we verify the signature:
$ gpg phpunit-9.5.phar.asc gpg: WARNING: no command supplied. Trying to guess what you mean ... gpg: assuming signed data in 'phpunit-9.5.phar' gpg: Signature made tir 23 mar 2021 08:16:55 CET gpg: using RSA key D8406D0D82947747293778314AA394086372C20A gpg: issuer "sb@sebastian-bergmann.de" gpg: Good signature from "Sebastian Bergmann" [unknown] gpg: aka "Sebastian Bergmann " [unknown] gpg: aka "Sebastian Bergmann " [unknown] gpg: aka "Sebastian Bergmann " [unknown] gpg: aka "Sebastian Bergmann " [unknown] gpg: aka "[jpeg image of size 40635]" [unknown] gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: D840 6D0D 8294 7747 2937 7831 4AA3 9408 6372 C20A
The signature is good and a good signature means that the file has not been tampered with. However, due to the nature of public key cryptography, you need to additionally verify that the primary key fingerprint was created by the real Sebastian Bergmann. I am going to leave that up to you to figure out :)
Then we make the script executable:
$ chmod +x phpunit-9.5.phar $ ./phpunit-9.5.phar --version PHPUnit x.y.z by Sebastian Bergmann and contributors
Now we're ready to do some testing.
Let's create a single file in our public directory and put a couple of functions into it:
$ vim public/foo.php <?php declare(strict_types=1); function bar(string $string): string { return $string; } function add(int $a, int $b): int { return $a + $b; }
Then we create a test file for foo.php
:
$ vim test_foo.php <?php declare(strict_types=1); use PHPUnit\Framework\TestCase; // We require the file we need to test. require 'public/foo.php'; final class test_foo extends TestCase { public function test_bar() { $this->assertEquals('Hello', bar('Hello')); $this->assertEquals('Hi', bar('Hi')); } public function test_add() { $this->assertEquals(4, add(1, 3)); $this->assertEquals(10, add(4, 6)); } }
Make sure that the class name you use match the actual filename of the test file.
The run the test:
$ ./phpunit-9.5.phar --colors test_foo.php PHPUnit 9.5.4 by Sebastian Bergmann and contributors. .. 2 / 2 (100%) Time: 00:00.020, Memory: 18.00 MB OK (2 tests, 4 assertions)
Let's make the test fail by changing the assertion test for the add
function. Change it to something that is wrong:
$this->assertEquals(15, add(4, 6));
This should fail because 4 + 6 is not 15:
$ ./phpunit-9.5.phar --colors test_foo.php PHPUnit 9.5.4 by Sebastian Bergmann and contributors. .F 2 / 2 (100%) Time: 00:00.019, Memory: 18.00 MB There was 1 failure: 1) test_foo::test_add Failed asserting that 10 matches expected 15. test_foo.php:15 FAILURES! Tests: 2, Assertions: 4, Failures: 1.
That's pretty much it. Take a look at the documentation for relevant information about other kinds of tests.