Test Hooks | Bondar Academy
Course: Playwright API Testing with TypeScript
Module: API Testing Basics
Instructor: Artem Bondar
Lesson Summary
In this lesson, we explore test hooks , a feature in testing frameworks that allows you to run specific operations before or after tests. There are four main types of test hooks: BeforeAllHook : Executes code before all tests in a test file. BeforeEachHook : Runs code before each individual test, useful for setting up preconditions. AfterEachHook : Performs cleanup after each test. AfterAllHook : Executes code after all tests have completed. The lesson demonstrates how to optimize tests using these hooks. Initially, the Playwright configuration is updated to include a list reporter alongside the existing HTML reporter for better visualization of test execution. Key points covered include: Setting up hooks at the top of the test file. Using console.log to demonstrate when hooks are executed in relation to tests. Understanding the implications of using after hooks and best practices for avoiding flaky tests. It is advised to use before hooks for setup and avoid relying on after hooks for cleanup to prevent test failures due to incomplete operations. Additionally, the lesson illustrates how to refactor code by moving repeated operations, such as creating a token, into a before all hook to enhance code efficiency and maintainability. This way, the token can be shared across tests without redundancy. In conclusion, test hooks are a powerful tool for optimizing test code and improving test execution flow.
Video Transcript
In this lesson, we're gonna talk about test hooks. So what is test hooks? Test hooks is a type of operation in the framework where you can repeat a certain operation before the test or after the test. So there are four types of the webhooks. BeforeAllHook is used when you want to run some code before all tests inside of your test file. BeforeEachHook is useful when you need to run some code for every test to create some test precondition, for example. AfterEachHook is some teardown after every test. And AfterAllHook is something that you want to execute after all tests within test file are executed. So in this lesson, we will use hooks to optimize our current tests a little bit, and I will show you how to use them, all right? So let's get into it. Okay, so far, we have four tests created in our spec file. And first of all, let me demonstrate how the test hooks works in action. For better demonstration, first of all, I want to update my reporter in Playwright configuration file. I go over here and looking for reporter. So far, we have just HTML reporter. I want to add a second reporter, which called list reporter, to print out the test execution in the terminal when we run them one by one. So you have a better visualization of the test order. So how to add this? I wrap the current HTML reporter in the array, and then add a second array with single value of list reporter. And all those two values, I need to wrap in another array. So don't ask me why configuration is made like that, it is what it is, okay? So that's the configuration that have to be done. Now, let's run all the tests and see how it works. So here on the left, go to Test Explorer. We have all our test example spec file and all our tests right here. So click on this little arrow to run all four tests so far. One, two, three, four, and all tests were executed within two seconds, 2.5 seconds. How about that? And the list reporter is this one. So it's printed all the tests, the name of the file, the line in the test file, and the name of the test that was executed, and duration for each of the test. So pretty convenient view when you need to run a big number of tests, and you will see which are pass, which are fail. Now, let me show you how to use a hooks. So here in the top of the test files, usually hooks are placed in the top of the test file. And let's say, for example, we create before all hook test, before all. So I type test.before, you see, I have two options, before all and before each. So for example, before all, and give some meaningful description. Run before all, something like this. Then async, then if we need, we can put arguments. So far, we will not put any of those, and new test function, okay? And I will create a similar one, but I will call it after all. This is the hook after all hook, and run after all. Okay, now within those hooks, I will put something, okay. A little misspell here, after all. Okay, I will put something to print out to the console, so you can see how it works in relation to the test. So console.log, this is executed before all tests. And copy here, copy here. It's after all test, okay? And now look, when I run those tests right now inside of our spec file, test execution, and look, this is executed before all tests. So before all of our tests executed, this hook was run, okay? And after all test, finally, was this hook executed, after all test is executed. So don't look that this line is printed right here before the reporter, because reporter is the last thing that is executed, okay? So first of all, we run the test, then we run after hook, and then reporter prints the result of execution. But if I change this to before each, or after each. And I will change the text, after each, after each, and run it again. Now you can see this is repetitive operation. So before and after every test, we have two texts printed. And if I will change it to before all, but we'll keep only after each and run it again. Then we see that before all hook was executed, and then only after each hooks were executed. So this is how it works, and you can put into here whatever code you want to be executed before all your tests, before each of your tests, or after all or after each. One note, it's considered not a good practice, actually, in testing to use after each or after all hooks. Why? Because it can be a reason of flaking. For example, if you put here some code that is responsible, let's say, for cleaning up database. So if the after each hook fails during the test execution, and then you try to rerun your test again, then your test will fail. Because the after each hook was not able to successfully clean up the data. What is considered a best practice is put everything what you need to create your setup environment, your test environment into before each or before all hook, and instead of step in after each hook to, let's say, clean your database, you should put this step into before each hook with check if database is ready for the test, something like this. Or check if the database is cleaned up before the test run. So that way, you will see that something happened before the test execution and that environment was not configured well, rather than the actual test failure itself, okay? So let's talk about only before hooks, and in our example, how we can use it. So here in our test, so create and delete article, we had this step, create the token. And we repeated this operation in the next step, create, update, and delete article. So this is exactly the same process of creating the token. And instead of repeating this operation and technically copy pasting the code from test to test, we can put this into the hook. And the before all hook works for us. And just use the values generated by this step inside of the test. So here we need to add a request fixture inside of before all. But we have a little problem here. So ALF token constant is not visible for other tests. So everything what you put into the before all or before each is kind of isolated from other tests. And we need to make this constant somehow visible for other tests to be able to use. So what we can do is instead of creating the constant inside of the test, we can create a variable, ALF token, outside of the test of type string, like this. And then we assign the result of the execution of this token to this variable. And now since this variable is outside of the test, now it is visible by other tests. Now we can go back and just simply delete those steps from the test. Create and delete article and remove this step, create, update and delete article as well. So this ALF token variable becomes visible from the higher test level by before all hook. So before all hook will be executed before all test. The value for ALF token will be created before all test. And then we execute four of our test. And they will use this value whenever they need during the test execution. So I believe the refactoring is done. We remove that. So let's run the test and see if it is working. One, two, three, four perfect tests were executed successfully. All right, so that's how test hooks works. Pretty useful and convenient way to optimize the code. And I remind you that before all hook is executed before all test just once. And before each hook can be used to repeat certain operation before every single test. This helps to optimize your test and test flow a little bit. All right, see you in the next lesson.