Web applications, on their front ends, are HTML pages. The origin of this HTML is some code in the server, that in some way, delivers a complete HTML page to the browser. The browser renders the HTML, and brings all the necessary design and images. It also processes the interactions of the user with the page’s elements.

Ok, you know that.

The thing is, browsers render and display complete HTML pages. However, we know that modern web apps, are built with components. These components don’t look exactly like HTML and javascript.

More importantly: How can I test them?

Where have all those components gone? What happend to the component I wrote, and where is it in the HTML I just got? How can I access them?

Here’s a page. This thing here in blue (including the label and textbox) is a React component.

Here’s the page’s code. I used NextJS to build it. You can see it contains the component.

And here’s the React component code, using Material UI components. It includes the blue Box that contains a label and a TextField.

So, far so good. As you can see I’ve got nothing up my sleeves.

Now let’s take a look at the resulting HTML of the page.

You can squeeze your eyes as much as you want. I only have one question:

Component Tests Magic

Web components are a bit weird, if you’re coming from an object-oriented, compiled world. After all, in Java, for example, if there’s a class defined somewhere, we can always create an instance of it and use it.

When we’re testing the class in a unit test, we’re doing exactly that – we create an instance of it, operate it and query it.

Starting out, web component, look the same way. You can write a Component Test, that renders the component, and checks its behavior. And this test looks like a regular unit test.

Like this (This is using Jest with the React Testing Library):

Test works! Ship it!

Then things change.

We saw that the reslulting HTML web page has no recollection of the contained components. That’s because as part of the build process of the pages, the components are ripped apart into bits and pieces of HTML and JS, then complete HTML page is built and served.

Looking at the resulting HTML you may identify some of the code. But because the build process is optimized for fast network delivery, and not for human readability, some bits would be less recognizable. Or completely.

The rendered component becomes partial HTML and JS. There’s no “instance” of it. No “properties” that may have been there on the design side. It is no longer a component, especially a React component, because HTML doesn’t speak React-ish.

So How The Hell Did I Test It?

I still have a running component test. What sorcery is this? Let’s look at it again.

You see the render command? It’s part of the React Testing Library. It does the HTML and JS translation. It does it inside a container, or a testbed. Remember that components compile into partial HTML. They don’t translate into complete HTML, like a regular page. For the translation to work, we need a surrogate for the page, and that’s going to be the container that the test library provides. When run in the real application, the component will be translated into the real application pages.

Our component test has access only to the HTML of the rendered component. There’s no page there to handle events, or to contain things, other then what we wanted to render. In this test we render just the component. We can send more HTML there, depending on the context we want to test it in.

That means everything our test know about, is the resulting HTML DOM of our component, and nothing else. Like with a unit test, we’ve achieved isolation of the tested code.

That’s cool, because isolation gives us speed, it gives us focus, it gives us easier debugging and maintenance.

In fact, when our test runs with Jest, there’s no browser that needs to load, go to a server, get a page, render everything on the page, and then we need to find our elements on the page and operate them. This is how testing with Selenium or Playwright work. Slow and heavy.

Think on the test-bed as a small HTML processor, that runs in-process. And when the test is done, exits without leaving a footprint.

Just like a unit test.

Of course, if our component calls out, making API calls, or tries to access resources – it will fail our test. If the resources are not accissible, or if we didn’t mock them correctly.

Just like a unit test.

Component tests are fast, focused, small and turns out – pretty stable. Without external dependencies (or when they are handled correctly), component tests are as dependable as unit tests.

And we really like those kind of tests. They give us the confidence the small parts work before integrating them into the big world, and with a cheap price tag.

Final thing about them – we couldn’t write a component test, without a component. Think about if you wrote plain HTML and vanilla javascript. You;d have to load the the entire page and test it as a whole. Then, you’d have to test another page where the “component” bits appear.

Turns out, again, that if you write the code in a certain way, you make your testing life easy (or hard).

Component tests are unit tests’ siblings. One fast, trustworthy, and happy family. And if you want to learn about testing web components, and web in general, check out my web developer tesitng workshop.

Categories: Uncategorized

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *