Testing Recipes for web components: Part 1 — Testing Presentation Components
There are limit out of box solution for web component testing like wct. However I managed to create much easier setup with lit-html , open-wc, karma. Here is how my package.json look like
Step 1: Setting Up Karma
Karma needs to be updated with file loaders to handle the es6 modules. karma.conf.js will go inside root of your folder
2. Testing Code
a) Testing Functional Components: Functional components are who are just used for presentation and doesn’t manage own internal state
For example lets test this movie card
It includes a image, title, ratings and date.
so my input will an json object with above mentioned properties. Web component code for movie card is as follows
Images are coming from tmdb ui.
Let’s create our movie-card.test.ts file.
First import all the required dependencies
import { html, fixture, expect,} from '@open-wc/testing';
import './movie-card.js';
Here is our sample input
Let’s start our unit tests, we will be using mocha for test language and fixture from open-wc for rendering the component. We also will be using sinon for stubs and fakes
As you can see, I have created a pseudo renderer inside ‘el’
Let’s go to actual test cases
- Test if card has a proper movie rating
We will be testing following line with given input
<div class="movie__rating">${movie.vote_average}</div>
Our test case goes as follows
- Get the element or shadowRoot from fixture renderer. I mostly test over shadow renderer
- check if element contains expected output
it('has a proper movie rating', async () => {//const el = await fixture('<movie-card></movie-card>');el.movie = MOVIE_INPUT;const movieRating = el.shadowRoot.querySelector('.movie__rating');expect(movieRating.innerHTML).to.equal('7.2');});
So we are expecting out movie Rating to be 7.2, so as per our given input, test case should be successful. You can try by supplying different input.
Now run npm run test
to check and test coverage
2. Check has proper movie title
<h3 class="movie__title">${movie.title}</h3>it('has a proper movie title', async () => {el.movie = MOVIE_INPUT;const title = el.shadowRoot.querySelector('.movie__title');expect(title.innerHTML).to.equal('Aladdin');});
3. Check has proper movie poster
<img src="${posterUrl}" alt="${movie.title}">it('has a proper movie poster', async () => {el.movie = MOVIE_INPUT;const poster = el.shadowRoot.querySelector('.movie__poster > img');expect(poster.src).to.equal('https://image.tmdb.org/t/p/w500/3iYQTLGoy7QnjcUYRJy4YrAgGvp.jpg');});
4. Negative: Check has no movie poster
<img src="${posterUrl}" alt="${movie.title}">it('has a NO movie poster', async () => {delete MOVIE_INPUT.poster_path;el.movie = MOVIE_INPUT;const title = el.shadowRoot.querySelector('.movie__poster > img');expect(title.src).to.contain('no-poster.png');});
So we comes to end to test our presentation web component, in next part we will go to test stateful components and most important the custom events testing.
Here is our final code
Go to the second part of the series
You can check the complete code here at https://github.com/inms-adarsh/movie-app-webc and demo is at https://movie-app-892c6.firebaseapp.com/