telekom / scale

Scale is the digital design system for Telekom products and experiences.
https://telekom.github.io/scale/
Other
374 stars 82 forks source link

Unit Testing with React, Jest and Testing Library #631

Open tschinski opened 3 years ago

tschinski commented 3 years ago

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

acstll commented 3 years ago

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:

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):

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

tschinski commented 3 years ago

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:

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

mato-a commented 2 years ago

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

tommy-codez commented 2 years ago

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

tshimber commented 2 days ago

@tschinski @mato-a @tommy-codez is the issue still relevant?

mato-a commented 2 days ago

For me this is no longer relevant.