[React 19] revive `react-test-renderer`
Summary
Ideally react is shipped with official test utilities instead of relying on third-party vendors.
Unfortunately it was decided to deprecatereact-test-renderer.
As a consequence it isn't easy anymore to:
- write unit tests
- test React components independently of the target platform (React DOM, React Native, or any other custom renderer which is out there)
- test complex, deeply nested component trees
- shallow render
- make shallow snapshots
- to run tests FAST (in memory)
Regressions
@testing-library/react is an integration testing library, promotes testing anti-patterns and completely ditches unit tests.
It is slow and requires a DOM or a mock like js-dom.
Please refer to these resources for a comprehensive understanding of why unit tests are of high value:
- https://martinfowler.com/articles/practical-test-pyramid.html#UnitTests
Other critical voices from the community
- https://javascript.plainenglish.io/in-defense-of-shallow-rendering-5f627f7c155d
- https://blog.hao.dev/my-struggles-with-react-testing-library
References
react-test-rendereris deprecated. A warning will fire whenever callingReactTestRenderer.create()orReactShallowRender.render(). Thereact-test-rendererpackage will remain available on NPM but will not be maintained and may break with new React features or changes to React’s internals. https://react.dev/warnings/react-test-renderer
react-test-rendereris deprecated and no longer maintained. It will be removed in a future version. As of React 19, you will see a console warning when invokingReactTestRenderer.create(). https://www.npmjs.com/package/react-test-renderer/v/19.0.0-canary-8afa144bd-20240416?activeTab=readme#react-test-renderer-deprecated
Note: that affects any code using react-test-renderer
https://github.com/search?q=repo%3Ajestjs%2Fjest%20react-test-renderer&type=code
I fully agree with the points raised in this issue. The React thinking model, which emphasizes components, is widely praised for its effectiveness. It is only logical to continue this component-centric approach in unit testing as well. Usually I want to only test the public API of the component under test during unit tests. In my view, this API consists of props and context as inputs and the virtual DOM tree as the output.
I think we could imagine the DOM as an I/O device. Abstracting I/O devices has been a common practice for already a few decades because it hides device-specific quirks and allows us to focus on business logic. This is where react fits in perfectly. It abstracts the DOM and other renderers. I trust a renderer like react-dom-renderer to work correctly and do not see the need to re-test its behavior in my unit tests. Instead, I prefer to focus on testing the API at the component boundary, ensuring that my components interact with the renderer in the expected way.
Testability is a crucial feature for me, and it is one of the main reasons I choose React. In my experience, most other frameworks or rendering libraries present even greater challenges when it comes to testing. With the deprecation of react-test-renderer, I feel like React is losing its most valuable feature.
As I understand the major issue with the current version of react-test-renderer is that it exposes the fiber data structures directly, but those data structures are target of frequent backwards-incompatible changes, right? So what if we could use something different? IMHO it doesn’t have to be fiber instances that react-test-renderer should expose. The only important thing is that it represents the rendered component tree.
I’m not really familiar with react internals and especially not with the DevTools, but from what I’ve seen while skimming recent PRs, there is a lot of things going on regarding DevTools. One interesting change was #30625 which introduces a shadow/virtual tree for the same reason, so DevTools are less dependent on fiber data structures. Wouldn’t it be possible to use the same approach for a test renderer? CC: @sebmarkbage.
Just adding my two cents...
I see two approaches: either run everything with jsdom and you will get complete html, which is unnecessary but mainly SLOW or use react-test-renderer run your implemented logic, get logical results which you can process without unnecessary html and do it 2 - 3 times faster.
So please, keep react-test-renderer alive.
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
+1
+1
React Docs: The React team recommends @testing-library/react-native as a replacement for react-test-renderer for native integration tests. This React Native testing-library variant follows the same API design as described above and promotes better testing patterns.
@testing-library/react-native docs: This library has a peer dependency for react-test-renderer package. Make sure that your react-test-renderer version matches exactly your react version.
This is contradictory. What is the plan here?
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
+1
This issue has been automatically marked as stale. If this issue is still affecting you, please leave any comment (for example, "bump"), and we'll keep it open. We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
+1