Croot Blog

Home About Tech Hobby Archive

테스팅 문법 비교

0image.png

요약 비교

도구 테스트 환경 테스트 목적 API Mocking
Cypress 실제 브라우저 E2E cy.intercept
Jest jsdom (가상 DOM) 유닛/통합 global.fetch = jest.fn()
Playwright 브라우저 (크롬 등) E2E page.route()
Vitest jsdom (vite 기반) 유닛/통합 global.fetch = vi.fn()

Cypress

// cypress/e2e/page.cy.js
describe('Page E2E Test', () => {
  it('renders correctly, checks title, button, and API result', () => {
    cy.intercept('GET', '/api/message', {
      statusCode: 200,
      body: { message: 'Hello from API!' },
    }).as('getMessage');

    cy.visit('http://localhost:3000');

    cy.get('h1').should('have.text', 'My Page Title');
    cy.get('#submit').should('be.enabled').click();

    cy.wait('@getMessage');
    cy.get('[role="status"]').should('contain', 'Hello from API!');
    cy.get('#submit').should('be.enabled');
  });
});


Jest + React Testing Library

// Page.test.jsx
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import Page from './Page';

beforeEach(() => {
  global.fetch = jest.fn(() =>
    Promise.resolve({
      json: () => Promise.resolve({ message: 'Hello from API!' }),
    })
  );
});

afterEach(() => {
  jest.resetAllMocks();
});

test('renders page and fetches data on button click', async () => {
  render(<Page />);

  expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('My Page Title');

  const button = screen.getByRole('button', { name: /submit/i });
  expect(button).toBeEnabled();

  fireEvent.click(button);

  expect(button).toBeDisabled();

  await waitFor(() => {
    expect(screen.getByRole('status')).toHaveTextContent('Hello from API!');
  });

  expect(button).toBeEnabled();
});


Playwright

// tests/page.spec.ts
import { test, expect } from '@playwright/test';

test('renders page, checks h1, button, and API response', async ({ page }) => {
  await page.route('**/api/message', async route => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({ message: 'Hello from API!' }),
    });
  });

  await page.goto('http://localhost:3000');

  await expect(page.getByRole('heading', { level: 1 })).toHaveText('My Page Title');

  const button = page.getByRole('button', { name: /submit/i });
  await expect(button).toBeEnabled();
  await button.click();

  await expect(page.getByRole('status')).toHaveText('✅ Hello from API!');
  await expect(button).toBeEnabled();
});


Vitest + Testing Library

// Page.test.jsx
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import Page from './Page';

describe('Page', () => {
  beforeEach(() => {
    global.fetch = vi.fn(() =>
      Promise.resolve({
        json: () => Promise.resolve({ message: 'Hello from API!' }),
      })
    );
  });

  afterEach(() => {
    vi.resetAllMocks();
  });

  it('renders, checks h1 and button, then fetches data', async () => {
    render(<Page />);

    expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent('My Page Title');

    const button = screen.getByRole('button', { name: /submit/i });
    expect(button).toBeEnabled();

    fireEvent.click(button);
    expect(button).toBeDisabled();

    await waitFor(() => {
      expect(screen.getByRole('status')).toHaveTextContent('Hello from API!');
    });

    expect(button).toBeEnabled();
  });
});