pest: Using factories in beforeAll/afterAll hook throws InvalidArgumentException
Hey,
Reproducible with clean project:
laravel new pest-beforeAll
composer require pestphp/pest --dev --with-all-dependencies
composer require pestphp/pest-plugin-laravel --dev
php artisan pest:install
Refactor the default ExampleTest.php
to Pest and try to create User
factory in beforeAll
/afterAll
hook:
<?php
use App\Models\User;
use function Pest\Laravel\be;
use function Pest\Laravel\get;
beforeAll(function(){
be(User::factory()->create());
});
test('basic test', function(){
get('/')->assertStatus(200);
});
Run php artisan test
and it will fail with:

When using beforeEach
instead of beforeAll
the tests pass. ✨
Sorry that this didn’t come with a pull request - haven’t tinkered with reflection that deep and I bet given that it’s reproducible someone from the core contributors will have easier time fixing this. Alternatively if someone could provide some pointers as to what might be the cause I can take a look and try to figure it out. 🤓
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 2
- Comments: 18 (7 by maintainers)
A very strange solution, making the use of Pest very questionable. How do I set up group of tests?
@ilyavaiser I agree with you, as I am having the same issue. I need to test a table sorting, and for each test case, I need to seed my DB again and again with the same data, which influences the performance of the test. In fact, it should be done only once.
@nunomaduro it doesn’t mention there the fact that the framework hasn’t booted and you can only run basic code. Would be a nice touch for new adopters who don’t know/haven’t used PHPUnit and jump right in to PestPHP. 🚀
I second the request. I’m starting using Pest too since yesterday and it take me a while to understand that the class isn’t instantiated during beforeAll() which i find it odd, so i thought i was doing something wrong.
So i think that beforeAl() should be instantiated after the class is initialized, it should be a good gain on performance time if we have to load the fixtures once for the class instead of each test.
Edit: im using Symfony and not Laravel
This is a known “issue”,
beforeAll
/afterAll
are called before (or after) the class has been instantiated (they are the equivalents of@beforeClass
and@afterClass
in PHPUnit). So the framework hasn’t been booted at that point. 👍🏻 In the meantime you need to usebeforeEach
/afterEach
. See https://github.com/pestphp/pest/issues/237 and https://github.com/pestphp/pest/issues/33#issuecomment-658022624. 🙂 I think that Nuno was thinking about a possible way of resolving this though. 🤔It’s not really an issue, just a lot of people seem to get confused with
beforeAll()
/beforeEach()
not working like howsetUp()
andtearDown()
work.I guess this is resolved now via: https://pestphp.com/docs/pest-spicy-summer-release#content-describe-blocks. 👏🏼
@nunomaduro it’s obvious from the previous comments and likes that a lot of devs want to be able to access framework functionalities, e.g factories, artisan commands, etc once before the whole test runs and hence access to the application’s booted state. Is there a way out to do this without having to repeat executions in the
beforeEach
hook?I must admit that even I didn’t know about the
@beforeClass
restrictions because I hadn’t used them in Laravel. 😄That note seems Laravel specific.