scale icon indicating copy to clipboard operation
scale copied to clipboard

Unit Testing with React, Jest and Testing Library

Open tschinski opened this issue 3 years ago • 6 comments

Hello there,

we spent some time with unit tests in frontend the last weeks and run into several problems when testing a React component which contains Scale components.

Our setup is: React Jest as a test runner Testing library as testing framework

Because we use Testing library, the testing approach is more like "inspect and test the component's output" then "testing a state variable of the component".

In components which include Scale components, we have the problem, that we only see e.g. <scale-button </scale-button in the output and not the nested dom.

By adding some awful timeouts, we achieved to see the whole Scale component in the ouput, but interacting with them isn't working as expected.

Are there any best practices or guidelines about testing a component in React (or JS code in general), which contains Scale components?

Cheers Tobias

tschinski avatar Oct 18 '21 12:10 tschinski

Hey Tobias, thanks a lot for raising this issue.

I understand the problem. Interacting with the components in unit tests is difficult for a few reasons:

  • you have to make sure the custom elements are getting upgraded (aka defined)
  • the DOM testing environment (if not a real browser) must support custom elements
  • upgrading takes time, and
  • you need to account for the shadow DOM since most components use it

We don't have any best practices or guidelines, but we're going to work on them with high priority. I'm gonna start setting up an environment according to your setup. Can I ask you for details in case I need to?

The one thing I would suggest —please correct me if you're already doing this— is to try and test only the surface, namely, that the right props are being passed to these components, instead of checking the actual results in the DOM. Otherwise you might make the mistake of unnecessarily testing the component internals and not your own code which is what matters in the end.

For instance, if you're doing (this is fake code) <ScaleButton background="red">Open</ScaleButton>, instead of inspecting the DOM and checking for the actual background color, you just test that the element scale-button actually has the attribute/property background with a value of red. Making sure the component works as expected is the responsibility of the component library. Does that make sense?

A couple of technical tips from the top of my head (without having tested them in your setup):

  • you can use the customElements.whenDefined('scale-button') => Promise API to check for when an element has been upgraded, that could save you the timeouts

  • once the elements are upgraded, you should be able to inspect their inners by quering them and accessing their shadowRoot, like element.querySelector('scale-button').shadowRoot where element is a ref to ScaleButton (which is a wrapper for the actual scale-button custom element that it renders)

I will get back to you with more, hopefully very soon. Thanks again.

acstll avatar Oct 19 '21 08:10 acstll

Hey Arturo,

thanks for your quick reply.

I totally agree with you, we don't want to test the behaviour of the Scale components, that's your job ;).

Actually my example was really bad, forget the button. I try another one.

Imagine we have a component witch contains a Scale Checkbox and we want to display some content depending on checked or not. And we want to test that really user centric and not the implementation details, like is the checked state of the component true/false.

A user centric test would look like:

  • Render component
  • Check the checkbox
  • Write Assertions if the content is visible or not

For these kind of interactions we need the underlying native form elements.

Thanks for your technical advice, i will give them a try and give you some feedback.

If you have any questions about the setup, you can ask any time.

Cheers Tobias

tschinski avatar Oct 20 '21 11:10 tschinski

Hi @tschinski

This seems related to https://github.com/telekom/scale/issues/1101.

Have you got any updates on this?

We are considering switching from Karma to Jest and will probably face similar issues. I found this blog post that might have the solution which is to use Electron as the test env and runner: https://www.ninkovic.dev/blog/2020/testing-web-components-with-jest-and-lit-element

mato-a avatar Jul 06 '22 13:07 mato-a

Hi there, we also want to migrate our tests from Enzyme (which has only support for react 17) to React Testing Library.

Is there a way/good practice to test scale components with it?

Thanks

tommy-codez avatar Sep 19 '22 09:09 tommy-codez