DEV Community

Cover image for How to test Svelte components
Tim Deschryver
Tim Deschryver

Posted on • Originally published at timdeschryver.dev

How to test Svelte components

Follow me on Twitter at @tim_deschryver | Originally published on timdeschryver.dev.


I've been looking into Svelte, and while most of the info that I'm looking for can be found in the documentation, there's one piece missing. There's no section on how to test components, so I went to explore this area.

The first place where I was looking, was the Svelte repository itself. It contains tests that seem simple at first, like this one. The only problem that I have, is that it requires me to orchestrate the test setup.

After taking a look at the Svelte repository, I quickly came across the Svelte Testing Library. I'm the creator of the Angular Testing Library, and because of the Testing Library has a similar API across all frameworks, I was quickly used to it.

Jest Setup

Writing tests with the Svelte Testing Library can be done with all test, in this article I'm using Jest.

The first step is to install the dependencies:

npm install @babel/core @babel/preset-env jest babel-jest svelte-jester -D
Enter fullscreen mode Exit fullscreen mode

The Babel compiler has to be installed to use the ES6 syntax while writing tests.
To compile Svelte components, it's also needed to install svelte-jester.

After the installation is complete, Jest and Babel have to be configured.

To configure Jest, create a jest.config.js file in the root of the project.

module.exports = {
  transform: {
    '^.+\\.svelte$': 'svelte-jester',
    '^.+\\.js$': 'babel-jest',
  },
  moduleFileExtensions: ['js', 'svelte'],
}
Enter fullscreen mode Exit fullscreen mode

For Babel, create a babel.config.js file in the root of the project.

module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: {
          node: 'current',
        },
      },
    ],
  ],
}
Enter fullscreen mode Exit fullscreen mode

The last step of the setup is to add a script inside the package.json file:

{
  "name": "svelte-counter",
  "version": "1.0.0",
  "scripts": {
    "build": "rollup -c",
    "dev": "rollup -c -w",
    "start": "sirv public",
    "test": "jest"
  },
  "devDependencies": {
    "@babel/core": "^7.8.3",
    "@babel/preset-env": "^7.8.3",
    "@rollup/plugin-commonjs": "^11.0.0",
    "@rollup/plugin-node-resolve": "^7.0.0",
    "@testing-library/svelte": "^1.11.0",
    "babel-jest": "^25.1.0",
    "jest": "^25.1.0",
    "rollup": "^1.20.0",
    "rollup-plugin-livereload": "^1.0.0",
    "rollup-plugin-svelte": "^5.0.3",
    "rollup-plugin-terser": "^5.1.2",
    "svelte": "^3.0.0",
    "svelte-jester": "^1.0.3"
  },
  "dependencies": {
    "sirv-cli": "^0.4.4"
  }
}
Enter fullscreen mode Exit fullscreen mode

Svelte Testing Library Setup

To use the Svelte Testing Library, the @testing-library/svelte package has to be installed.

npm install @testing-library/svelte --D
Enter fullscreen mode Exit fullscreen mode

Writing a test

After all the setup, we can start writing tests.

The test will look familiar to you if you've already used a Testing Library.

  • to create the component, use the render method
  • to interact with the component, use the get(All)By and query(All)By methods, and the methods on fireEvent
  • as a bonus, use the jest-dom matchers
import Counter from './Counter.svelte'
import { render, fireEvent } from '@testing-library/svelte'

it('it works', async () => {
  const { getByText, getByTestId } = render(Counter)

  const increment = getByText('increment')
  const decrement = getByText('decrement')
  const counter = getByTestId('counter-value')

  await fireEvent.click(increment)
  await fireEvent.click(increment)
  await fireEvent.click(increment)
  await fireEvent.click(decrement)

  expect(counter.textContent).toBe('2')

  // with jest-dom
  expect(counter).toHaveTextContent('2')
})
Enter fullscreen mode Exit fullscreen mode

To pass props to a component, make use of the Component Options

import Counter from './Counter.svelte'
import { render, fireEvent } from '@testing-library/svelte'

it('it works', async () => {
  const { getByText, getByTestId } = render(Counter, {
    value: 10,
  })

  const increment = getByText('increment')
  const decrement = getByText('decrement')
  const counter = getByTestId('counter-value')

  await fireEvent.click(increment)
  await fireEvent.click(increment)
  await fireEvent.click(increment)
  await fireEvent.click(decrement)

  expect(counter.textContent).toBe('12')

  // with jest-dom
  expect(counter).toHaveTextContent('12')
})
Enter fullscreen mode Exit fullscreen mode

Running tests

Everything is set, and now we can finally run the tests.
Run the following command:

npm run test
Enter fullscreen mode Exit fullscreen mode

Follow me on Twitter at @tim_deschryver | Originally published on timdeschryver.dev.

Top comments (4)

Collapse
 
wakeupmh profile image
Marcos Henrique

Awesome post

Collapse
 
timdeschryver profile image
Tim Deschryver

Thanks Marcos!

Collapse
 
wakeupmh profile image
Marcos Henrique

I've been looking for posts about it, yours was very concise and objective, congratulations on the initiative

Thread Thread
 
timdeschryver profile image
Tim Deschryver

Yep, that was the main reason why I wrote it - there's little to none information about it