DEV Community

Marabesi
Marabesi

Posted on • Edited on • Originally published at marabesi.com

Configuring vitest and testing library to work together - step by step guide

The javascript ecosystem provides a variety of tools and frameworks that sometimes require some configuration dancing to work together.

Jest has been the dominating player for running javascript tests, it provides a end-to-end experience in regards of features, for example, you don't need to configure a test runner and also the assertion library. Even though, such thing is possible to do if needed.

Jest works across libraries and frameworks, React packs Jest into automatically when creating a project using Create-React-App.

Besides, Jest also works with applications that are run in the server side.

Such popularity was questioned by vitest, an alternative to Jest, that is focused in speed.

Vitest was born from vuejs ecosystem and rapidly started to evolve to other communities, such evolution, leads to a friction when migrating or even when trying to make tools to work together.

In Jest, testing-library works automatically, no much effort needs to be done. On the other hand, trying to combine, testing library and vite, might bring some challenges.

The aim here is to go step-by-step to configure vite and testing-library in an environment that uses typescript.

The project

To start with, let's create a project with create-vue, executing the following command should create a brand new project:

npm create vue@3 create && \
  cd vitest-testing-library && \
  npm i
Enter fullscreen mode Exit fullscreen mode

This command will issue an interactive terminal to fill in some relevant information for the project, the following options were used:

Options used to create the vuejs application through create-vue

Using create-vue jump a few steps in the way to configure vuejs and vitest. Setting up vitest in an already existing
vuejs application requires a different approach.

To make sure that the requirements are in place before moving to the next section run the test suite with the following npm script:

npm run test:unit
Enter fullscreen mode Exit fullscreen mode

The output should be green, indicating that the test passed, as the following image depicts:

Output vitest execution

Why testing library

If you are like me, the ideal test is the one that is not coupled with my production code allowing me to refactor and improve the code as much as I want without even worrying about the test.

Opposed to testing library, vue testing utils expose the internals of a component, and this scenario is depicted in the test file that comes with the project we just created.

describe('HelloWorld', () => {
  it('renders properly', () => {
    const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
    expect(wrapper.text()).toContain('Hello Vitest')
  })
})
Enter fullscreen mode Exit fullscreen mode

Anytime I change the props, to something else that is not msg I will have to update my test file, which is not desired, I haven't changed any behavior to break my tests, such change should not be needed.

Testing library allow the test to reflect what the user will do when interacting with the application, rather then focusing on component implementation such as props.

Testing library became popular within react ecosystem, but it was adopted by others as its benefits and philosophy supports evolution of applications as the one described.

Installing testing library

The version 3 of vuejs requires installing a different package from vuejs 2 as the official documentation depicts. As in the previous step was used vue 3, the following command is needed in order to install testing library:

npm install --save-dev @testing-library/vue
Enter fullscreen mode Exit fullscreen mode

Once Installed, the library will allow us to convert the previous test case to something to the following:

it('renders properly', () => {
  const {getByText} = render(HelloWorld)
  expect(getByText('Hello Vitest')).toBeInTheDocument();
})
Enter fullscreen mode Exit fullscreen mode

Doing so and trying to execute the test suite will lead to a different problem, now, vitest complains that it cannot understand toBeInTheDocument, as the following image depicts:

Error faced by vitest when using a matcher that is not <br>
supported

Which makes sense. This is a matcher from Jest that vitest does not support, fixing that was shown already by
this blog post, which installs the jest-dom package and extends the vitest matchers.

Error: Invalid Chai property: toBeInTheDocument

The next step to fix this issue is to install the package @testing-library/jest-dom that adds the matchers used
by jest in our project, to accomplish that the following command should be executed:

npm install --save-dev @testing-library/jest-dom
Enter fullscreen mode Exit fullscreen mode

Then, the matcher can be exposed to vitest. Exposing the matchers to vitest happens through extending the vitest matchers, Markus recommended to create a file named setup.ts* under the folder test, inside src, with the following content:

import matchers from '@testing-library/jest-dom/matchers';
import { expect } from 'vitest';

expect.extend(matchers);
Enter fullscreen mode Exit fullscreen mode

With this file in place, the next step is to inform vitest to use this file and load that up before the test run. Informing
vitest about the setup.ts file is as simple as adding it in the configuration file vite.config.ts.

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vitest'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  // ===============================================
  // ===============================================
  // Add the live above to the configuration, it will inform vitest to use the file.
  test: {
    setupFiles: ['test/setup.ts']
  }
})
Enter fullscreen mode Exit fullscreen mode

TS2345 'test' does not exist in type 'UserConfigExport' - Issues with type script

You might also face an issue with types in typescript when trying to add the key test in the configuration,
the error is similar to the following:

TS2345: Argument of type '{ plugins: Plugin_2[]; resolve: { alias: { '@': string; }; }; test: { setupFiles: string[]; }; }' is not assignable to parameter of type 'UserConfigExport'.   Object literal may only specify known properties, and 'test' does not exist in type 'UserConfigExport'.
Enter fullscreen mode Exit fullscreen mode

The fix is to replace the typed configuration from vite to vitest:

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vitest/config' // <!------ This is the fix
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  // ===============================================
  // ===============================================
  // Add the live above to the configuration, it will inform vitest to use the file.
  test: {
    setupFiles: ['test/setup.ts']
  }
})
Enter fullscreen mode Exit fullscreen mode

With that in place the test should be back to green again, the configuration, in the execution point of view is done.

TS2339: Property 'toBeInTheDocument' does not exist on type 'Assertion ' - Fixing assertions type

The last bit of this configuration left is to share the types that jest has to use with testing library, this is needed
because at this point in time, the project should be giving the following error when trying to build with npm run build or opening it in an IDE or text editor.

The following image depicts the error when trying to build:

Typescript error building the application

Fortunately, the trick to fix this issue is adding the types that jest also uses.

To start fixing this, run the following command in the terminal:

npm i --save-dev @types/testing-library__jest-dom 
Enter fullscreen mode Exit fullscreen mode

With the types installed, the next step is to share them with vitest. The file that is responsible for that is in the root of the project and is named tsconfig.vitest.json, opening the file, should give the following content:

{
  "extends": "./tsconfig.app.json",
  "exclude": [],
  "compilerOptions": {
    "composite": true,
    "lib": [],
    "types": ["node", "jsdom"]
  }
}
Enter fullscreen mode Exit fullscreen mode

The key that we are interested in is the last one, under compileOptions named types. Types is the place that we can give vitest the hint of the types we are using. The step missing is the one to add the type @types/testing-library__jest-dom there.

In the end, the file tsconfig.vitest.json should be as the following:

{
  "extends": "./tsconfig.app.json",
  "exclude": [],
  "compilerOptions": {
    "composite": true,
    "lib": [],
    "types": ["node", "jsdom", "@types/testing-library__jest-dom"] // <------ we added this last type
  }
}
Enter fullscreen mode Exit fullscreen mode

Running the command npm run build again should give the desired output, building the application without problems. The following image depicts the successful run of the build command.

Success output running the build command

Top comments (0)