Vitest
Unit tests
Using Vitest for unit tests should work out of the box.
By default, Vike's Vite plugin isn't loaded when running Vitest.
This is because Vitest is typically used for unit tests, where Vike's Vite plugin doesn't add any value. For that reason, Vike's Vite plugin removes itself when it detects Vitest.
If you do want Vike's Vite plugin to be loaded, use Vike's JavaScript API (Vike's Vite plugin won't remove itself then) — see With Vike (e2e).
With Vike (e2e)
If you want to use Vitest to test your whole Vike app (typically for end-to-end tests), use Vike's JavaScript API:
// dev.spec.js
import { afterAll, beforeAll } from 'vitest'
import { testApp, viteConfig } from './testApp'
import { dev } from 'vike/api'
let viteServer
beforeAll(async () => {
const { viteServer } = await dev({ viteConfig })
await viteServer.listen()
await sleep(10) // avoid race condition of server not actually being ready
}, 10 * 1000)
afterAll(async () => {
await viteServer.close()
})
testApp()
function sleep(milliseconds) {
return new Promise((r) => setTimeout(r, milliseconds))
}
// dev.spec.ts
import { afterAll, beforeAll } from 'vitest'
import { testApp, viteConfig } from './testApp'
import { dev } from 'vike/api'
let viteServer: Awaited<ReturnType<typeof dev>>['viteServer']
beforeAll(async () => {
const { viteServer } = await dev({ viteConfig })
await viteServer.listen()
await sleep(10) // avoid race condition of server not actually being ready
}, 10 * 1000)
afterAll(async () => {
await viteServer.close()
})
testApp()
function sleep(milliseconds: number): Promise<void> {
return new Promise((r) => setTimeout(r, milliseconds))
}
Make sure to use Vike's JavaScript API — not Vite's API. (When using Vike's JavaScript API, Vike's Vite pugin won't remove itself.)
// preview.spec.js
import { afterAll, beforeAll } from 'vitest'
import { testApp, viteConfig } from './testApp'
import { build, preview } from 'vike/api'
let viteServer
beforeAll(async () => {
await build({ viteConfig })
const { viteServer } = await preview({ viteConfig })
// If you want to replicate Vite's startup log:
viteServer.printUrls()
// For the preview server, no need to call server.listen()
}, 40 * 1000)
afterAll(async () => {
await viteServer.close()
})
testApp()
// preview.spec.ts
import { afterAll, beforeAll } from 'vitest'
import { testApp, viteConfig } from './testApp'
import { build, preview } from 'vike/api'
let viteServer: Awaited<ReturnType<typeof preview>>['viteServer']
beforeAll(async () => {
await build({ viteConfig })
const { viteServer } = await preview({ viteConfig })
// If you want to replicate Vite's startup log:
viteServer!.printUrls()
// For the preview server, no need to call server.listen()
}, 40 * 1000)
afterAll(async () => {
await viteServer!.close()
})
testApp()
// testApp.js
export { testApp }
export { viteConfig }
import { expect, describe, it } from 'vitest'
const viteConfig = {
logLevel: 'warn',
root: __dirname,
configFile: __dirname + '/vite.config.js'
}
const urlBase = 'http://localhost:3000'
function testApp() {
describe('Vitest', () => {
it('run Vitest with Vike', { timeout: 10 * 1000 }, async () => {
{
const html = await fetchHtml('/')
expect(html).toContain('<h1>Welcome</h1>')
expect(html).toContain('<li>Rendered to HTML.</li>')
}
{
const html = await fetchHtml('/about')
expect(html).toContain('<h1>About</h1>')
expect(html).toContain('<p>Example of using Vike.</p>')
}
})
})
}
async function fetchHtml(urlPathname) {
const ret = await fetch(urlBase + urlPathname)
const html = await ret.text()
return html
}
// testApp.ts
export { testApp }
export { viteConfig }
import { expect, describe, it } from 'vitest'
const viteConfig = {
logLevel: 'warn' as const,
root: __dirname,
configFile: __dirname + '/vite.config.js'
}
const urlBase = 'http://localhost:3000'
function testApp() {
describe('Vitest', () => {
it('run Vitest with Vike', { timeout: 10 * 1000 }, async () => {
{
const html = await fetchHtml('/')
expect(html).toContain('<h1>Welcome</h1>')
expect(html).toContain('<li>Rendered to HTML.</li>')
}
{
const html = await fetchHtml('/about')
expect(html).toContain('<h1>About</h1>')
expect(html).toContain('<p>Example of using Vike.</p>')
}
})
})
}
async function fetchHtml(urlPathname: string) {
const ret = await fetch(urlBase + urlPathname)
const html = await ret.text()
return html
}