Writing Tests for PHPUnit (Exceptions and Errors)
Introduction
#Testing Exceptions
PHPUnit has a nice way of testing exceptions, using the exceptException() method. The example below illustrates the use of the exceptException() method to test for an exception against a code under test.
<?php
use PHPUnit\Framework\TestCase;
class ExceptionTest extends TestCase
{
public function testException()
{
$this->expectException(InvalidArgumentException::class);
}
}
?>
When the test for an exception runs, output as shown below is seen
$ phpunit ExceptionTest
PHPUnit |version|.0 by Sebastian Bergmann and contributors.
F
Time: 0 seconds, Memory: 4.75Mb
There was 1 failure:
1) ExceptionTest::testException
Failed asserting that exception of type "InvalidArgumentException" is thrown.
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
There are other exception methods available for use in when writing PHPUnit tests aside the expectException() method, some of these methods are the expectExceptionCode() method, expectExceptionMessage() method, and expectExceptionMessageRegExp() method. These methods are used to set up expectations for exceptions raised by the code under test.
It should be noted that expectExceptionMessage() method asserts that the $actual message contains the $expected message. It doesn’t perform an exact string comparison.
Alternatively, we can also use the @expectedException(), @expectedExceptionCode(), @expectedExceptionMessage(), and @expectedExceptionMessageRegExp() annotations to set up expectations for exceptions raised by the code under test. The example below illustrates the use of some of these methods.
Example Using the @expectedException annotation
<?php
use PHPUnit\Framework\TestCase;
class ExceptionTest extends TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
}
}
?>
When the test using the @expectedException annotation runs, the following output is generated.
$ phpunit ExceptionTest
PHPUnit |version|.0 by Sebastian Bergmann and contributors.
F
Time: 0 seconds, Memory: 4.75Mb
There was 1 failure:
1) ExceptionTest::testException
Failed asserting that exception of type "InvalidArgumentException" is thrown.
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
#Testing PHP Errors
By default, PHPUnit converts PHP errors, warnings, and notices that are triggered during the execution of a test to an exception. Using these exceptions, we can, for instance, expect a test to trigger a PHP error.
We should note that PHP’s error_reporting runtime configuration can limit which errors PHPUnit will convert to exceptions.
When testing for errors, ensure that the error you are testing for isn’t suppressed by the settings in the PHP error configuration.
The example below illustrates the testing for PHP errors using @expectedException annotation.
<?php
use PHPUnit\Framework\TestCase;
class ExpectedErrorTest extends TestCase
{
/**
* @expectedException PHPUnit\Framework\Error\Error
*/
public function testFailingInclude()
{
include 'not_existing_file.php';
}
}
?>
When the above test executes, the output below is seen
$ phpunit -d error_reporting=2 ExpectedErrorTest
PHPUnit |version|.0 by Sebastian Bergmann and contributors.
.
Time: 0 seconds, Memory: 5.25Mb
OK (1 test, 1 assertion)
PHPUnit\Framework\Error\Notice and PHPUnit\Framework\Error\Warning represent PHP notices and warnings, respectively.
We should note that tests for exceptions should be as specific as possible. Testing for classes that are too generic might lead to undesirable side-effects.
Also testing the Exception class with the @expectedException annotation and expectedException method is no longer permitted.
Some tests that relies on PHP functions to trigger errors like fopen it may sometimes be useful to use error suppression in such tests. This allows us to check the return values by suppressing notices that could lead to a PHPUnit PHPUnit\Framework\Error\Notice.
The example below illustrates a test for return values of codes that uses PHP Errors.
<?php
use PHPUnit\Framework\TestCase;
class ErrorSuppressionTest extends TestCase
{
public function testFileWriting()
{
$writer = new FileWriter;
$this->assertFalse(@$writer->write('/is-not-writeable/file', 'stuff'));
}
}
class FileWriter
{
public function write($file, $content)
{
$file = fopen($file, 'w');
if ($file == false) {
return false;
}
// ...
}
}
?>
The out of the test above is shown below
$ phpunit ErrorSuppressionTest
PHPUnit |version|.0 by Sebastian Bergmann and contributors.
.
Time: 1 seconds, Memory: 5.25Mb
OK (1 test, 1 assertion)
If error suppression was not used in the above test, the test would fail reporting fopen(/is-not-writeable/file): failed to open stream: No such file or directory.
Previous:
Writing tests for phpunit (outputs)
Next:
The command-line test runner (1)
PHP: Tips of the Day
PHP: Correct file permissions for WordPress
When you setup WP you (the webserver) may need write access to the files. So the access rights may need to be loose.
chown www-data:www-data -R * # Let Apache be owner find . -type d -exec chmod 755 {} \; # Change directory permissions rwxr-xr-x find . -type f -exec chmod 644 {} \; # Change file permissions rw-r--r-
After the setup you should tighten the access rights, according to Hardening WordPress all files except for wp-content should be writable by your user account only. wp-content must be writable by www-data too.
chown <username>:<username> -R * # Let your useraccount be owner chown www-data:www-data wp-content # Let apache be owner of wp-content
Maybe you want to change the contents in wp-content later on. In this case you could
- temporarily change to the user to www-data with su,
- give wp-content group write access 775 and join the group www-data or
- give your user the access rights to the folder using ACLs.
Whatever you do, make sure the files have rw permissions for www-data.
Ref : https://bit.ly/3hcrTkL
- Weekly Trends
- Python Interview Questions and Answers: Comprehensive Guide
- Scala Exercises, Practice, Solution
- Kotlin Exercises practice with solution
- MongoDB Exercises, Practice, Solution
- SQL Exercises, Practice, Solution - JOINS
- Java Basic Programming Exercises
- SQL Subqueries
- Adventureworks Database Exercises
- C# Sharp Basic Exercises
- SQL COUNT() with distinct
- JavaScript String Exercises
- JavaScript HTML Form Validation
- Java Collection Exercises
- SQL COUNT() function
- SQL Inner Join
We are closing our Disqus commenting system for some maintenanace issues. You may write to us at reach[at]yahoo[dot]com or visit us at Facebook