Fixing 'A Facade Root Has Not Been Set' when testing Laravel with Pest
When developing with Laravel, Pest is the modern choice for testing. It's expressive, clean, builds on the PHPUnit framework, and as of Laravel 11 is the default setting for new Laravel applications. However, when you're first starting out, you might run into some configuration issues. One common error is the A facade root has not been set
error. This error typically indicates a bootstrap issue with Laravel - the framework has not been loaded correctly by Pest into your tests. Fortunately the fix is fairly simple!
The short answer is to ensure that all high-level directories containing tests are specified in your tests/Pest.php
file:
pest()->extend(Tests\TestCase::class)
->use(Illuminate\Foundation\Testing\RefreshDatabase::class)
->in('Feature', 'Unit'); <-- all test suites listed here!
For a more detailed explanation, let's break down the error and how to fix it.
Test Setup
Pest builds on top of PHPUnit, allowing it to use a lot of the same functionality. When you create a new Laravel application, you'll find a phpunit.xml
file in the root directory, containing baseline configuration for all test runs. In it, the <testsuites>
tag is used to define the different test suites you want to run. For example, you might have a "Unit" suite for unit tests and a "Feature" suite for feature tests. PHPUnit uses this to decide which tests to run when you specify a suite, e.g, php artisan test --testsuite=Unit
.
<testsuites>
<testsuite name="Unit">
<directory>tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>tests/Feature</directory>
</testsuite>
</testsuites>
The configuration of these test suites is important because it tells PHPUnit which directories to look in for tests. Within the tests/Pest.php
file, there is also a base configuration, which will look something like this:
pest()->extend(Tests\TestCase::class)
->use(Illuminate\Foundation\Testing\RefreshDatabase::class)
->in('Feature');
This block of code is doing a couple of things:
- allowing Pest to use the core
TestCase
class from Laravel (boot the framework) - using the RefreshDatabase trait (fresh database after each test)
- applying this to all tests in the "Feature" test suite
The first point above is effectively bootstrapping the framework, allowing us to use Laravel functionality inside our tests. The A facade root has not been set
error is essentially saying that the Laravel framework hasn't been bootstrapped yet by Pest, so we can't use Laravel functionality. In this case, the problem comes from a mismatch between our phpunit.xml and the Pest bootstrapping.
In the phpunit.xml, we've defined two test suites: "Unit" and "Feature". The "Unit" suite is not being used in the Pest bootstrapping, so Laravel isn't being bootstrapped for these tests. This is why the facade root has not been set
error appears when you run the tests in the "Unit" suite.
To ensure everything works correctly, the test directories in tests/Pest.php
must match the <directory>
entries in phpunit.xml
. If you define a test suite in phpunit.xml
(e.g, Unit
) but forget to include it in tests/Pest.php
, Laravel won't bootstrap the framework for tests in that directory.
We can test this with a simple test under the Unit
folder, validating something simple like factories setting up models ok:
# tests/Unit/Models/ArticleTest.php
<?php
use App\Models\Article;
use App\Models\Author;
it('creates an article successfully', function () {
$article = Article::factory()->create();
expect($article)->toBeInstanceOf(Article::class)
->and($article->author)->toBeInstanceOf(Author::class);
});
When we run php artisan test
, we get a failure:
FAIL Tests\Unit\Models\ArticleTest
⨯ it creates a catalogue item successfully
────────────────────────────────────────────────────
FAILED Tests\Unit\Models\ArticleTest > it creates a catalogue item successfully RuntimeException
A facade root has not been set.
at vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:358
354▕ {
355▕ $instance = static::getFacadeRoot();
356▕
357▕ if (! $instance) {
➜ 358▕ throw new RuntimeException('A facade root has not been set.');
Fixing the Facade Root Error in Pest
To fix the error, we need to ensure that all directories containing tests are specified in the tests/Pest.php
file. This will ensure that Laravel is bootstrapped for all tests, not just those in the "Feature" directory. We can do this by adding the "Unit" directory to the in()
method:
pest()->extend(Tests\TestCase::class)
->use(Illuminate\Foundation\Testing\RefreshDatabase::class)
->in('Feature', 'Unit'); <-- all test suites listed here!
Once that change has been made, if we re-run php artisan test
, the Unit tests now have access to the framework, and the test passes:
PASS Tests\Unit\Models\ArticleTest
✓ it creates an article successfully 0.17s
Tests: 1 passed (2 assertions)
Duration: 0.27s
CyberWiseCon 2025
In May 2025, I'll be giving a talk at CyberWiseCon 2025 in Vilnius, Lithuania. From selling 10 Downing St, to moving the Eiffel Tower to Dublin, this talk covers real-world examples of unconventional ways to stop scrapers, phishers, and content thieves. You'll gain practical insights to protect assets, outsmart bad actors, and avoid the mistakes we made along the way!
Get your ticket now and I'll see you there!