In this lesson, we'll use vue-testing-library along with Jest to write some integration tests for a Counter component. What's nice about the vue-testing-library and it's equivalents like dom-testing-library and react-testing-library is that it has several functions to retrieve and assert on elements like a user would when interacting with your application.
When a user clicks a button, they're not clicking on a CSS class (as some testing libraries suggest), they're clicking on a button labeled "Increment". The user doesn't know about the implementation details, so testing an app this way makes sense. We'll look at several of the getBy* functions vue-testing-library offers to test our component.
Additional Resources:
https://blog.kentcdodds.com/introducing-the-react-testing-library-e3a274307e65?gi=2b3d25b4f1cd
https://github.com/dfcook/vue-testing-library
Instructor: [00:00] I have a counter component that I've created with Vue, that increments and decrements by a multiplier. In this case, it increments by four, decrements by four, and has a reset button.
[00:10] If we look at the actual component code, you can see that I'm using the template syntax and that I have an area to show my counter and increments, decrements, and reset button. This component accepts one property called multiplier and has a default of one, but in this case, I'm passing four.
[00:25] We also have a count property to keep track of state. Our methods include increment, decrement, and reset. When you click the increment button, we increase the state of count by one. Decrement, you decrease it by one. The reset button sets it back to zero.
[00:39] I also have a computed property called multiplierCount that takes the current state of count and multiplies it by the multiplier that were passed in.
[00:50] What I want to do for this particular lesson is write an integration test using vue-testing-library. I've set up this little project using the Vue CLI, which comes with a default setting for Jest.
[01:00] In fact, I've already written a few unit tests for this particular component in a previous lesson. In order to write integration tests for this particular lesson, we're going to use vue-testing-library, so we need to install that.
[01:12] I can do that by running yarn add vue-testing-library. Now that that's installed, the next thing I'm going to do is add another folder for my integration test. As you can see, there's already a unit folder that came with Vue CLI, but I'm going to create one called integration.
[01:29] I'm also going to copy the eslintrc file that comes with the unit directory. We'll throw this in here. This just keeps ESLint happy for all the globals that we need to add through Jest like it, int, expect, and things like that.
[01:41] There's one last thing that we need to do. We need to let Jest know where our integration tests are at. We can do this by modifying the jest-config file and add a line for the integration directory we just created.
[01:52] You don't have to separate your integration from your unit test. A lot of times, people combine them. For this particular project, I'm separating them for clarity.
[02:01] Let's write some tests. The first thing I'm going to need to do is add a new test file called counter-spec.js. Since this lesson is about the vue-testing-library, let's import a couple things from it.
[02:12] We'll say, "Import render simulate from vue-testing-library." We'll also need to import our counter, of course. I'll write a describe block. The first thing I like to test is to see whether the component renders or not. We can say, "It renders component."
[02:33] The way that we render a component using the vue-testing-library is using the render function that we've imported. Render will return a mounted version of our component, along with a couple utility functions for our assertions.
[02:47] One such function is called getByText, which we can use to find text anywhere within the component to check whether it's visible and has a value.
[02:55] What's really awesome about the vue-testing-library and any of the associated versions -- like dom-testing-library or react-testing-library -- is that it uses these getBy functions to retrieve DOM elements more like a user would do when interacting with your application.
[03:08] Users aren't clicking on a CSS class. They're clicking on a button labeled "Increment." There are several of these getBy functions, getByText, getByLabel, getByPlaceholder, and getByTestId.
[03:20] In this particular test, I've simulated a click on an element that has the text of "Increments," which is our increment button and asserting there is an element with a value of one. I can actually clean this up a bit by removing the textContent property and the toBe method to just test whether the element exists.
[03:39] Next, to test the decrement button. We'll paste this here, change this to decrements. We'll say, "-1." Test. All right, good.
[03:49] Next, to test out the reset button. We'll copy this again. We'll say, "Resets counter back to 0on click." Change this to reset. We'll change this back to zero.
[04:06] The last thing I want to test is my multiplierComputed property. Let's go ahead and copy this. We'll say, "Multiplier increases on click." We'll need to pass a prop to our counter component.
[04:20] We can do that by adding a second argument to the render function. We'll say, "Props multiplier 4." We'll change resets to increments. We'll change zero to four. Let's test this.
[04:34] Now to test our decrement button again. We'll change this to decrements. I just noticed right here it's not increases, but increments and decrements. We'll say, "-4." Run our test.
[04:55] You may have noticed that our getByText assertions are a little general, and that they look for elements containing text like "0or "-1" or "4." We can make these more specific by adding a test ID to our counter output and look for that instead.
[05:11] Wherever I'm retrieving the count output by text, I can use getByTestId and pass the ID of my DOM element instead. If you read the testing library documentation, retrieving the element by test ID should be one of your last options, as it's not representative of how the user interacts with your application.
[05:30] There are some cases like this where it makes sense. Again, the main reason this library was invented was to allow you to test your application in a manner that's a little closer to how your users actually use it.
[05:42] Just a few more adjustments. It looks like the tests are green. We can now sleep at night knowing our counter component is indeed working.
[05:55] I hope this helps lay a foundation for what makes vue-testing-library and its equivalents so awesome.
Member comments are a way for members to communicate, interact, and ask questions about a lesson.
The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io
Be on-Topic
Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.
Avoid meta-discussion
Code Problems?
Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context
Details and Context
Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!