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();
  356357if (! $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 Speaker

CyberWiseCon 2025

In May 2025, I'll be presenting Digital Cat-and-Mouse: Strategies to Outsmart Scrapers, Phishers, and Thieves at CyberWiseCon 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!


Share This Article

Related Articles


More