We use cookies to enhance your experience on the site
CodeWorlds

Setup and Teardown

In Jurassic Park, before every enclosure inspection you need to prepare equipment, and after the inspection you need to clean up. It is exactly the same with tests - setup and teardown functions allow you to prepare and clean up the test environment.

beforeEach - Before Every Test

beforeEach
runs before each test in a
describe
block. It is the ideal place for creating fresh test data.

1describe('DinosaurEnclosure', () => {
2  let enclosure;
3  let rex;
4
5  beforeEach(() => {
6    // Before each test we create a new enclosure and dinosaur
7    enclosure = createEnclosure('Zone A', 5);
8    rex = createDinosaur('Rex', 'T-Rex', 'carnivore');
9  });
10
11  it('should add dinosaur to enclosure', () => {
12    enclosure.add(rex);
13    expect(enclosure.dinosaurs).toHaveLength(1);
14    expect(enclosure.dinosaurs[0].name).toBe('Rex');
15  });
16
17  it('should start with empty enclosure', () => {
18    // Thanks to beforeEach, enclosure is always fresh!
19    expect(enclosure.dinosaurs).toHaveLength(0);
20  });
21
22  it('should track capacity', () => {
23    enclosure.add(rex);
24    expect(enclosure.remainingCapacity()).toBe(4);
25  });
26});

afterEach - After Every Test

afterEach
runs after each test. It serves to clean up after tests - closing connections, resetting state.

1describe('SecuritySystem', () => {
2  let securitySystem;
3  let alarmLog;
4
5  beforeEach(() => {
6    securitySystem = new SecuritySystem();
7    alarmLog = [];
8    securitySystem.onAlarm((msg) => alarmLog.push(msg));
9  });
10
11  afterEach(() => {
12    // Reset the security system after each test
13    securitySystem.deactivate();
14    alarmLog = [];
15    console.log('System reset after test');
16  });
17
18  it('should detect breach', () => {
19    securitySystem.simulateBreach('Zone A');
20    expect(alarmLog).toContain('Breach in Zone A');
21  });
22
23  it('should handle multiple alarms', () => {
24    securitySystem.simulateBreach('Zone A');
25    securitySystem.simulateBreach('Zone B');
26    expect(alarmLog).toHaveLength(2);
27  });
28});

beforeAll and afterAll - Once for the Entire Group

beforeAll
runs once before all tests in a
describe
, and
afterAll
once after all. Use them for expensive operations.

1describe('DatabaseTests', () => {
2  let database;
3
4  beforeAll(async () => {
5    // Expensive operation - database connection, only once!
6    database = await connectToDatabase();
7    console.log('Database connected');
8  });
9
10  afterAll(async () => {
11    // Close connection after all tests
12    await database.close();
13    console.log('Database disconnected');
14  });
15
16  beforeEach(async () => {
17    // Clear data before each test
18    await database.clear();
19  });
20
21  it('should save dinosaur', async () => {
22    await database.save({ name: 'Rex', species: 'T-Rex' });
23    const dinos = await database.findAll();
24    expect(dinos).toHaveLength(1);
25  });
26
27  it('should find by species', async () => {
28    await database.save({ name: 'Rex', species: 'T-Rex' });
29    await database.save({ name: 'Blue', species: 'Velociraptor' });
30
31    const raptors = await database.findBySpecies('Velociraptor');
32    expect(raptors).toHaveLength(1);
33    expect(raptors[0].name).toBe('Blue');
34  });
35});

Execution Order

It is important to understand the order in which Jest executes setup and teardown:

1describe('Execution order', () => {
2  beforeAll(() => console.log('1. beforeAll'));
3  afterAll(() => console.log('6. afterAll'));
4  beforeEach(() => console.log('2. beforeEach'));
5  afterEach(() => console.log('4. afterEach'));
6
7  it('test 1', () => console.log('3. test 1'));
8  it('test 2', () => console.log('3. test 2'));
9});
10
11// Output:
12// 1. beforeAll
13// 2. beforeEach
14// 3. test 1
15// 4. afterEach
16// 2. beforeEach
17// 3. test 2
18// 4. afterEach
19// 6. afterAll

Nested describe

Setup and teardown work hierarchically in nested

describe
blocks:

1describe('Jurassic Park', () => {
2  beforeEach(() => console.log('Setup: Park'));
3
4  describe('Predator Zone', () => {
5    beforeEach(() => console.log('Setup: Predator Zone'));
6
7    it('T-Rex is in the enclosure', () => {
8      console.log('Test: T-Rex');
9      // Setup order: Park -> Predator Zone
10    });
11  });
12
13  describe('Herbivore Zone', () => {
14    beforeEach(() => console.log('Setup: Herbivore Zone'));
15
16    it('Triceratops is in the enclosure', () => {
17      console.log('Test: Triceratops');
18      // Setup order: Park -> Herbivore Zone
19    });
20  });
21});

Nested

describe
blocks inherit setup from parent blocks.
beforeEach
from the parent runs before the child's
beforeEach
.

Go to CodeWorlds