SolidOS / solid-ui

User Interface widgets and utilities for Solid
https://solidos.github.io/solid-ui/dist/solid-ui.js
MIT License
148 stars 41 forks source link

Unit tests for functionality that involves DOM manipulation #215

Open megoth opened 4 years ago

megoth commented 4 years ago

We are currently working on writing unit tests for existing functionality. Solid UI has a lot of functionality that deals with DOM manipulation, which can be extremely hard to write good unit tests for (good as in easy to maintain). For this reason we might skip some tests in this iteration that we deem to complex/hard to write good tests for.

All of these tests will refer to this issue by URL so that we can revisit these skipped tests later on when we have better strategies for dealing with these kinds of DOM manipulation.

If you have suggestions for what these strategies can be, please let us know.

timbl commented 4 years ago

When two pieces of code do the same thing, one using dom manipulation and the other using templates or JSX, why is the one which manipulates the Dom harder to write tests for?

Vinnl commented 4 years ago

The main reason is that, when you are generating a Virtual DOM, you generally do not need to worry about consecutive updates. For example, if it renders a list of friends, and the user unfriends someone, there's no need to remove their respective list elements - the function generating the Virtual DOM is simply called again and renders one fewer list element.

That allows for the unit test to simply pass the list of friends as arguments, and to verify that it displays all of them, whereas tests for code writing against the DOM will also need to maintain a reference to the rendered (likely mocked, but still stateful) DOM, simulate the removal of a friend, and verify that that update is rendered correctly. And these type of tests grow exponentially: if the user then also has the ability to add a friend, for example, you'll not only have to add a test to check whether the addition is rendered correctly, but also that it is still rendered correctly if a friend is added after a friend is removed, and vice versa.

(Or more likely: those tests won't get written (coverage reports don't catch their absence either), and there will be bugs in the app.)

Additionally, a virtual DOM is natively "rendered" in-memory and hence independent of the browser runtime, so the test environment is more similar to the production environment without having to fire up a full-fledged browser during unit tests (which also makes tests more flaky).