-
-
Notifications
You must be signed in to change notification settings - Fork 700
test: migrate to Vitest fake timers, remove @testing-library/user-event, and resolve act warnings #3147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test: migrate to Vitest fake timers, remove @testing-library/user-event, and resolve act warnings #3147
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
commit: |
bae4b43 to
93723d9
Compare
|
| Playground | Link |
|---|---|
| React demo | https://livecodes.io?x=id/6RNESTAFA |
See documentations for usage instructions.
5d220f5 to
80e3043
Compare
…ByText' with 'getByText', and add fake timers
80e3043 to
9c44611
Compare
0fc2d0e to
c93671a
Compare
…ByText' with 'getByText', and remove 'waitFor'
4c297c0 to
c871edf
Compare
9643b35 to
7f52e9e
Compare
7f52e9e to
4d9a53c
Compare
…t' with 'getByText', add fake timer, and remove 'waitFor'
4d9a53c to
1c953e2
Compare
Got it now. Thanks for your tip. |
dai-shi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finally, I reviewed all files. Hope I don't miss anything. If I do, hope you can cover it.
tests/react/useAtomValue.test.tsx
Outdated
| const asyncAtom = atom(async () => 42) | ||
| const asyncAtom = atom(async () => { | ||
| await new Promise((resolve) => setTimeout(resolve, 10)) | ||
| return 42 | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you revert the change in this PR?
I only find it in this file, but please check all other files too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests/react/useAtomValue.test.tsx
Outdated
| expect(screen.getByText('loading')).toBeInTheDocument() | ||
|
|
||
| expect(await screen.findByText('value: 42')).toBeInTheDocument() | ||
| await act(() => vi.advanceTimersByTimeAsync(10)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though, this is a good addition to our tests. Let's do that after merging this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // we need a small delay to reproduce the issue | ||
| await new Promise((r) => setTimeout(r, 10)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't feel valid to remove this. It means to remove the entire spec. Would it be possible for you to try reverting #1481 temporary on your end locally and learn how to reproduce the issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests/vanilla/store.test.tsx
Outdated
| await new Promise((r) => setTimeout(r)) | ||
| await Promise.resolve() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes the behavior. Can you revert?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| get(countDerivedAtom) | ||
| set(countAtom, 2) | ||
| }) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you remove changes that only add new lines? It makes the diff bigger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dai-shi These blank lines improve readability by separating logical sections. I'd prefer to keep them if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you might have noticed that my preference is fewer lines. Anyway, it's just stylistic. I will change them later if I want to.
tests/vanilla/utils/unwrap.test.ts
Outdated
| await store.get(asyncAtom) | ||
|
|
||
| await vi.advanceTimersByTimeAsync(100) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it's testing the same thing, but should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was fixed with f674996
tests/vanilla/utils/unwrap.test.ts
Outdated
| store.set(syncAtom, Promise.resolve(2)) | ||
| store.set( | ||
| syncAtom, | ||
| new Promise<number>((resolve) => setTimeout(() => resolve(2), 100)), | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw this kind of changes many times, but I wonder if we could simply do vi.advanceTimersByTimeAsync(0), instead of changing the atom definition. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted to Promise.resolve() with vi.advanceTimersByTimeAsync(0) in unwrap.test.ts and loadable.test.ts (f674996)
…thout 'setTimeout'
1a34580 to
9125c21
Compare
…d use 'advanceTimersByTimeAsync(0)'
…erve macrotask behavior
…r for infinite loop test (pmndrs#1481)
65ab804 to
25e2ba6
Compare
dai-shi
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not surprised if I missed anything, but let's merge this for now.
Thanks for your contribution!
| get(countDerivedAtom) | ||
| set(countAtom, 2) | ||
| }) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, you might have noticed that my preference is fewer lines. Anyway, it's just stylistic. I will change them later if I want to.
Related Bug Reports or Discussions
Fixes #
Summary
This PR migrates all tests from real timers to Vitest fake timers to improve test determinism and execution speed. The migration includes comprehensive updates across 33 test files, eliminates most React act warnings, and removes the
@testing-library/user-eventdependency in favor offireEvent.Key Changes
beforeEach(vi.useFakeTimers)andafterEach(vi.useRealTimers)userEventwithfireEvent- Use synchronous event simulation (userEvent uses real timers internally)setTimeoutdelays - Convert manual promise resolution to timer-controlled delaysfindByText/waitFortogetByTextwith explicit timer controlWhy Replace
userEventwithfireEvent?userEventuses real timers internally, conflicting with fake timersfireEventis synchronous and fully compatible withvi.useFakeTimers()fireEventPattern (Simple Rule)Use
await act(() => fireEvent.click(...))when immediately checking Suspense loading state.Otherwise use plain
fireEvent.click(...).Examples
With Suspense (need act):
Without Suspense (plain fireEvent):
Pro tip: When in doubt, try plain
fireEventfirst. If the test fails or shows act warnings, wrap withawait act().Statistics
package.json@testing-library/user-eventCheck List
pnpm run fixfor formatting and linting code and docs