Setting up a superfast CI with Vitest and GitHub Actions

Setting up a superfast CI with Vitest and GitHub ActionsIn this article, I want to show you what a CI does and how to set it up. The scope of this article is not only limited to vitest, this works also for other test runners like jest.
Categoriestesting vite vitestdevHack devtools javaScript
Date
2022-04-29
Hire me on Upwork!

What is GitHub Actions?

I think nobody could describe it better than GitHub itself in its official docs.

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production.

GitHub Actions goes beyond just DevOps and lets you run workflows when other events happen in your repository. For example, you can run a workflow to automatically add the appropriate labels whenever someone creates a new issue in your repository.

GitHub provides Linux, Windows, and macOS virtual machines to run your workflows, or you can host your own self-hosted runners in your own data center or cloud infrastructure.

So when you are already using GitHub to manage your source code, it is the easiest way to also make your CI there and not add another tool to your process.

Setting up GitHub actions is also an easy task, basically it is just another file in your codebase and GitHub guides you through the setup process. You just need to know what to do.

You just need to know what to do

But don't worry, this is what this article is about.

What is Vitest?

if(vitestKnowlege)
	continue;
else
	this.read;

When you are reading this, you probably have already heard of Vite (french for Quick).

Vite is an amazing build tool developed by Evan You, Anthony Fu, patak and 533 more amazing developers. Vite is build to save you time and increase your developers experience by lots of incredible features like Rollup builds and superfast HMR by serving files via native ES modules.

Jest and some other state of the art test runners were having problems with vite the core team also decided to come up with an own test runner called vitest. Vitest is build with the developers in mind and therefore provides a breathtaking developer experience. It is easy to set up since it reuses the vite.config.js you already have and is also superfast.

I talk a bit deeper about vitest and its UI in this article.

If you want to learn more about the Vite ecosystem, here is an interesting article from patak for you.

Why Should I Use a CI?

Let's first start talking about the sake of a Continuous integration (CI) and Continuous Delivery (CD).

You are using CI/CD systems because you want to ship smaller features continuously during your iterations instead of just shipping on huge update every few months.

Using a CI reduces the risk of breaking huge parts of your codebase. You just can break tiny parts, which is much easier to fix, since you know what feature caused the problem. It is also easy to roll back this changes when you have just small incremental steps till this issue is fixed.

Another advantage of CI is that you can include your tests into this CI systems, which means that you can run your tests on every commit on a specific branch (master, Deploy or whatever you want to ship). Every time when you commit or merge on master, the tests will be executed before deploying the application. If the tests fail, the deployment process will abort and the tests needs to pass before you are allowed to ship this feature.

To summarize, using a CI will significantly improve your codes quality and reduces the time for testing and shipping. So it is a complete Win for you and your users. The only things you need to do is writing tests (which you generally should do) and setting up an CI on your platform of choice.

I will guide you now through the steps on setting up a CI with GitHub Actions.

How to set up a CI with Vitest and GitHub Actions?

1. Go to GitHub actions and chose the node.js template

github actions templates

You will see an empty template

GitHub Actions example

You can give it a meaning full name in line 4.

2. Chose a branch to execute.

In line 8 you now should define the branches where these Actions should be executed.

In line 10 you can also define branches where the actions should be executed after an PR. This gives the developer reviewing the PR already a Test report to see if all tests were passing.

If you leave everything on master, it will look like below.

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

3. Chose your node version.

Since vite just work on node ≥ 14 I recommend using node 16.x. This is the latest node LTS version, where everything should work.

node-version: [16.x]

4. Install your dependencies.

To Install your dependencies, you can either run npm install or npm ci

What is the difference between NPM Install and NPM CI?

Npm install is made to be used on the developer's machine. It reads the package.json and checks if it is already in package-lock.json. If not, it will be added and installed. If yes, it will get the defined version out of package-lock and install this version if it is not already installed.

Npm CI (Clean Install) is made to run in automated environments like our CI and give us a clean deterministic state to run the tests on.

Npm CI never edits package.json or package-lock.json. Before installing, it will delete all node-modules. Then all dependencies will directly be installed from package-lock.json and package.json is only used for cross-checking. If a dependency is not in package-lock.json it will not add it and throw an error instead.

5. Run your Unit tests.

After everything is installed, we can finally run our Unit tests. 🥳

If you have multiple types of tests (Unit and e2e) in place, you need different comments to start vite and cypress.

To do so, go to your package.json and edit the test line, like I did here.

"test:unit": "vitest"

This will run our Unit tests using vitest.

Inside GitHub Actions, then simply run

npm run test:unit

Vitest will automatically recognize that you are in a CI and will only run once and not watch for code changes!

6. (Optional) Deploy

As a last step, you can deploy your application to Azure Static or any other hosting provider.

Since this commands strongly differs for the different providers and services you want to host on, I would recommend you to check out their guides.

Azure Static for example provides you an own GitHub action to deploy it to their service.

You then can just take the test steps from this article and add it before the build and deploy steps to test everything before it gets deployed.

      - name: Execute Unit tests
      - run: npm ci
	    - run: npm run test:unit

The resulting GitHub Actions file to run Vitest

# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions

name: Runs All Unit tests

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

    steps:
      - uses: actions/checkout@v3
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: "npm"
      #- run: npm run build --if-present
      - name: Execute Unit tests
      - run: npm ci
	    - run: npm run test:unit

Running the CI inside GitHub Actions

GitHub Actions Vitest results

After everything is set up, GitHub actions will run your tests after each time you pushed something in your branch.

For a failing run, you can see the step where the pipeline has failed.

GitHub Actions Vitest error

When expanding this pipeline, you will see the same output as you are seeing when you are running vitest in your console.

GitHub Actions Vitest output

So you see why these tests were failing and how many files were affected.

For this case, I uninstalled this package and forgot updating my tests before pushing. I now directly get an Email notification when something like this happens and can directly see what I messed up with my last commit. Therefore, I can catch errors before they reach the Users or in this case confuses my coworkers.

If you are going to resolve it, I recommend using Vitest UI to get a live overview on your test results.

I wrote an article about it here.

Disclaimer

Vitest is currently still in beta, therefore even if it's working great already you can encounter bugs and issues. I would not recommend using it in Production till a stable release is out. But I encourage you to try it out and have everything in place when a stable version is released.

Conclusion

I hope I could help you to set up your Ci and therefore improving your code Quality. The concepts you learned i n this article is not only limited to vitest and GitHub actions. Most CI tools have a similar syntax and similar concepts. Same for test runners.

Since Vitest is also pretty new for me, I will update this article frequently and add also new Articles when I'm trying out new features of Vitest.

If you want to stay up to date, you can follow me on Twitter.

If you want to support me and the work I’m doing, you can buy me a coffee.

Happy, coding asserting,

Alex

Recommended Products for you
recommended for you