Testing Nuxt Applications

Building Confidence Through Tests

Testing ensures your application works as expected and prevents regressions. Nuxt apps can be tested at multiple levels.

Testing Pyramid

  1. Unit Tests - Test individual functions and composables
  2. Component Tests - Test Vue components in isolation
  3. E2E Tests - Test full user workflows

Unit Testing with Vitest

// composables/useCounter.test.ts
import { describe, expect, it } from 'vitest'
import { useCounter } from './useCounter'

describe('useCounter', () => {
  it('increments count', () => {
    const { count, increment } = useCounter()
    expect(count.value).toBe(0)
    increment()
    expect(count.value).toBe(1)
  })
})

Setup Vitest:

import vue from '@vitejs/plugin-vue'
// vitest.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  plugins: [vue()],
  test: {
    environment: 'jsdom',
  },
})

Component Testing

// components/Counter.test.ts
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import Counter from './Counter.vue'

describe('Counter Component', () => {
  it('renders count', () => {
    const wrapper = mount(Counter, {
      props: { initialValue: 5 }
    })
    expect(wrapper.text()).toContain('5')
  })

  it('increments on button click', async () => {
    const wrapper = mount(Counter)
    await wrapper.find('button').trigger('click')
    expect(wrapper.emitted('update')).toBeTruthy()
  })
})

E2E Testing with Playwright

// tests/e2e/homepage.spec.ts
import { expect, test } from '@playwright/test'

test('homepage loads correctly', async ({ page }) => {
  await page.goto('http://localhost:3000')
  await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible()
})

test('navigation works', async ({ page }) => {
  await page.goto('http://localhost:3000')
  await page.click('text=About')
  await expect(page).toHaveURL(/.*about/)
})

Testing Server Routes

import { $fetch, setup } from '@nuxt/test-utils'
// server/api/todos.test.ts
import { describe, expect, it } from 'vitest'

describe('Todos API', async () => {
  await setup()

  it('returns todos', async () => {
    const todos = await $fetch('/api/todos')
    expect(Array.isArray(todos)).toBe(true)
  })

  it('creates todo', async () => {
    const newTodo = await $fetch('/api/todos', {
      method: 'POST',
      body: { title: 'Test' }
    })
    expect(newTodo.title).toBe('Test')
  })
})

Testing Best Practices

  1. ✅ Write tests for critical paths
  2. ✅ Test business logic, not implementation details
  3. ✅ Use descriptive test names
  4. ✅ Keep tests isolated and independent
  5. ✅ Mock external dependencies
  6. ✅ Aim for good coverage, not 100%
  7. ✅ Run tests in CI/CD

Test Coverage

// package.json
{
  "scripts": {
    "test": "vitest",
    "test:coverage": "vitest --coverage",
    "test:e2e": "playwright test"
  }
}

Testing is an investment that pays dividends. Start with critical paths, then expand coverage. Remember: some tests are better than no tests!

SEO Best Practices
Deploying Nuxt Applications
Files
Editor
Initializing WebContainer
Mounting files
Installing dependencies
Starting Nuxt server
Waiting for Nuxt to ready
Terminal