vitest-dev / vitest

Next generation testing framework powered by Vite.
https://vitest.dev
MIT License
12.96k stars 1.16k forks source link

Vitest is not showing act warnings when it actually should when testing React components #6782

Open amrtaher1234 opened 10 hours ago

amrtaher1234 commented 10 hours ago

Describe the bug

Act warnings are very useful to spot issues in your codebase and to make tests more resilient.

I have a test that should trigger an act warning. When trying to run Jest and rendering the component it shows the act warnings as expected but when running vitest no act warnings are shown, I tried playing around with configuration file to see if console warnings/errors are disabled somehow but no luck.

If vitest does some act wrapping magic then it should document it some where, act warnings in general are very useful and makes 1) tests more resiliant 2) spot issues in your code.

Here is the component I'm testing:

import React, { useState, useEffect } from "react";

const Counter = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    // Simulate an async state update, like a network request.
    const timer = setTimeout(() => {
      setCount(count + 1);
    }, 5000);

    return () => clearTimeout(timer);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};

export default Counter;

Here is the test:


it("Counter with act warnings", () => {
  render(<Counter />);

  const button = screen.getByText("Increment");
  button.click(); // shjould trigger act warnings, no `act(...)` is used here.

});

Reproduction

https://stackblitz.com/edit/vitest-dev-vitest-zk9hnz?file=test%2Fcounter.test.tsx

System Info

System:
    OS: Windows 11 10.0.26100
    CPU: (12) x64 AMD Ryzen 5 7600X 6-Core Processor
    Memory: 5.71 GB / 31.15 GB
  Binaries:
    Node: 19.8.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.19 - C:\Program Files\nodejs\yarn.CMD
    npm: 9.5.1 - C:\Program Files\nodejs\npm.CMD
    bun: 1.1.1 - ~\.bun\bin\bun.EXE
  Browsers:
    Chrome: 130.0.6723.58
    Edge: Chromium (130.0.2849.46)
    Internet Explorer: 11.0.26100.1882
  npmPackages:
    @vitejs/plugin-react: ^4.3.2 => 4.3.3
    vite: ^5.4.8 => 5.4.9
    vitest: ^2.1.3 => 2.1.3

Used Package Manager

npm

Validations

sheremet-va commented 10 hours ago

There is zero code except "it" from your reproduction that is coming from Vitest. Vitest doesn't know anything about react, the testing library that you use renders your components, not Vitest.

amrtaher1234 commented 10 hours ago

Hmmm, running the exact same test and only removing the vitest it import and running npx jest gives me an act warning.

I'm not using anything from RTL except for the render and the getByText methods which does not do contribute to the issue as the real issue comes when clicking the button (because it sets a state in async)

sheremet-va commented 10 hours ago

The testing library might rely in jest API to give the warnings. Vitest does nothing but give a runtime to run the code in.

This is an issue with testing-library running in Vitest, not Vitest doing something different.

amrtaher1234 commented 10 hours ago

@sheremet-va Another fun reproducible one:

import Counter from "../comp";
import { it } from "vitest";
import { createRoot } from "react-dom/client";

it("Counter", () => {
  const container = document.createElement("div");
  createRoot(container).render(<Counter />);

  const buttonElement = container.querySelector("button"); 
  buttonElement?.click();
});

No more RTL here. Jest still shows act warnings

sheremet-va commented 9 hours ago

Then react itself expects a jest environment to give act warnings. Again, there is nothing Vitest does to make this work/not work.

amrtaher1234 commented 9 hours ago

I see, that is a reasonable explanation. Will take this to the React team cause I really think this is a blocking issue, act warnings should be always displayed regardless of the test runner (jest or vitest in this case).

I'll come back with their replies (hopefully soon)

Thank you for the very quick reply btw, great project!

hi-ogawa commented 5 hours ago

Look like you can use globalThis.IS_REACT_ACT_ENVIRONMENT = true to get the warning https://stackblitz.com/edit/vitest-dev-vitest-apefdq?file=test%2Fcounter.test.tsx I was poking around the code here https://github.com/facebook/react/blob/1631855f4303cc8585205307a56c69e3b7248bb4/packages/react-reconciler/src/ReactFiberAct.js which also involes type jest global check.