πŸ’‘ This page contain affiliate links. By making a purchase through them, we may earn a commission at no extra cost to you.
How to Get Up and Running With Vitest

How to Get Up and Running With Vitest

Learn how to write your first unit tests with Vitest
Ferenc Almasi β€’ 2022 August 01 β€’ Read time 8 min read
Learn how you can configure and get up and running with Vitest by Vite to unit test your frontend application.
  • twitter
  • facebook

Vitest, the unit test framework powered by Vite shares many similarities with Jest. On the other hand, it offers much more and improves on it. Vitest is built on top of the Jest API, so if you already know how to work with Jest, you will know how to work with Vitest too.

This not only makes the learning curve very shallow but also helps ease the migration process in case you would like to switch from Jest to Vitest. But why Vitest in the first place? Let's take a look at some of the features of Vitest to see what it has to offer, then we will see how you can get up and running with Vitest.


Features of Vitest

First and foremost, Vitest is compatible with Jest, which means most of your existing unit tests will work with Vitest too. It uses the same API meaning you don't have to learn new ways of writing unit tests.

Apart from the similarity it shares with the Jest API, it comes with a handful of improvements on top of Jest which could make it a better choice:

  • Performance: Vitest is built on top of Vite. It uses multi-threading workers, allowing tests to run simultaneously. This makes it faster to execute tests compared to Jest.
  • Configuration: Configuration happens using a vite.config file, which can also be used to configure other aspects of your project. This means you can configure both your code, and your test suite from a single source.
  • Supports: It supports TypeScript and JSX out of the box. It also supports using import statements, which is not something that you can do in Jest out of the box. It also supports top-level await, as well as code coverage which we will look into how to do.

Writing Your First Unit Tests Using Vitest

To get up and running with Vitest, you first need to have a Vite project. In case you already have one, you can jump to the next section. In case you don't have one, you can create a new one using the following command:

npm create vite .

This will initiate a new Vite project in the current directory. You also have the option to choose the following frameworks when bootstrapping Vite:

> vanilla
- vue
- react
- preact
- lit
- svelte

In this tutorial, we are going to go with a vanilla project. During the setup, you can also choose to set up TypeScript along with your Vite project. After your project is bootstrapped, don't forget to run npm i to install all dependencies.

Installing and using Vitest

Once you have a Vite project ready, you will also need to install Vitest as a dev dependency.

npm i --save-dev vitest

Notice that Vitest is still under version 1.x. This means breaking changes might be expected.

Now that we have all the required dependencies installed, it's time to create a test file to start writing some unit test cases. Create a new test file somewhere in your project's folder and add the following:

Copied to clipboard! Playground
import sum from './sum'
import { describe, it, expect } from 'vitest'

describe('sum', () => {
    it('Should sum two numbers together', () => {
        expect(sum(3, 3)).toBe(6)
    })
})
vitest.test.ts
Testing a sum function with Vitest

The very first thing you may notice is that in Vitest, we need to import the different building blocks of a unit test. Other than that, the syntax is more or less the same as Jest.

To run the test, open your package.json file and create a new test command in your scripts object.

Copied to clipboard!
{
    "scripts": {
        ...
        "test": "vitest"
    }
}
package.json
Create a new command in your package.json to run Vitest

Now you can call npm run test to execute Vitest to run your tests. This will run Vitests in watch mode, meaning you can make some changes to your unit tests, save the file, and Vitest will rerun your test suite.

The good thing? If you have multiple test files (which you will likely have), Vitest will only execute the file that is changed, so no need to wait for all the other tests to pass. To perform a single run without watch mode, you can change your test script to call vitest run.

Copied to clipboard!
{
    "scripts": {
        ...
        "test": "vitest run"
    }
}
Use "vitest run" if you want to execute Vitest in your CI

Apart from the Jest compatible APIs, Vitest also has Chai built-in for assertions, as well as jsdom for DOM mocking. All of this makes it super easy to migrate your test suite from Jest to Vitest.

Looking to improve your skills? Master Jest from start to finish.
Master Jestinfo Remove ads

In-source Testing

Another great feature of Vitest is in-source testing. In-source testing lets you write your test cases right next to your functions. Let's see how the above example can be translated to in-source testing.

First, you will need to move your unit test underneath your exported function, and wrap it in the following if statement:

Copied to clipboard! Playground
import { describe, it, expect } from 'vitest'

export const sum = (a: number, b: number): number => a + b

if (import.meta.vitest) {
    describe('sum', () => {
        it('Should sum two numbers together', () => {
            expect(sum(2, 2)).toBe(4)
        })
    })
}
sum.ts
In-source testing in Vitest

This check will tell Vite to only run the code if we are executing Vitest. So the part inside the if statement will only be executed if we are running the code from the unit test suite. Now using this approach we will run into three problems:

  • As this is not a test file, Vitest will be unable to find the test
  • The code will be bundled into the final app
  • If you are using TypeScript, you will get a type error for meta.vitest

Luckily, all three of them can be resolved relatively easily. To let Vitest find the test, we need to modify our vite.config file. Inside your vite.config, add the following to your defineConfig call.

Copied to clipboard! Playground
import { defineConfig } from 'vitest/config'

export default defineConfig({
    test: {
        includeSource: ['**/*.ts']
    }
})
vite.config.ts
Add includeSource to your vite.config file

This will tell Vitest to look for tests in files ending with .ts. By default, it will only look for tests in files with a .test.extension or .spec.extension ending. To ensure that the test code is not included in the final bundle, we can extend the config with the following lines:

Copied to clipboard!
import { defineConfig } from 'vitest/config'

export default defineConfig({
+   define: {
+       'import.meta.vitest': 'undefined'
+   },
    test: {
        includeSource: ['**/*.ts']
    }
})
vite.config.ts

This will ensure that import.meta.vitest will always be skipped for production builds. Last but not least, to fix type errors related to import.meta.vitest, we need to modify tsconfig.json with an extended type.

Copied to clipboard!
"types": [
    "vitest/importMeta"
]
tsconfig.json
Add the type to your tsconfig file to avoid type errors with Vitest during in-source testing

Test Coverage Reports Using Vitest

Vitest supports generating test coverage out of the box. It requires c8 as a dependency, so in case you don't have it installed, run npm i --save-dev c8. Vitest will also prompt you to install it during the first coverage run. To create a coverage report, run vitest --coverage. This will generate a report into your terminal.

Vitest coverage report shown inside the terminal
Coverage report shown inside the terminal

In case you want to work with a coverage report represented by HTML, you can add the following config to your vite.config file.

Copied to clipboard! Playground
import { defineConfig } from 'vitest/config'

export default defineConfig({
    test: {
        coverage: {
            reporter: ['text', 'html']
        }
    }
})

This will generate a coverage folder at the root of your project, where you can find an index.html report file for your code coverage, that is generated using Istanbul.

100 JavaScript Project Ideas

Summary

In summary, Vitest provides various improvements on top of Jest. Its similar API to Jest makes it very easy to migrate your unit tests. Its single configuration file lets you configure both your app and your unit test suite from one place. Its implementation lets you execute your test suite faster compared to Jest.

Have you already worked with Vitest before? Let us know your thoughts on it in the comments below! Want to learn more about unit testing? Check out our tutorials below on how to achieve various test scenarios in Jest. Thank you for reading through, happy testing!

100 JavaScript Project Ideas
  • twitter
  • facebook
Did you find this page helpful?
πŸ“š More Webtips
Mentoring

Rocket Launch Your Career

Speed up your learning progress with our mentorship program. Join as a mentee to unlock the full potential of Webtips and get a personalized learning experience by experts to master the following frontend technologies:

Courses

Recommended

This site uses cookies We use cookies to understand visitors and create a better experience for you. By clicking on "Accept", you accept its use. To find out more, please see our privacy policy.