Svelte 整合 vitest
tags: Svelte
Testing
category: Front-End
description: Svelte 整合 vitest
created_at: 2023/04/07 02:00:00
事前準備
- 裝好
Node.js
前言
在使用 SvelteKit
建立專案時雖然有問你要不要用 Vitest
去做測試,不過感覺給的不夠誠意,所以誕生了這篇文章。
記得先照著 Svelte 開新專案與環境設定 並且記得至少勾選 Vitest
來建立專案。
原本的長相
看看原本的提供的 src/index.test.ts
,長的像下面這樣
import { describe, it, expect } from 'vitest';
describe('sum test', () => {
it('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3);
});
});
好...啦,真的很 Unit test
,但是我會想用應該都是想測組件(Component
)啊,總不會整個 App
都只有很純的單元測試吧,這樣可靠度感覺不太妙
像是在 Vue
預設還會給你這些:
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import HelloWorld from '../HelloWorld.vue'
describe('HelloWorld', () => {
it('renders properly', () => {
const wrapper = mount(HelloWorld, { props: { msg: 'Hello Vitest' } })
expect(wrapper.text()).toContain('Hello Vitest')
})
})
感覺有誠意多了
至少這樣知道怎麼把 Component
掛上去,然後做一些 expect
去測試。
加入 testing-library
之前寫 React
的話可能會對這個測試工具比較熟悉(如果是create-react-app
的話),用 Vue3
的就不一定了(因為我覺得 Vue3
提供的 test-utils
就滿好用的了)。
總之 testing-library
也有提供 Svelte
,所以可以裝來使用。
$ npm i -D @testing-library/svelte
然後因為我們執行 test
是在 Node
環境,在這個環境下沒有 DOM
,所以也需要安裝 jsdom
去模擬。
$npm i -D jsdom
安裝好 jsdom
之後,要記得加入 vite.config.ts
設定。
vite.config.ts
// ...
export default defineConfig({
// ...
test: {
include: ['src/**/*.{test,spec}.{js,ts}'],
environment: 'jsdom' // <-- 主要是這行
}
});
再來就可以去修改 src/index.test.ts
:
import { test } from 'vitest';
import { render } from '@testing-library/svelte';
import Page from './routes/+page.svelte';
test('test page', () => {
const page = render(Page);
console.log(page);
});
然後執行測試看看有沒有問題
$ npm run test:unit
沒意外會看到 1 passed
且印出一堆可用的函數,就完成了。
如果還是不放心,可以改成下面這一段去測試
test('test page', () => {
const page = render(Page);
page.getByText('Welcome to SvelteKit');
});
理論上,如果你的 page.svelte
還是長下面這樣的話,測試就會通過,因為它存在一個元素的文字是 Welcome to SvelteKit
<h1>Welcome to SvelteKit</h1>
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
還是不放心,就把內容改掉,例如
<h1>Welcome to SvelteKit!!</h1>
你馬上就會得到 1 failed
的結果。
其他方便的設定
可以在 vite.config.ts
加入一個 globals
設定,這樣就不用在每一個測試的程式最上面 import {...} from 'vitest'
了
// ...
export default defineConfig({
// ...
test: {
// ...
globals: true // <-- 加入這個
}
});
這時你的 index.test.ts
就可以拿掉關於 vitest
的 import
了,如下:
import { render } from '@testing-library/svelte';
import Page from './routes/+page.svelte';
test('test page', () => {
const page = render(Page);
page.getByText('Welcome to SvelteKit!!');
});
這時因為你改了設定檔,所以你可能需要重新跑測試的指令,重新跑一次 npm run test:unit
應該一樣會看到正常運作。
但這時又會引發另一個問題(如果你的 lint
正常的話),發現 Cannot find name 'test'.
一長串的錯誤,這時只要去修改 tsconfig.json
(如果你使用 TypeScript
的話):
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
// ...
"types": [
"vitest/globals" // <-- 加入這個設定
]
}
}
到這邊就設定完成了。
提醒: 建議還是使用 TypeScript
再使用 globals
設定,至少再我當下測 jsconfig.json
加上 types
設定一樣會噴 is not defined.
,反正每個檔案上面加一行也沒多麻煩,但也說不定未來哪天就忽然解決了,所以也不一定會碰到這問題。
總結
依照慣例,上面這種重複的事情交給我幫你做就好,可以使用 lai-cmd
幫助你快速設完(就算不成功至少你可以手動貼,不用再花時間查文件)
$ npx lai-cmd@latest init svelte-testing
順便打廣告: 如果你是全新專案想要一次弄好多個環境,也可以只下
$ npx lai-cmd@latest init svelte
他會問你要不要 eslint
、prettier
、tailwindcss
、testing
...等等。