Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

fcno's avatar
Level 6

PestPHP/PHPUnit/PHP 8.1 and Memory Leaks

How do you deal with memory leak problem in Pest framework.

I tried to solve it by setting process isolation to true, but Pest still doesn't support it.

I tried other alternatives described in this post

https://darkghosthunter.medium.com/laravel-fixing-memory-leaks-on-tests-4fe87b87f0ad

but it ended up not working.

What solved it for me was the thing I least wanted to do which is to increase the memory available for testing.

Tests are currently limited to 128MB. I increased it to 2GB and now its working (without memory leaks), but that doesn't feel right to me.

0 likes
12 replies
sr57's avatar

Have you dump/log the memory usage at the end of each test (to be sure it's a leak and not a mistake in a (test) code?

fcno's avatar
Level 6

Yes.

It starts around 60Mb and grows with each test until it bursts when it reaches 128Mb.

sr57's avatar

@fcno

!

I don't use a lot unit tests to have noticed this, does another reader get the same pb?

fcno's avatar
Level 6

Sorry, not sure what do u mean.

But if u are talking about any reader, Yes. If I read big files, like big log files, I have the same problem if I read all at once. So, in this case, I read line by line.

sr57's avatar

@fcno

Communication is always a difficult art.

By reader, I mean "human user/reader of this forum", it should be good to know if it's a general pb of laravel/test or a pb linked to a config/platform?

salla's avatar

@fcno facing the same issue (processIsolation does not work with Pest), did you later find a fix for this ?

fcno's avatar
Level 6

@salla No man ... sorry. I increased the memory. Rn w8ing for a trully fix.

Sinnbeck's avatar

Are you sure the issue is pest specific? I was just working on fixing the same issue with phpunit on a non laravel project. Then I stumbled upon this https://bugs.php.net/bug.php?id=79519 Check the comment by brent at "2021-12-09 12:20"

fcno's avatar
Level 6

@Sinnbeck Looks like its probably not Pest issue... but not sure if its PHPUnit xor PHP issue :(

I updated the title.

PropaySystems's avatar

Hi seems like im running into a memory issue myself and everything i tried doesnt work.

Crash report

  ✓ can confirm user1 cannot access user2's user personal info with (Closure Object (...)) / (Closure Object (...))

Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 1052672 bytes) in /home/vagrant/projects/snp-portal-solidarity/vendor/chelout/laravel-relationship-events/src/Traits/HasRelationshipObservables.php on line 56

   Whoops\Exception\ErrorException 

  Allowed memory size of 536870912 bytes exhausted (tried to allocate 1052672 bytes)

  at vendor/chelout/laravel-relationship-events/src/Traits/HasRelationshipObservables.php:56
     52▕      * @return void
     53▕      */
     54▕     public static function mergeRelationshipObservables(array $relationshipObservables)
     55▕     {
  ➜  56▕         static::$relationshipObservables = array_merge(static::$relationshipObservables, $relationshipObservables);
     57▕     }
     58▕ 
     59▕     /**
     60▕      * Get the observable event names.

      +1 vendor frames 
  2   [internal]:0
      Whoops\Run::handleShutdown()

In HasRelationshipObservables.php line 56:

Pest.php file

uses(
    Tests\TestCase::class,
    LazilyRefreshDatabase::class,
    MorphMapper::class,
    PermissionTrait::class,
)->in('Feature', 'Unit');

uses()
    ->afterAll(function () {
        gc_collect_cycles();
        \Illuminate\Container\Container::setInstance();

        app()->flush();
    })
    ->afterEach(function () {



        $memory_size = memory_get_usage();
        $memory_unit = array('Bytes','KB','MB','GB','TB','PB');
        // Display memory size into kb, mb etc.
        echo 'Used Memory : '.round($memory_size/pow(1024,($x=floor(log($memory_size,1024)))),2).' '.$memory_unit[$x]."\n";
    })
    ->beforeEach(function () {
    $this->seed(PermissionSeeder::class);
    $this->seed(RoleSeeder::class);
})->in(
    'Feature/Articles',
    'Feature/Dashboard',
    'Feature/Company',
    'Unit/Company',
    'Feature/UserProfile',
    'Feature/Member',
    'Feature/SettingsPage',
    'Feature/JobSeeker',
    'Feature/Group',
    'Feature/StudyHelpInstitution',
    'Feature/IndustrialPsychologist',
    'Feature/Youth',
    'Unit/DatePicker',
    'Unit/Actions',
    'Unit/CompanyAvatar',
    'Unit/UserProfilePublicComps',
);

/*
|--------------------------------------------------------------------------
| Expectations
|--------------------------------------------------------------------------
|
| When you're writing tests, you often need to check that values meet certain conditions. The
| "expect()" function gives you access to a set of "expectations" methods that you can use
| to assert different things. Of course, you may extend the Expectation API at any time.
|
*/

expect()->extend('toBeRedirectedFor', function (string $url, string $method = 'get') {
    if (! $this->value) {
        $response = test()->{$method}($url);
    } else {
        $response = actingAs($this->value)->{$method}($url);
    }

    return $response->assertStatus(302);
});

expect()->extend('isLessThanOrEqualTo', function (int $limit) {
    return $this->value->count() <= $limit;
});

/*
|--------------------------------------------------------------------------
| Functions
|--------------------------------------------------------------------------
|
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
| project that you don't want to repeat in every file. Here you can also expose helpers as
| global functions to help you to reduce the number of lines of code in your test files.
|
*/

/**
 * @param  Authenticatable  $user
 * @return TestCase
 */
function actingAs(Authenticatable $user): TestCase
{
    return test()->actingAs($user);
}

/**
 * @return Expectation
 */
function expectGuest(): Expectation
{
    return test()->expect(null);
}

Please or to participate in this conversation.