Web App Testing & Tools

Testing a Component with Storybook

Miško Hevery

Miško Hevery

Qwik Creator (Previously Angular)
Web App Testing & Tools

Check out a free preview of the full Web App Testing & Tools course

The "Testing a Component with Storybook" Lesson is part of the full, Web App Testing & Tools course featured in this preview video. Here's what you'd learn in this lesson:

Miško introduces Storybook, which enables UI testing by allowing developers to isolate individual components. The visual representation can be compared to previous tests, and controls can be exposed to manipulate the component in isolation to test how it responds to different inputs. The final code can be found on the lesson-6 branch.


Transcript from the "Testing a Component with Storybook" Lesson

>> Let's talk about testing UI, right? So again, what we're talking about is this white box in here, right? There's a page. This page has whole bunch of things on it. Well, we just want to assert, just like when we were talking about the whole application, we were focusing on a unit.

Our unit of testing now is gonna become just as white box in here. And we wanna assert that we can correctly render this white box. So how is this box rendered? So here's our component which we call a cluster. And it gets cluster props. And these props are gonna be the data set, the width and the height.

And looks like the size is optional, right? The size is the size of the box on the screen, right? And so all it does is grabs the data set, right? And we iterate over the data set, and for each item in a dataset, we create, in this case, a b element where we pass in left hop with the compute properties, colors, etc.

Now, you could do several things. First of all, you could definitely run a unit test to compute position, right? This would be a good function to make sure that this thing is doing what you think it's doing. I assume that it's not gonna be very hard, or we don't have to go because we've already kind of done it.

But how would you unit test this particular component? You could write a kind of a snapshot where you assert that the JSX that comes out of this is of the correct shape. But that doesn't actually answer whether it looks right, right? So what you really want is a way to instantiate this component in isolation and take an image screenshot of it and then compare it against the previous image screenshot.

And it turns out that such a thing already exists. Storybook is, the idea is you put individual components on a page, you control different things, different inputs on it, etc. And you take a image screenshot of this particular output to see how this thing is working. So let's install this.

Let's see, right? I believe we have to run a special command. Let's see, integration. So every framework will have a different way of doing this. Where`s Storybook? Okay, here we go. Let's run this command. So this installs the Storybook inside of our application. Now, this is specific to different frameworks will have different things.

This is not the important bit. Let's just go and install it. And more we're gonna talk about how we actually create a test. Basic idea of Storybook is, you have lots lots of components, like think of it like a design system in your application. And what you wanna do is you wanna be able to get each component up and running in isolation and then poke at it in isolation to kind of see if the right things are actually happening.

And because we are talking about a visual representation of what we want, really turns out that image snapshots are really the only good way to kinda prove that the thing looks like the way we intended it to look like. Because you could easily create a CSS change somewhere in the global style sheet which would affect the way your component renders.

Okay, now if I remember correctly, I believe I already have Storybook, okay? So now once we have this.
>> Quick just adds those scripts for you?
>> Yes, a lot of frameworks have a CLI that does kind of the setup for you Okay, so what does this look like?

In this case, this is just a demo test. We will add our own test in a second. But basic idea is that you have a button, and then in this particular case, you said, this is what the button should look like. And then in here, you can click on a button and you can come kind of interact with it to see if it kind of makes sense.

You can also go here and say medium, I think large. So you can get a large button, you can do small, right? So you can kind of prove to yourself that things are rendering the way you want. So let's create a test now for our cluster. What you wanna do is you wanna export.

And as a convention they call it the primary for a second. So, let's create different situations. Let's call the first one called square. And a square is going to be a story. And what is the story? Story is a story object which we import and it's gonna take cluster props.

And we have to create a default export so that the Storybook knows how to load this. And the component we're testing is cluster. Types I don't think you have to declare printables just empty think, and. Okay, so with this, we should be able to create a first story.

Let's create a super simple one. So for now, I am just going to say dataset. Dataset is. Right, so, let's just leave this empty for a second. I'll show you how to fill this in a second. And hopes args. And we want to have width. Width is 250 height is 250.

Let's say size is. And now we've created say, well how do we render this? And so we just going to create a cluster and this takes props. Okay, I know it's red, but I think we're gonna come back to it later. But I believe that that should be enough to, okay, maybe I have to restart this to pick it up What am I missing here?

source components? Right, because the default places source components, right? For whatever reason we did not put our component in the right location, and I think it is in Storybook Main. And we just say anything, not just components. It has to be restarted. Here we go, okay. So now we have our cluster.

And we have our default one called square and we can't really see it unless we flip the darkness. How do I do dark? It's not gonna show it. I have to have a data set. Okay, I think I have to have a data set. I'm not gonna escape this.

Cluster storage, okay, so let's do the data set. So we need to come up with clusters. And we could do it manually or remember we already have this function that does the clustering, right? So if we could just push in data into it. So we can say we want to put in a square data, and let's do the parameters of it actually here.

We can say const square, cluster 10, 2 are the parameters, and so now we have to pass in our longitude 0. So to make a square, right? You would do 0, 0, 0, not longitude, it's lng. You would make 0, 0, 0, 1, 1, and so those are four points in the corner, right?

And so now that we have this fed through the clustering, I can pass it to my data, and I should see the box. Here we go. So now this box is too big. Can I zoom out? Right, so we have a box now with four points. Notice just like when we were unit testing, we didn't want to do the real dataset.

Instead, we're making up our data set that is useful for us from testing perspective. Having four particular points in the space to be able to do that is useful. Does that make sense? So now the thing to do is to be able to maybe create other scenarios. So let's say we want to create a diagonal scenario.

So we have a square and let's create a diagonal. And maybe we want to create a smaller one, just to kind of prove that the sizing works. And so now we have to come up with a diagonal. Diagonal would be 001122, and maybe 33, right? So now notice we have the square, but I can also go to diagonal and prove that this particular thing works.

It seems a little squished, no? What did I mess up? Because I didn't do 200 here. Here we go. So we have a diagonal. So this is how you would test your items in isolation, eight? That are independent from everything else in your code base, right? Just like with unit tests, we were trying to isolate and not have to worry about the whole world, and we just wanna test one particular thing.

This particular thing would allow you to do the same thing in isolation as one. But the basic idea here of Storybook is that it allows you to treat your components as individual units, right? And because they're individual units, what you can do is, for example, here is our square, right?

And I can go, and I can modify. So if I go to the clusters, I can see that I have keys in here. And I can go, and I can actually modify these numbers. So I can decide that this is now 1. Maybe that was too much. Now this is 0.5.

If I could type 0.5, and I have actually moved the visual representation, right? So, it is a way for you to poke at your components in an isolated way, so that you can then assert the right UI happens. We can also so in this particular case, when we did our clustering.

The second cluster was distance ten. We can change the distance to one, and now if we go to the diagonals, the diagonals should be in different colors. Because, right, if I make it one, I have to say minimum cluster size, right? We have to say one. So now, it has each one is a separate dot write different colors.

Now we decided to break it into separate clusters, right? This also might be useful test for you. So the way you will taste UI components is in terms of visual representation rather than behavioral. I mean, you could do behavior as well. But in terms of visual, right? And again, you don't want to do a assertion on the whole page or whole application.

Or you don't want to do an assertion on the humongous data set like Iwouldn't want to assert on well it's not running right now, here I wouldn't want to assert on this because if something goes wrong or whatever it'd be super difficult to see. You want to assert on essentially the unit test kind of philosophy where it's very clear as to what is going inside and what's coming out of the system.

>> I thought I heard you say earlier that some of this, when you get to testing components in a visual way, it can be a bit more flaky. Is that more with integration tests or even something like this where you're just testing a single component at a time and single those snapshots.

>> So we should talk about where does flakiness come from? Flakiness usually comes from the network. So if you're actually talking to the outside world, whether it's database or something like that, you could in theory have flakiness, right? And usually the way flakiness are dealt with is that You do retries and exponential back off so you wait and try again see if it kind of works out.

And usually these frameworks have a built in, but at some point you will encounter the fact that like, things just don't pass for whatever reason. Stuff like Storybook because there really is no network, right? It's all integrated together into one page where the components are instantiated, the data is fixed, etc.

This should have extremely low flakiness. It probably still might have flakiness because it still requires that a browser be brought up. It still requires that something like Playwright would sit on top of it and try to poke on it and interact with it. And all of that, those require that you have some behavioral changes.

But it should be pretty low in terms of flakiness. So I would expect this to be almost no flakiness, whereas if you do an end-to-end test of your application, it'd probably be a lot more flaky.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now