oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.51k stars 2.79k forks source link

`bun test` #1825

Open Electroid opened 1 year ago

Electroid commented 1 year ago

Jest

describe()

test()

Lifecycle hooks

expect()

Mocks

Misc

Vitest

expect()

Mocks

Timers

Misc

jest-extended

expect()

useafterfree commented 1 year ago

ts-jest does some magical hoisting with mock* functions which may or may not be a challenge with bun: https://github.com/swc-project/swc/issues/5448#issuecomment-1386969864

nskins commented 1 year ago

This issue can be updated to check off these four (they were implemented in PR https://github.com/oven-sh/bun/pull/1573):

erikshestopal commented 1 year ago

Should jest.mock be added as well? Doesn't seem to be tracked.

Jarred-Sumner commented 1 year ago

@erikshestopal please give it a try in the canary build, a lot of it is in there

brapifra commented 1 year ago

jest.clearAllMocks() is also missing 👀 🙏

image

itsezc commented 1 year ago

Would there be any scope to add DOM matchers? If so, I'd love for some parity with the jest-dom library.

Hanaasagi commented 1 year ago

2023-07-07_10-56

toThrowError is missing. It's a alias for toThrow.

Ref: https://jestjs.io/docs/expect#tothrowerror

riywo commented 1 year ago

test.each and describe.each are super helpful to build data-driven unit tests.

simylein commented 1 year ago

I am proposing adding https://vitest.dev/api/expect-typeof.html to the vitest list.

ghiscoding commented 1 year ago

test.each and describe.each are super helpful to build data-driven unit tests.

It's being worked on in PR #4047

dsanchezjt commented 1 year ago

Are there plans to add the expect.toBeInTheDocument matcher from @testing-library/jest-dom that many typically use for JSX component testing? Or is that out of scope? Feels like that would be something useful to provide out of the box.

OleksandrKucherenko commented 1 year ago

expect.objectContaining

any ideas how to replace this call in tests?

Solution / Workaround

    expect(Object.fromEntries(data.statistics[Kpi.codes])).toHaveProperty(`502`, 1)
    expect(Object.fromEntries(data.statistics[Kpi.codes])).toHaveProperty(`200`, 32)

// instead of:

    expect(Object.fromEntries(data.statistics[Kpi.codes])).toStrictEqual(
      expect.objectContaining({ '200': 32, '502': 1 })
    )
OleksandrKucherenko commented 1 year ago

What can you recommend as a replacement for such jest code?

await expect(async () => await askGPT(text, prompt, context)).rejects.toThrowError(`⛔ API error.`)
simylein commented 1 year ago

Shouldn't that be working?

Does this suit your needs?

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

const askGPT = async (text: string, prompt: string, context: string): Promise<void> => {
    throw new Error('⛔ API error.');
};

describe('', () => {
    test('', async () => {
        await expect(async () => await askGPT('text', 'prompt', 'context')).toThrow(Error(`⛔ API error.`));
    });
});
TroyAlford commented 1 year ago

Edit: these functions have been added to the list, now, thank you!!


Should jest.mock be added as well? Doesn't seem to be tracked.

This still seems to not be on the list. Could we get support for jest.mock and jest.requireActual compatibility APIs added as an official target on this list? Module mocking is a pretty important part of jest compatibility.

Example:

import { foo } from 'some-module'

jest.mock('some-module', () => ({
  ...jest.requireActual<object>('some-module'),
  foo: jest.fn(() => 'foo'),
}))

The pattern here allows you to override just the foo method of some-module, while requireActual gives you the real implementation for the rest.

Jest also supports placing an override for some-module in a __mocks__/some-module.ts file, as another way to automatically module-mock, though imho that is less priority.

silverwind commented 1 year ago

Shouldn't that be working?

Does this suit your needs?

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

const askGPT = async (text: string, prompt: string, context: string): Promise<void> => {
  throw new Error('⛔ API error.');
};

describe('', () => {
  test('', async () => {
      await expect(async () => await askGPT('text', 'prompt', 'context')).toThrow(Error(`⛔ API error.`));
  });
});

This works only in bun, but not in vitest, so it's not compatible. It seems .rejects.toThrow is not implemented correctly or at all in bun, it throws Expected value must be a function on code like this that works in vitest:

await expect(asyncFn()).rejects.toThrow()
coratgerl commented 1 year ago

There is an issue on spyon https://github.com/oven-sh/bun/issues/4482

supersmile2009 commented 1 year ago

Would love to see these implemented:

Even basic half-broken implementation of concurrent (like in jest) would be awesome, as it's absolutely vital for various slow integration tests involving external APIs and services. I'm saying half-broken because in jest before* and after* hooks don't work correctly with concurrent, but it's still usable - you can call the setup/teardown logic directly from each test.

coolxeo commented 1 year ago

Should jest.mock be added as well? Doesn't seem to be tracked.

This still seems to not be on the list. Could we get support for jest.mock and jest.requireActual compatibility APIs added as an official target on this list? Module mocking is a pretty important part of jest compatibility.

Example:

import { foo } from 'some-module'

jest.mock('some-module', () => ({
  ...jest.requireActual<object>('some-module'),
  foo: jest.fn(() => 'foo'),
}))

The pattern here allows you to override just the foo method of some-module, while requireActual gives you the real implementation for the rest.

Jest also supports placing an override for some-module in a __mocks__/some-module.ts file, as another way to automatically module-mock, though imho that is less priority.

Well put together @TroyAlford I think this is a very clear implementation maybe you want to create a new issue?

riezahughes commented 1 year ago

Are there plans to add the expect.toBeInTheDocument matcher from @testing-library/jest-dom that many typically use for JSX component testing? Or is that out of scope? Feels like that would be something useful to provide out of the box.

Very much looking for information on this as well to be honest.

TroyAlford commented 1 year ago

Could we get support for jest.mock and jest.requireActual compatibility APIs

Well put together @TroyAlford I think this is a very clear implementation maybe you want to create a new issue?

This has been added to the list above, now. Thank you!! :) As suggested by @coolxeo, I've also opened a new issue in relation for tracking the sub-task: https://github.com/oven-sh/bun/issues/5394.

vidup commented 1 year ago

Shouldn't that be working? Does this suit your needs?

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

const askGPT = async (text: string, prompt: string, context: string): Promise<void> => {
    throw new Error('⛔ API error.');
};

describe('', () => {
    test('', async () => {
        await expect(async () => await askGPT('text', 'prompt', 'context')).toThrow(Error(`⛔ API error.`));
    });
});

This works only in bun, but not in vitest, so it's not compatible. It seems .rejects.toThrow is not implemented correctly or at all in bun, it throws Expected value must be a function on code like this that works in vitest:

await expect(asyncFn()).rejects.toThrow()

I have the exact same issue: it is not ISO from jest to bun. expect().rejects.toThrow breaks in bun while working in Jest.

mrherickz commented 1 year ago

Shouldn't that be working? Does this suit your needs?

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

const askGPT = async (text: string, prompt: string, context: string): Promise<void> => {
  throw new Error('⛔ API error.');
};

describe('', () => {
  test('', async () => {
      await expect(async () => await askGPT('text', 'prompt', 'context')).toThrow(Error(`⛔ API error.`));
  });
});

This works only in bun, but not in vitest, so it's not compatible. It seems .rejects.toThrow is not implemented correctly or at all in bun, it throws Expected value must be a function on code like this that works in vitest:

await expect(asyncFn()).rejects.toThrow()

I have the exact same issue: it is not ISO from jest to bun. expect().rejects.toThrow breaks in bun while working in Jest.

Same here, it seems like we cannot await on expect also

Screenshot 2023-09-15 at 17 10 19
ImBIOS commented 1 year ago

Are there plans to add the expect.toBeInTheDocument matcher from @testing-library/jest-dom that many typically use for JSX component testing? Or is that out of scope? Feels like that would be something useful to provide out of the box.

I also need this feature for component testing

riezahughes commented 1 year ago

Are there plans to add the expect.toBeInTheDocument matcher from @testing-library/jest-dom that many typically use for JSX component testing? Or is that out of scope? Feels like that would be something useful to provide out of the box.

I also need this feature for component testing

i've asked a few times on their discord but nobodies been able to give any answer at all regarding this.

Jarred-Sumner commented 1 year ago

@riezahughes we will add support for expect.extend and get @testing-library/jest-dom to work

Almenon commented 1 year ago

Another thing to consider for compatibility is the ability to configure custom file names to pick up: https://github.com/oven-sh/bun/discussions/5880

In jest you can do this with https://jestjs.io/docs/configuration#testregex-string--arraystring

Voldemat commented 1 year ago

@Jarred-Sumner @Electroid Hi, is there any roadmap or planned date of release for this missing features? Personally interested in concurrent tests, as it could speed up some tests significantly.  By the way do you plan to create some sort of fixtures for tests? I think it is big pain point for a lot of people. Right now we use a workaround, but it would be nice to see it in standard bun testing library. P.S. by fixtures I mean some objects that are reused between tests and there is a ways for tuning its lifetime

stevensacks commented 1 year ago

@riezahughes we will add support for expect.extend and get @testing-library/jest-dom to work

This is the primary thing keeping us from adopting bun.

mgasner commented 1 year ago

@riezahughes we will add support for expect.extend and get @testing-library/jest-dom to work

This is the primary thing keeping us from adopting bun.

This is also the only thing keeping us from adopting bun.

itsjavi commented 1 year ago

Apart from expect.extend, these are the ones preventing us to switch to bun test, since it seems there are no easy workarounds for them:

expect.toHaveBeenCalledWith, expect.toHaveBeenLastCalledWith, expect.toHaveBeenNthCalledWith, jest.mock, jest.clearAllMocks, jest.resetAllMocks

Also, these ones are very helpful to wait for all timers and promises:

jest.runAllTicks and jest.runAllTimers

Anyway, excellent work! I am using bun for simple tests and they fly so fast I can't even believe they worked :D

KutnerUri commented 1 year ago

I'm seeing a type problem with expect(x).toSatisfy(predicate). it seems type of x is always unknown.

Screenshot 2023-10-18 at 17 18 47
vikingair commented 1 year ago

I think you are missing expect.getState in your list, which allows to get the current information from the context such as the currentTestName.

HarryTurney commented 1 year ago

Yeah, I'd love to move to bun but a lot of tests using jest.clearAllMocks

redbmk commented 1 year ago

I haven't seen vitest's In-Source Testing mentioned here or documented anywhere else, but I think that would also be a great feature.

Something like

// internal function
const add = (left, right) => left + right

if (import.meta.buntest) {
  const { test, expect } = import.meta.buntest
  test('add', () => {
    expect(add(1,2)).toBe(3)
  }
}

and vitest could be an alias for buntest which would just expose bun:test.

The idea is that you can test internal utility functions you don't want to export but that might have decently complicated logic with edge cases worth testing.

nedredmond commented 1 year ago

Why not track vitest's expect.unreachable()? It's very useful for ensuring variables aren't null in strict typescript modes-- i.e., if (!variable) expect.unreachable() will make sure variable can't be null or undefined going forward. https://vitest.dev/api/expect.html#expect-unreachable

fregante commented 1 year ago

vitest.dev/api/expect.html#expect-unreachable

That's just an alias for expect.fail: if (!variable) expect.unreachable(msg) is identical to if (!variable) expect.fail(msg)

TkDodo commented 1 year ago

Are there any plans to include expectTypeOf from vitest?

jakeboone02 commented 1 year ago

Looks like the expect.extend box can be checked off now that #7319 is merged, which closed #3621.

abejfehr commented 12 months ago

Is this accurate? I can't seem to use jest.resetAllMocks() in the latest version of bun (1.0.15), and I don't see it defined in the types

HarryTurney commented 12 months ago

I don't believe it is, I remember seeing that ticked back as of 1.0.13 and it didn't work then and it still doesn't work now.

bernsno commented 11 months ago

Seeing jest.clearAllMocks checked off but still getting jest.clearAllMocks is not a function in bun 1.0.17.

tdowling-hakbah commented 11 months ago

Seeing jest.clearAllMocks checked off but still getting jest.clearAllMocks is not a function in bun 1.0.17.

Same behavior in 1.0.18

maciej-gurban commented 11 months ago

@Electroid Could we update the original message with links to GIthub issues discussing the progress of each item that isn't checked off? Even a stub would be useful to follow the progress, i.e. get an email when it's implemented.

The only thing stopping my team from adopting Bun for testing would be having jest.requireActual(module) and .toContainEqual(item).

Plus the following if they indeed don't yet work like posters above mentioned:

ghiscoding commented 11 months ago

The only thing stopping my team from adopting Bun for testing would be having jest.requireActual(module) and .toContainEqual(item).

Just a side note, toContainEqual() was implemented in v1.0.19 and was highlighted in their release blog post New matcher in bun:test expect().toContainEqual()

mariusbutuc commented 10 months ago

When using bun 1.0.21 to explore these examples, I'm also experiencing

8 |     jest.advanceTimersByTime(time);
     ^
TypeError: jest.advanceTimersByTime is not a function. (In 'jest.advanceTimersByTime(time)', 'jest.advanceTimersByTime' is undefined)
Jarred-Sumner commented 10 months ago

When using bun 1.0.21 to explore these examples, I'm also experiencing

8 |   jest.advanceTimersByTime(time);
     ^
TypeError: jest.advanceTimersByTime is not a function. (In 'jest.advanceTimersByTime(time)', 'jest.advanceTimersByTime' is undefined)

We haven't implemented Jest timer support in Bun yet

kubaprzetakiewicz commented 10 months ago

@Jarred-Sumner is missing mock-related functionality (jest.*AllMocks) a bug or it was incorrectly marked as ready?

NateRadebaugh commented 10 months ago

Are test reporters in scope for this? eg junit test reporter can be useful in CI/CD scenarios

8019

DaleSeo commented 10 months ago

The following Jest methods are missing from the checklist: