Enzyme and react-test-library on the other hand have the potential to write a test like:
1. Mount component
2. Do something to the component (say click on a button)
3. Wait for React to settle down
4. Check that the component looks OK
Both Enzyme and RTL have many minor problems in 1, 2 and 4. For instance some CSS selectors that should work in Enzyme don't seem to. The html() method crashes sometimes in Enzyme. RTL's dependence on the accessibility tree answers some of the problems of "test automation" but it also is a statement that "three.js developers don't deserve to have a test framework". Also I have enough things to worry about with my code and getting it to actually work inside the test framework (like discovering whatever shibboleth it takes to get my useEffect callbacks actually called) that I don't have any mental capacity to fight with the accessibility tree and the Rube Goldberg machine that extracts it from HTML. Thus instead of seeing the HTML which the end user "sees" I have a bunch of abstractions that introduce more uncertainty in a situation where I'm already uncertain of just about everything.And it is (3) that is the elephant in the room because what you have to do for (3) is dependent on your application and it can get pretty complicated. The root problem is that your code might set some value by calling setSomeValue but even in a rerender, value doesn't change until React does some work that is scheduled in a promise. And that promise could cause another promise to get queued and so forth so all you can do is set a long timeout and keep polling to check that your component has really settled down which is dependent on your component, the implementation of your component, etc. (Hint: if your "unit test" has a 1000ms timeout it's not really a unit test... For that matter, RTL is always warning you how slow it is to look up items by role)
Given that React is so prominent in the industry and that people seem to think testing is so important you'd think somebody would patch React or the node.js runtime if necessary to keep track to see if there are still promises so (3) can be as simple as
await done()
Looking at discussions in the ticket systems for the frameworks the developers seem to be as confused as everyone else.As it was, if an evil billionaire had paid these framework developers to convince developers that testing is a total waste of time he'd be tickled pink by the results. Is anyone trying a different path? Is there a React testing framework developed by someone who actually tried writing tests for React?
Those are just real browsers running headlessly, performing UI actions, and then verifying the results (either looking for something in a real DOM and/or comparing screenshots). If something went wrong, the devs can then follow the exact steps to replicate it and debug it.
It was a lot quicker (and arguably more useful, I think, since it emulates real users and mostly real systems -- if your staging setup is similar to prod) than trying to shim some intermediary component testing. (You can also fake certain inputs in lieu of waiting for a backend, if you prefer.) Is it perfect? No, but it's a quick and cheap stopgap.
Edit: A further argument is that this can also help catch unexpected DOM bugs (like z-indexes or viewport width weirdnesses or plain browser incompatibilities) that pure code bugs won't catch. At the end of the day it's what the user sees that matters, so IMO if you have limited resources and can't write tests at every level, it's better to have more E2E coverage that realistically emulates what a real user would experience, since that would typically cover logic bugs too (at least happy path ones).
User flows can be written as sagas, or generators, or state machines—these get tested. Reifying a data object into some model that has a lot of derived getters or actions the presentation layer needs—this can be implemented and tested, then made available with a hook.
To me this is always the logical starting point because I can unit test or TDD, evaluate my assumptions about problems and solutions, and present conflicts to stakeholders, all without having to have the project up in the browser or writing problematic React tests.
When you have a component library that needs testing, or specific things need interaction testing, Storybook’s visual tests have been the easiest way to go. And if you’ve separated the logic out from the presentation as I’ve laid out, stories are easy to write because you’ve decoupled the presentation from the complicated bits from the start.
No solution is perfect! I see this as more integration / component testing than a true unit test.
Test what the user does and sees. I shoot for 90% coverage with about 100 integration tests using testing-library.