From a4f03c402ab2f3e2d66d7f231183f8a329f0544a Mon Sep 17 00:00:00 2001 From: Tom Mrazauskas Date: Mon, 23 May 2022 12:54:41 +0300 Subject: [PATCH] docs: add execution order documentation for `after*` hooks (#12865) --- docs/SetupAndTeardown.md | 92 ++++++++++++++----- .../version-27.x/SetupAndTeardown.md | 92 ++++++++++++++----- .../version-28.0/SetupAndTeardown.md | 92 ++++++++++++++----- .../version-28.1/SetupAndTeardown.md | 92 ++++++++++++++----- 4 files changed, 280 insertions(+), 88 deletions(-) diff --git a/docs/SetupAndTeardown.md b/docs/SetupAndTeardown.md index 131376d0de6f..d835a46c82e0 100644 --- a/docs/SetupAndTeardown.md +++ b/docs/SetupAndTeardown.md @@ -5,9 +5,9 @@ title: Setup and Teardown Often while writing tests you have some setup work that needs to happen before tests run, and you have some finishing work that needs to happen after tests run. Jest provides helper functions to handle this. -## Repeating Setup For Many Tests +## Repeating Setup -If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach`. +If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach` hooks. For example, let's say that several tests interact with a database of cities. You have a method `initializeCityDatabase()` that must be called before each of these tests, and a method `clearCityDatabase()` that must be called after each of these tests. You can do this with: @@ -39,9 +39,9 @@ beforeEach(() => { ## One-Time Setup -In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` to handle this situation. +In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` hooks to handle this situation. -For example, if both `initializeCityDatabase` and `clearCityDatabase` returned promises, and the city database could be reused between tests, we could change our test code to: +For example, if both `initializeCityDatabase()` and `clearCityDatabase()` returned promises, and the city database could be reused between tests, we could change our test code to: ```js beforeAll(() => { @@ -104,12 +104,15 @@ beforeAll(() => console.log('1 - beforeAll')); afterAll(() => console.log('1 - afterAll')); beforeEach(() => console.log('1 - beforeEach')); afterEach(() => console.log('1 - afterEach')); + test('', () => console.log('1 - test')); + describe('Scoped / Nested block', () => { beforeAll(() => console.log('2 - beforeAll')); afterAll(() => console.log('2 - afterAll')); beforeEach(() => console.log('2 - beforeEach')); afterEach(() => console.log('2 - afterEach')); + test('', () => console.log('2 - test')); }); @@ -127,37 +130,30 @@ describe('Scoped / Nested block', () => { // 1 - afterAll ``` -## Order of execution of describe and test blocks +## Order of Execution -Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the describe blocks. Once the describe blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. +Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the `describe` blocks. Once the `describe` blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. Consider the following illustrative test file and output: ```js -describe('outer', () => { +describe('describe outer', () => { console.log('describe outer-a'); describe('describe inner 1', () => { console.log('describe inner 1'); - test('test 1', () => { - console.log('test for describe inner 1'); - expect(true).toEqual(true); - }); + + test('test 1', () => console.log('test 1')); }); console.log('describe outer-b'); - test('test 1', () => { - console.log('test for describe outer'); - expect(true).toEqual(true); - }); + test('test 2', () => console.log('test 2')); describe('describe inner 2', () => { console.log('describe inner 2'); - test('test for describe inner 2', () => { - console.log('test for describe inner 2'); - expect(false).toEqual(false); - }); + + test('test 3', () => console.log('test 3')); }); console.log('describe outer-c'); @@ -168,11 +164,63 @@ describe('outer', () => { // describe outer-b // describe inner 2 // describe outer-c -// test for describe inner 1 -// test for describe outer -// test for describe inner 2 +// test 1 +// test 2 +// test 3 ``` +Just like the `describe` and `test` blocks Jest calls the `before*` and `after*` hooks in the order of declaration. Note that the `after*` hooks of the enclosing scope are called first. For example, here is how you can set up and tear down resources which depend on each other: + +```js +beforeEach(() => console.log('connection setup')); +beforeEach(() => console.log('database setup')); + +afterEach(() => console.log('database teardown')); +afterEach(() => console.log('connection teardown')); + +test('test 1', () => console.log('test 1')); + +describe('extra', () => { + beforeEach(() => console.log('extra database setup')); + afterEach(() => console.log('extra database teardown')); + + test('test 2', () => console.log('test 2')); +}); + +// connection setup +// database setup +// test 1 +// database teardown +// connection teardown + +// connection setup +// database setup +// extra database setup +// test 2 +// extra database teardown +// database teardown +// connection teardown +``` + +:::note + +If you are using `jasmine2` test runner, take into account that it calls the `after*` hooks in the reverse order of declaration. To have identical output, the above example should be altered like this: + +```diff + beforeEach(() => console.log('connection setup')); ++ afterEach(() => console.log('connection teardown')); + + beforeEach(() => console.log('database setup')); ++ afterEach(() => console.log('database teardown')); + +- afterEach(() => console.log('database teardown')); +- afterEach(() => console.log('connection teardown')); + + // ... +``` + +::: + ## General Advice If a test is failing, one of the first things to check should be whether the test is failing when it's the only test that runs. To run only one test with Jest, temporarily change that `test` command to a `test.only`: diff --git a/website/versioned_docs/version-27.x/SetupAndTeardown.md b/website/versioned_docs/version-27.x/SetupAndTeardown.md index 131376d0de6f..d835a46c82e0 100644 --- a/website/versioned_docs/version-27.x/SetupAndTeardown.md +++ b/website/versioned_docs/version-27.x/SetupAndTeardown.md @@ -5,9 +5,9 @@ title: Setup and Teardown Often while writing tests you have some setup work that needs to happen before tests run, and you have some finishing work that needs to happen after tests run. Jest provides helper functions to handle this. -## Repeating Setup For Many Tests +## Repeating Setup -If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach`. +If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach` hooks. For example, let's say that several tests interact with a database of cities. You have a method `initializeCityDatabase()` that must be called before each of these tests, and a method `clearCityDatabase()` that must be called after each of these tests. You can do this with: @@ -39,9 +39,9 @@ beforeEach(() => { ## One-Time Setup -In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` to handle this situation. +In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` hooks to handle this situation. -For example, if both `initializeCityDatabase` and `clearCityDatabase` returned promises, and the city database could be reused between tests, we could change our test code to: +For example, if both `initializeCityDatabase()` and `clearCityDatabase()` returned promises, and the city database could be reused between tests, we could change our test code to: ```js beforeAll(() => { @@ -104,12 +104,15 @@ beforeAll(() => console.log('1 - beforeAll')); afterAll(() => console.log('1 - afterAll')); beforeEach(() => console.log('1 - beforeEach')); afterEach(() => console.log('1 - afterEach')); + test('', () => console.log('1 - test')); + describe('Scoped / Nested block', () => { beforeAll(() => console.log('2 - beforeAll')); afterAll(() => console.log('2 - afterAll')); beforeEach(() => console.log('2 - beforeEach')); afterEach(() => console.log('2 - afterEach')); + test('', () => console.log('2 - test')); }); @@ -127,37 +130,30 @@ describe('Scoped / Nested block', () => { // 1 - afterAll ``` -## Order of execution of describe and test blocks +## Order of Execution -Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the describe blocks. Once the describe blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. +Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the `describe` blocks. Once the `describe` blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. Consider the following illustrative test file and output: ```js -describe('outer', () => { +describe('describe outer', () => { console.log('describe outer-a'); describe('describe inner 1', () => { console.log('describe inner 1'); - test('test 1', () => { - console.log('test for describe inner 1'); - expect(true).toEqual(true); - }); + + test('test 1', () => console.log('test 1')); }); console.log('describe outer-b'); - test('test 1', () => { - console.log('test for describe outer'); - expect(true).toEqual(true); - }); + test('test 2', () => console.log('test 2')); describe('describe inner 2', () => { console.log('describe inner 2'); - test('test for describe inner 2', () => { - console.log('test for describe inner 2'); - expect(false).toEqual(false); - }); + + test('test 3', () => console.log('test 3')); }); console.log('describe outer-c'); @@ -168,11 +164,63 @@ describe('outer', () => { // describe outer-b // describe inner 2 // describe outer-c -// test for describe inner 1 -// test for describe outer -// test for describe inner 2 +// test 1 +// test 2 +// test 3 ``` +Just like the `describe` and `test` blocks Jest calls the `before*` and `after*` hooks in the order of declaration. Note that the `after*` hooks of the enclosing scope are called first. For example, here is how you can set up and tear down resources which depend on each other: + +```js +beforeEach(() => console.log('connection setup')); +beforeEach(() => console.log('database setup')); + +afterEach(() => console.log('database teardown')); +afterEach(() => console.log('connection teardown')); + +test('test 1', () => console.log('test 1')); + +describe('extra', () => { + beforeEach(() => console.log('extra database setup')); + afterEach(() => console.log('extra database teardown')); + + test('test 2', () => console.log('test 2')); +}); + +// connection setup +// database setup +// test 1 +// database teardown +// connection teardown + +// connection setup +// database setup +// extra database setup +// test 2 +// extra database teardown +// database teardown +// connection teardown +``` + +:::note + +If you are using `jasmine2` test runner, take into account that it calls the `after*` hooks in the reverse order of declaration. To have identical output, the above example should be altered like this: + +```diff + beforeEach(() => console.log('connection setup')); ++ afterEach(() => console.log('connection teardown')); + + beforeEach(() => console.log('database setup')); ++ afterEach(() => console.log('database teardown')); + +- afterEach(() => console.log('database teardown')); +- afterEach(() => console.log('connection teardown')); + + // ... +``` + +::: + ## General Advice If a test is failing, one of the first things to check should be whether the test is failing when it's the only test that runs. To run only one test with Jest, temporarily change that `test` command to a `test.only`: diff --git a/website/versioned_docs/version-28.0/SetupAndTeardown.md b/website/versioned_docs/version-28.0/SetupAndTeardown.md index 131376d0de6f..d835a46c82e0 100644 --- a/website/versioned_docs/version-28.0/SetupAndTeardown.md +++ b/website/versioned_docs/version-28.0/SetupAndTeardown.md @@ -5,9 +5,9 @@ title: Setup and Teardown Often while writing tests you have some setup work that needs to happen before tests run, and you have some finishing work that needs to happen after tests run. Jest provides helper functions to handle this. -## Repeating Setup For Many Tests +## Repeating Setup -If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach`. +If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach` hooks. For example, let's say that several tests interact with a database of cities. You have a method `initializeCityDatabase()` that must be called before each of these tests, and a method `clearCityDatabase()` that must be called after each of these tests. You can do this with: @@ -39,9 +39,9 @@ beforeEach(() => { ## One-Time Setup -In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` to handle this situation. +In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` hooks to handle this situation. -For example, if both `initializeCityDatabase` and `clearCityDatabase` returned promises, and the city database could be reused between tests, we could change our test code to: +For example, if both `initializeCityDatabase()` and `clearCityDatabase()` returned promises, and the city database could be reused between tests, we could change our test code to: ```js beforeAll(() => { @@ -104,12 +104,15 @@ beforeAll(() => console.log('1 - beforeAll')); afterAll(() => console.log('1 - afterAll')); beforeEach(() => console.log('1 - beforeEach')); afterEach(() => console.log('1 - afterEach')); + test('', () => console.log('1 - test')); + describe('Scoped / Nested block', () => { beforeAll(() => console.log('2 - beforeAll')); afterAll(() => console.log('2 - afterAll')); beforeEach(() => console.log('2 - beforeEach')); afterEach(() => console.log('2 - afterEach')); + test('', () => console.log('2 - test')); }); @@ -127,37 +130,30 @@ describe('Scoped / Nested block', () => { // 1 - afterAll ``` -## Order of execution of describe and test blocks +## Order of Execution -Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the describe blocks. Once the describe blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. +Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the `describe` blocks. Once the `describe` blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. Consider the following illustrative test file and output: ```js -describe('outer', () => { +describe('describe outer', () => { console.log('describe outer-a'); describe('describe inner 1', () => { console.log('describe inner 1'); - test('test 1', () => { - console.log('test for describe inner 1'); - expect(true).toEqual(true); - }); + + test('test 1', () => console.log('test 1')); }); console.log('describe outer-b'); - test('test 1', () => { - console.log('test for describe outer'); - expect(true).toEqual(true); - }); + test('test 2', () => console.log('test 2')); describe('describe inner 2', () => { console.log('describe inner 2'); - test('test for describe inner 2', () => { - console.log('test for describe inner 2'); - expect(false).toEqual(false); - }); + + test('test 3', () => console.log('test 3')); }); console.log('describe outer-c'); @@ -168,11 +164,63 @@ describe('outer', () => { // describe outer-b // describe inner 2 // describe outer-c -// test for describe inner 1 -// test for describe outer -// test for describe inner 2 +// test 1 +// test 2 +// test 3 ``` +Just like the `describe` and `test` blocks Jest calls the `before*` and `after*` hooks in the order of declaration. Note that the `after*` hooks of the enclosing scope are called first. For example, here is how you can set up and tear down resources which depend on each other: + +```js +beforeEach(() => console.log('connection setup')); +beforeEach(() => console.log('database setup')); + +afterEach(() => console.log('database teardown')); +afterEach(() => console.log('connection teardown')); + +test('test 1', () => console.log('test 1')); + +describe('extra', () => { + beforeEach(() => console.log('extra database setup')); + afterEach(() => console.log('extra database teardown')); + + test('test 2', () => console.log('test 2')); +}); + +// connection setup +// database setup +// test 1 +// database teardown +// connection teardown + +// connection setup +// database setup +// extra database setup +// test 2 +// extra database teardown +// database teardown +// connection teardown +``` + +:::note + +If you are using `jasmine2` test runner, take into account that it calls the `after*` hooks in the reverse order of declaration. To have identical output, the above example should be altered like this: + +```diff + beforeEach(() => console.log('connection setup')); ++ afterEach(() => console.log('connection teardown')); + + beforeEach(() => console.log('database setup')); ++ afterEach(() => console.log('database teardown')); + +- afterEach(() => console.log('database teardown')); +- afterEach(() => console.log('connection teardown')); + + // ... +``` + +::: + ## General Advice If a test is failing, one of the first things to check should be whether the test is failing when it's the only test that runs. To run only one test with Jest, temporarily change that `test` command to a `test.only`: diff --git a/website/versioned_docs/version-28.1/SetupAndTeardown.md b/website/versioned_docs/version-28.1/SetupAndTeardown.md index 131376d0de6f..d835a46c82e0 100644 --- a/website/versioned_docs/version-28.1/SetupAndTeardown.md +++ b/website/versioned_docs/version-28.1/SetupAndTeardown.md @@ -5,9 +5,9 @@ title: Setup and Teardown Often while writing tests you have some setup work that needs to happen before tests run, and you have some finishing work that needs to happen after tests run. Jest provides helper functions to handle this. -## Repeating Setup For Many Tests +## Repeating Setup -If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach`. +If you have some work you need to do repeatedly for many tests, you can use `beforeEach` and `afterEach` hooks. For example, let's say that several tests interact with a database of cities. You have a method `initializeCityDatabase()` that must be called before each of these tests, and a method `clearCityDatabase()` that must be called after each of these tests. You can do this with: @@ -39,9 +39,9 @@ beforeEach(() => { ## One-Time Setup -In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` to handle this situation. +In some cases, you only need to do setup once, at the beginning of a file. This can be especially bothersome when the setup is asynchronous, so you can't do it inline. Jest provides `beforeAll` and `afterAll` hooks to handle this situation. -For example, if both `initializeCityDatabase` and `clearCityDatabase` returned promises, and the city database could be reused between tests, we could change our test code to: +For example, if both `initializeCityDatabase()` and `clearCityDatabase()` returned promises, and the city database could be reused between tests, we could change our test code to: ```js beforeAll(() => { @@ -104,12 +104,15 @@ beforeAll(() => console.log('1 - beforeAll')); afterAll(() => console.log('1 - afterAll')); beforeEach(() => console.log('1 - beforeEach')); afterEach(() => console.log('1 - afterEach')); + test('', () => console.log('1 - test')); + describe('Scoped / Nested block', () => { beforeAll(() => console.log('2 - beforeAll')); afterAll(() => console.log('2 - afterAll')); beforeEach(() => console.log('2 - beforeEach')); afterEach(() => console.log('2 - afterEach')); + test('', () => console.log('2 - test')); }); @@ -127,37 +130,30 @@ describe('Scoped / Nested block', () => { // 1 - afterAll ``` -## Order of execution of describe and test blocks +## Order of Execution -Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the describe blocks. Once the describe blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. +Jest executes all describe handlers in a test file _before_ it executes any of the actual tests. This is another reason to do setup and teardown inside `before*` and `after*` handlers rather than inside the `describe` blocks. Once the `describe` blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on. Consider the following illustrative test file and output: ```js -describe('outer', () => { +describe('describe outer', () => { console.log('describe outer-a'); describe('describe inner 1', () => { console.log('describe inner 1'); - test('test 1', () => { - console.log('test for describe inner 1'); - expect(true).toEqual(true); - }); + + test('test 1', () => console.log('test 1')); }); console.log('describe outer-b'); - test('test 1', () => { - console.log('test for describe outer'); - expect(true).toEqual(true); - }); + test('test 2', () => console.log('test 2')); describe('describe inner 2', () => { console.log('describe inner 2'); - test('test for describe inner 2', () => { - console.log('test for describe inner 2'); - expect(false).toEqual(false); - }); + + test('test 3', () => console.log('test 3')); }); console.log('describe outer-c'); @@ -168,11 +164,63 @@ describe('outer', () => { // describe outer-b // describe inner 2 // describe outer-c -// test for describe inner 1 -// test for describe outer -// test for describe inner 2 +// test 1 +// test 2 +// test 3 ``` +Just like the `describe` and `test` blocks Jest calls the `before*` and `after*` hooks in the order of declaration. Note that the `after*` hooks of the enclosing scope are called first. For example, here is how you can set up and tear down resources which depend on each other: + +```js +beforeEach(() => console.log('connection setup')); +beforeEach(() => console.log('database setup')); + +afterEach(() => console.log('database teardown')); +afterEach(() => console.log('connection teardown')); + +test('test 1', () => console.log('test 1')); + +describe('extra', () => { + beforeEach(() => console.log('extra database setup')); + afterEach(() => console.log('extra database teardown')); + + test('test 2', () => console.log('test 2')); +}); + +// connection setup +// database setup +// test 1 +// database teardown +// connection teardown + +// connection setup +// database setup +// extra database setup +// test 2 +// extra database teardown +// database teardown +// connection teardown +``` + +:::note + +If you are using `jasmine2` test runner, take into account that it calls the `after*` hooks in the reverse order of declaration. To have identical output, the above example should be altered like this: + +```diff + beforeEach(() => console.log('connection setup')); ++ afterEach(() => console.log('connection teardown')); + + beforeEach(() => console.log('database setup')); ++ afterEach(() => console.log('database teardown')); + +- afterEach(() => console.log('database teardown')); +- afterEach(() => console.log('connection teardown')); + + // ... +``` + +::: + ## General Advice If a test is failing, one of the first things to check should be whether the test is failing when it's the only test that runs. To run only one test with Jest, temporarily change that `test` command to a `test.only`: