Hooks
Pest hooks are similar to the steps you might take when preparing a meal: first, you gather and prepare the ingredients, then you cook the meal, and finally, you clean up after yourself. In the same way, hooks allow you to perform specific actions before and after each test or file, such as setting up test data, initializing the test environment, or cleaning up resources once the tests are complete.
By using hooks in Pest, you may streamline your testing process and automate repetitive tasks. Whether you are writing unit tests for a small project or building a complex test suite for a large application, hooks help you save time and improve the quality of your tests.
Sometimes you may wish to run a hook only for a specific group of tests. To accomplish this, you may place the hook within a describe() function:
1beforeEach(function () { 2 // 3}); 4 5describe('something', function () { 6 beforeEach(function () { 7 // 8 }); 9 10 //11 12 describe('something else', function () {13 beforeEach(function () {14 //15 });16 17 //18 });19});20 21test('something', function () {22 //23});
Here is a list of the hooks available in Pest:
beforeEach()
The beforeEach() hook executes the provided closure before every test within the current file, ensuring that any necessary setup or configuration is completed before each test:
1beforeEach(function () {2 // Prepare something before each test run...3});
When using the beforeEach() hook, you may initialize properties that will be shared across all tests within the current file. For example, you may use beforeEach() to initialize the $userRepository property before each test runs, ensuring that it is available for the subsequent tests in the file:
1beforeEach(function () {2 $this->userRepository = new UserRepository();3});4 5it('may be created', function () {6 $user = $this->userRepository->create();7 8 expect($user)->toBeInstanceOf(User::class);9});
afterEach()
The afterEach() hook executes the provided closure after every test within the current file, allowing you to clean up any resources or state that may have been modified during testing:
1afterEach(function () {2 // Clear testing data after each test run...3});
Continuing the example above, if the beforeEach() hook is used to initialize the $userRepository property, the afterEach() hook may be used to "clean" it after each test when necessary. This ensures that any resources the object may be using are released or reset between tests, preventing any interference or unwanted behavior:
1afterEach(function () {2 $this->userRepository->reset();3});
Optionally, you may use the after() method to perform clean-up tasks after a specific test. This is helpful when you need to clean up resources that are specific to a single test, rather than shared across all tests in the file:
1it('may be created', function () {2 $this->userRepository->create();3 4 expect($user)->toBeInstanceOf(User::class);5})->after(function () {6 $this->userRepository->reset();7});
beforeAll()
The beforeAll() hook executes the provided closure once before any tests are run within the current file, allowing you to perform any necessary setup or initialization that applies to all tests:
1beforeAll(function () {2 // Prepare something once before any of this file's tests run...3});
It is important to note that, unlike the beforeEach() hook, the $this variable is not available in the beforeAll() hook. This is because the hook runs before any tests are executed, so there is no instance of the test class or object to which the variable could refer.
afterAll()
The afterAll() hook executes the provided closure once after all tests have completed within the current file, allowing you to perform any necessary clean-up or tear-down tasks:
1afterAll(function () {2 // Clean testing data after all tests run...3});
As with the beforeAll() hook, the $this variable is not available in the afterAll() hook. This is because the afterAll() hook runs after all tests in the file have completed, so there is no longer a test instance or object to which the variable could refer.
Once you have mastered using hooks to set up preconditions and clean-up actions for your tests, we are ready to discuss "Datasets", which allow you to run the same test with different inputs or parameters. Datasets let you thoroughly test your code under a variety of conditions and edge cases, helping you identify and fix bugs that may not be immediately obvious: Datasets →