bun icon indicating copy to clipboard operation
bun copied to clipboard

Execution order of nested tests is counter intuitive

Open vinnichase opened this issue 1 year ago • 1 comments

What version of Bun is running?

1.1.4+fbe2fe0c3

What platform is your computer?

Darwin 23.3.0 arm64 arm

What steps can reproduce the bug?

create test file test.spec.ts in bun project

import { describe, it, expect } from 'bun:test';

describe('A', () => {
    it('a', async () => {
        expect(true).toBe(true);
    });
    it('b', async () => {
        expect(true).toBe(true);
    });
    describe('1', () => {
        it('a', async () => {
            expect(true).toBe(true);
        });
        it('b', async () => {
            expect(true).toBe(true);
        });
    });
    describe('2', () => {
        describe('1', () => {
            it('a', async () => {
                expect(true).toBe(true);
            });
            it('b', async () => {
                expect(true).toBe(true);
            });
        });
        describe('2', () => {
            it('a', async () => {
                expect(true).toBe(true);
            });
            it('b', async () => {
                expect(true).toBe(true);
            });
            it('c', async () => {
                expect(true).toBe(true);
            });
        });
        describe('3', () => {
            it('a', async () => {
                expect(true).toBe(true);
            });
            it('b', async () => {
                expect(true).toBe(true);
            });
            it('c', async () => {
                expect(true).toBe(true);
            });
        });
    });
    describe('3', () => {
        it('a', async () => {
            expect(true).toBe(true);
        });
        it('b', async () => {
            expect(true).toBe(true);
        });
    });
});

run

$ bun test

What is the expected behavior?

I expect the test execution with outer describe blocks being executed first.

...
test.spec.ts:
✓ A > a [0.01ms]
✓ A > b
✓ A > 1 > a [0.23ms]
✓ A > 1 > b [0.02ms]
✓ A > 2 > 1 > a [0.01ms]
✓ A > 2 > 1 > b [0.01ms]
✓ A > 2 > 2 > a [0.01ms]
✓ A > 2 > 2 > b [0.21ms]
✓ A > 2 > 2 > c
✓ A > 2 > 3 > a
✓ A > 2 > 3 > b [0.01ms]
✓ A > 2 > 3 > c
✓ A > 3 > a
✓ A > 3 > b
...

What do you see instead?

Instead I see an execution order that seems to follow no logic.

...
test.spec.ts:
✓ A > 1 > a [0.23ms]
✓ A > 1 > b [0.02ms]
✓ A > 2 > 1 > a [0.01ms]
✓ A > 2 > 1 > b [0.01ms]
✓ A > 2 > 2 > a [0.01ms]
✓ A > 2 > 2 > b [0.21ms]
✓ A > 2 > 2 > c
✓ A > 2 > 3 > a
✓ A > 2 > 3 > b [0.01ms]
✓ A > 2 > 3 > c
✓ A > 3 > a
✓ A > 3 > b
✓ A > a [0.01ms]
✓ A > b
...

One could argue that inner describe blocks should be executed first which does not make sense to me.

But here on A > 1 level it goes from outer to inner and on A level it executes the inner level A > 1-3 first and then the outer block A > a,b

Additional information

Assuming that inner tests build on top of outer tests they should also fail if a parent test fails. When I tell the runner to exit after the first failed test I can safe valuable runtime.

Imho this is not a duplicate of #5738 since it is independent from setup and teardown hooks.

vinnichase avatar Apr 25 '24 08:04 vinnichase

having the same issue, working with a mocked queue is extremely difficult right now, on one describe i send a message through a service and check that it's sent, then in other describe i clear the mocks to do it again, the second describe clears the mock before i can check it on the firs one

gunsha avatar Jul 12 '24 03:07 gunsha

Fixed by @pfgithub in #22534, and will be included in Bun v1.2.23 later tonight

Image

dylan-conway avatar Sep 27 '25 08:09 dylan-conway