README-Isolated-Testing.md
OpenEMR includes an isolated testing setup that allows you to run PHPUnit tests without database or service dependencies.
The default OpenEMR test bootstrap loads interface/globals.php, which:
library/sql.inc.phpsqlconf.phpThis prevents running simple unit tests without a full OpenEMR environment.
New code written to fully follow SOLID design principles, and in particular (D)ependency Inversion, can be tested in complete isolation using mocks and stubs.
The isolated test suite bypasses the main test suite's bootstrap process, and provides only the Composer autoloader.
Key files:
phpunit-isolated.xml — PHPUnit configuration for isolated teststests/Tests/Isolated/ — Directory for dependency-free testssqlconf.php$GLOBALS)vendor/bin/phpunit -c phpunit-isolated.xml
vendor/bin/phpunit -c phpunit-isolated.xml --testsuite isolated
vendor/bin/phpunit -c phpunit-isolated.xml --testsuite unit-isolated
vendor/bin/phpunit -c phpunit-isolated.xml tests/Tests/Isolated/ExampleIsolatedTest.php
tests/Tests/Isolated/ directory, mirroring the src/ structure
src/Validators/ classes → tests/Tests/Isolated/Validators/src/Services/ classes → tests/Tests/Isolated/Services/src/Common/ classes → tests/Tests/Isolated/Common/OpenEMR\Tests\Isolated\{Module}PHPUnit\Framework\TestCasetests/Tests/Isolated/
├── Validators/
│ ├── AllergyIntoleranceValidatorTest.php
│ └── ConditionValidatorTest.php
├── Services/
│ └── SomeServiceTest.php
└── Common/
└── UtilsTest.php
<?php
namespace OpenEMR\Tests\Isolated\Services;
use OpenEMR\Services\SomeService;
use OpenEMR\Repositories\SomeRepositoryInterface;
use PHPUnit\Framework\TestCase;
class SomeServiceTest extends TestCase
{
public function testProcessReturnsTransformedData(): void
{
// Create mock for the repository dependency
$repository = $this->createMock(SomeRepositoryInterface::class);
$repository->expects($this->once())
->method('findById')
->with(123)
->willReturn(['id' => 123, 'name' => 'Test']);
// Inject mocked dependencies
$service = new SomeService($repository);
// Test the behavior
$result = $service->process(123);
$this->assertEquals('Test', $result->getName());
}
}