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 2025 Speaker

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!


Share This Article

Related Articles


Lazy loading background images to improve load time performance

Lazy loading of images helps to radically speed up initial page load. Rich site designs often call for background images, which can't be lazily loaded in the same way. How can we keep our designs, while optimising for a fast initial load?

Using Google Sheets as a RESTful JSON API

Save time by not building backends for simple CRUD apps. Use Google Sheets as both a free backend and JSON API endpoint!

Serverless caching and proxying with Cloudflare Workers

Using Cloudflare Workers we can quickly build an effective API proxy, without spinning up any additional hardware. Whether its needing a CORS proxy, speeding up slow APIs via caching, or rate limit management on stingy APIs, this serverless tech is as easy to set up as it is powerful.

Idempotency - what is it, and how can it help our Laravel APIs?

Idempotency is a critical concept to be aware of when building robust APIs, and is baked into the SDKs of companies like Stripe, Paypal, Shopify, and Amazon. But what exactly is idempotency? And how can we easily add support for it to our Laravel APIs?

Calculating rolling averages with Laravel Collections

Rolling averages are perfect for smoothing out time-series data, helping you to gain insight from noisy graphs and tables. This new package adds first-class support to Laravel Collections for rolling average calculation.

More