Skip to the content
Documentation
Help Start
Reading in:
  • German: 9,059 of 9,059 pages
About the help in other languages
All help pages

Testing: PHPUnit, database tests and checks

How to test an application on Exponential for developers used to WebTestCase, Laravel's HTTP tests, Django's test client or Rails system tests - PHPUnit without a database for services, tests against a throwaway…

Download as PDF

Address: https://doc.exponential.earth/learninminutes/exphelp/viewer/help/web-framework-developers/testing.md

On this page

Testing: PHPUnit, database tests and checks

This page is for developers who test with a framework's test kit: Symfony's WebTestCase, Laravel's HTTP tests and factories, Django's test client and fixtures, Rails system tests. Exponential's tests are plain PHPUnit. The kernel runs most of its suites without a database, a few against a throwaway one, and adds checks for templates, settings and links. Do the same in your extension (Testing applications).

Contents

  1. The layers
  2. Unit tests without a database
  3. Tests with a database
  4. Templates, settings and pages
  5. The kernel's CI as a model
  6. What has no built-in equivalent

The layers

LayerToolCatches
Syntaxphp -l, bin/php/eztemplatecheck.phpparse errors in PHP and templates
UnitPHPUnit, no databaselogic of services, validators, handlers, operators
IntegrationPHPUnit with tests/runtests.php --dsn ...SQL, persistent objects, content operations
Rendered pagesHTTP requests, browser automationtemplates, permissions, redirects
Accessibility and CSPan accessibility checker, the CSP report logbarriers, inline code

Unit tests without a database

phpunit.xml loads tests/bootstrap.php, which loads Composer's autoloader and the test toolkit but does not boot the kernel (DB-less PHPUnit tests):

<?php
// extension/expdemo/tests/expDemoColorValidatorTest.php
class expDemoColorValidatorTest extends PHPUnit\Framework\TestCase
{
    public function testAcceptsHexColors()
    {
        $this->assertTrue( expDemoColorValidator::isValid( '#a1b2c3' ) );
    }
}
vendor/bin/phpunit extension/expdemo/tests/

This works when the logic lives in plain classes with their dependencies passed in (Dependency injection and services). Keep database access out of those classes or behind an interface you can replace in the test.

Tests with a database

tests/runtests.php --dsn <dsn> --db-per-test runs suites against a throwaway database, as the kernel's CI job does on MySQL and PostgreSQL. Mark such tests @group database; vendor/bin/phpunit alone excludes that group. Never point tests at a database that holds real content (PHPUnit in the testing standard).

The test toolkit in tests/toolkit/ has the base classes ezpTestCase and ezpDatabaseTestCase, and ezpINIHelper::setINISetting() / restoreINISettings() to change a setting for one test.

There are no model factories: create the content your test needs with eZContentFunctions::createAndPublishObject() and remote IDs, and your own rows with eZPersistentObject::store().

Templates, settings and pages

php bin/php/eztemplatecheck.php -s<siteaccess> extension/expdemo/design/   # every template of your extension
./console exp:ini where expdemo.ini/ListSettings/DefaultLimit <siteaccess>  # settings resolve as expected

For pages, send HTTP requests to a running installation (PHP's built-in server through Velocity's php engine, or a test host) as anonymous, as a restricted user and as an editor. Use a dedicated test user created for the run, never a shared administrator account. Check the browser console and var/log/csp.log for blocked inline code.

The kernel's CI as a model

The kernel's phpunit.xml has 23 suites; GitHub Actions run them on PHP 8.1 to 8.5 without a database and on MySQL and PostgreSQL with one, plus syntax, PHPStan, code style and a PHP 8.0 boot test. tests/test-map.json maps source files to their tests, so a change runs only its own tests before a push (Testing and CI standard, Continuous integration for extensions).

What has no built-in equivalent

Framework featureIn Exponential
A kernel test client that handles a request in-process (WebTestCase, $this->get(), Django Client)none; test services directly and pages over HTTP
Model factories, fixtures loaderscontent API calls and .dba seed rows
Transaction rollback per test--db-per-test with a throwaway database
Mail fakesthe file mail transport in a test environment variant (Environments)

Become an Exponential Partner

Partners share their information, provide funding, contribute back and develop the products with us, and that is how Exponential grows. A partner website and dashboard are planned for mid-2027: please become a partner today to speed up our growth rate and land new features faster.

Something wrong on this page? Report an error

Documentation license

This documentation is free documentation, licensed under the GNU Free Documentation License 1.3 or later.

Exponential Copyright © 1998-2026 Exponential Foundation and 7x