DEV Community

Testing Workflow for Web Components

Thomas Allmer on April 09, 2019

Whenever you ship something to be used by others, you take on a responsibility to deliver safe and stable code. One way to address this is by testi...
Collapse
 
dj profile image
Daniel J. Lauk

Thank you for the time to writing this awesome tutorial!

Working through it has tremendously improved my understanding of the bits and pieces that make up testing in JS in general and for web components in particular.

I have been fiddling around with the "updates are asynchronous" problem, and found what looks like a solution: The updateComplete promise.

Using this promise, waiting for the updates to finish seems straight forward:

el.value = 'cat';
await el.updateComplete;
expect(logSpy.callCount).to.equal(1);

The tests pass using this construct, but -- as you already pointed out -- passing tests doesn't mean the tests actually work correctly. So maybe that's introducing more trouble down the line or hiding something, that I am unaware of, but still I have to ask: Is there a particular reason, you decided not to use updateComplete?

Collapse
 
dakmor profile image
Thomas Allmer

thxxxx ❤️

you are correct - using updateComplete will make the test pass. And in tests I use updateComplete a lot :) even the fixture itself relies on it 💪

However, setting properties is usually not an async action. So you would need to know that it's async and then you would need to know how to await this async-ness.

For logging it could be ok to stay async, unless you are actually logging timings 🙈

However other things

el.firstName = 'Foo';
el.lastName = 'Bar';
// would require an await el.updateComplete; if it's async
if (el.fullName === 'Foo Bar') { ... }

really would feel strange if they only work if you await an rendering update?
the "calculation" of a fullName should not depend on the updates of the dom.

I hope this makes it a little more clear 🤗
you can also read more in the original issue: github.com/Polymer/lit-element/iss...

Collapse
 
dj profile image
Daniel J. Lauk

Ah yes, I see what you mean now. Thanks for the added details.

I even had a look at the issue before I wrote my comment, but I just didn't get it in its entirety 🙈

Collapse
 
memee profile image
Maciej Maciaszek
✔ Do you want to install dependencies? › No
Enter fullscreen mode Exit fullscreen mode

Don't we want to install dependencies first before running npm test?

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
dakmor profile image
Thomas Allmer

Are you sure you selected to add "Testing" and do scaffolding for it?
You will need to hit "Space" and not "Enter" as it's a multi selection - it's a little confusing - we still want to improve that 🙈

Collapse
 
davidmaxwaterman profile image
Max Waterman

i get a folder with the name of my component

Like you, I guess most people will quickly figure out that you have to 'cd' into it, ie :

$ cd a11y-input

That step is missing.
I wonder if something changed in the generator between the time it was written and now :/

Collapse
 
fazuelinton profile image
fazuelinton • Edited

Not sure it is possible to follow through this tutorial at the present time.
Even after copying the dependencies and scripts from the Github project, and running npm run test this is what I get:

> a11y-input@0.0.0 test:watch /Users/veller/Programming/practice/a11y-input
> karma start --auto-watch=true --single-run=false

20 12 2021 22:09:22.141:WARN [karma]: No captured browser, open http://localhost:9876/
20 12 2021 22:09:22.176:INFO [karma-server]: Karma v5.2.3 server started at http://localhost:9876/
Enter fullscreen mode Exit fullscreen mode

This pretty much blocks me from the beginning, which is a bummer since this blog post seem to be a very thorough one.
I recognize the post is almost 3 years old and I congratulate OP for such work. At the same time I ask if by any chance there's a workaround, a newer version of the same content, etc.

Happy holidays!

Collapse
 
davidmaxwaterman profile image
Max Waterman • Edited

I find it odd that you select 'No':

✔ Do you want to install dependencies? › No

and yet:

npm run test

which complains about karma missing.

Did the 'test' 'script' used to do an 'npm install' or something. Why wouldn't you get the generator to install everything?

Hrm, I think things have changed too much, since even the 'npm run test' doesn't work as described.

@passle on the polymer @open-wc slack channel suggests just using the files as they are made by the generator.

Collapse
 
enginisha profile image
Enginisha

I an not able to set up this.. Npm run test giving error.. Saying no test specified.. Content of blog is good.. But i think some setup file or steps are missing..

Collapse
 
dakmor profile image
Thomas Allmer • Edited

hey, thx for letting me know :) the setup changed a little as the @open-wc generator evolved. I updated the appropriate part.

If it doesn't work out for you the easier would be to clone github.com/daKmoR/testing-workflow... and play around there - it has a working setup.

Collapse
 
enginisha profile image
Enginisha

HI Another query is what is the snapshot check use case , if somebody have updated then our changes are lost right? so what will be the right use case for testing the web components via snapshot

Thread Thread
 
dakmor profile image
Thomas Allmer

Snapshots are useful especially for components which very big dom trees - in these cases it's pretty painful to maintain 2 "versions" of the same dom (e.g. the actual dom and the dom you compare to in your test).

With snapshots you will be get an error whenever the html structure changed - what comes next depends:

  1. if you did not intend to change the dom (e.g. refactors, certain types of bug fixing, optimizations, ..) then something went wrong and you should fix it so the test passes again
  2. the dom change was intentional - then you just run the "update snapshot command" and your tests are green again

The important part here is that updating the snapshots is faster/simpler than manually adjusting a "dom string" (hence for doms with less then ~5-10 nodes it's probably impractical)

Collapse
 
enginisha profile image
Enginisha

Thanks for replying . Can you have all types of testing methods like event , loading of data like that.The link that you have shared consist of high level testing.

Thread Thread
 
dakmor profile image
Thomas Allmer

This is a setup of a Testing System you can test whatever is possible to test with JavaScript. Writing tests first usually results in a better API as you will need to make sure that your code is testable and all the needed information is publicly accessible.

For events just add an event listener and then expect if it was called the correct amount of times and with the expected parameters. Sinon can help in this case.

For data loading it really depends on your solution - sometimes it makes sense to check which properties end up on the web component and you there could be a "loading complete event" you await before testing. Or the data management has nothing to do with the component as it just get's passed in all the information via a global state management system.

So in short you should be able to test almost everything not only web components related :)

Thread Thread
 
enginisha profile image
Enginisha

Thank you Thomas. One thing i would like to hear from you is webcomponenets using angular vs lit-elements. what is your opinion about this. if you are not aware about this , can you give me some references regarding the same.

Thread Thread
 
enginisha profile image
Enginisha

Hi Thomas,

i made one dropdown component and i want to test on changing on value one event should dispatch. but dispatch event method is on selection change method. how i will call selection change method, by firing event (if yes how?)or by taking the id on select tag (which is inside dropdown component)and firing event.

Collapse
 
ilyaukin profile image
Ilya Lyaukin

So what this lib actually does? Run some dev server and a headless chrome against it? Can I connect to the server manually?

Collapse
 
mmblack profile image
mmblack

how i can import other package such as jQuery, axios in Open Web Components