Skip to content

Frontend Testing Interview Questions for Frontend Development

25 Frontend Testing questions with answers for frontend development roles — 8 easy, 12 medium, 5 hard.

About Frontend Testing

Testing gives teams the confidence to ship often. This topic covers the testing pyramid and trophy, unit, integration and end-to-end tests, Vitest, Testing Library, mocking with MSW, snapshots, visual regression and flaky tests, with hands-on tests in Vitest and Playwright, including accessibility checks with axe.

Sheet progressStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

What is the testing pyramid, and how does the testing trophy differ?

Save to ▾
Show answer
The testing pyramid suggests many fast unit tests, fewer integration tests and very few slow end-to-end tests. The testing trophy, popular for frontend work, puts most effort into integration tests that render components with real behaviour, supported by static analysis like TypeScript and ESLint at the base. Both aim for confidence at reasonable cost; the trophy reflects that UI bugs often appear where units connect.
02

What is the difference between unit, integration and end-to-end tests?

Save to ▾
Show answer
A unit test checks a single function or module in isolation, such as a price formatter. An integration test checks several pieces working together, like a form component with validation and an API call mocked at the network level. An end-to-end test drives a real browser through a complete user flow, such as signup to dashboard, against a running app. They trade speed for realism in that order.
03

Write a Vitest unit test for an INR price formatter.

Save to ▾
Show answer
Test normal, edge and invalid inputs: // format.ts export const formatINR = (paise: number) => new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(paise / 100); // format.test.ts import { describe, it, expect } from 'vitest'; import { formatINR } from './format'; describe('formatINR', () => { it('formats lakhs with Indian grouping', () => { expect(formatINR(12345600)).toBe('\u20b91,23,456.00'); }); it('handles zero', () => { expect(formatINR(0)).toBe('\u20b90.00'); }); });
04

A bug reached production even though all tests passed. What do you do next?

Save to ▾
Show answer
First I fix the bug and confirm the fix with the user's steps. Then I write a regression test that fails without the fix and passes with it, so the same bug cannot return. I also ask why existing tests missed it, for example mocks that hid the real API shape or a browser not covered, and improve that gap rather than only adding one test.
05

QA reports a bug that happens only in Safari on iPhone. How do you debug it?

Save to ▾
Show answer
I would reproduce it on a real iPhone or simulator and connect Safari Web Inspector from a Mac to see console errors and network requests. Common causes are unsupported APIs, date parsing differences, 100vh and viewport issues, and input zoom on small fonts. Cloud device platforms help if no device is available. After fixing it, I would add WebKit to the Playwright browser matrix to catch similar issues.
06

How do you test that a page shows the right message when an API fails?

Save to ▾
Show answer
I would simulate failures at the network layer with Mock Service Worker or Playwright's page.route, returning 500 responses, timeouts or malformed JSON. Then I assert that the user sees a clear error message, a retry button works, and no broken partial data appears. Testing empty states and slow responses with loading indicators is equally important, because these paths are often skipped in manual testing.
07

How do you handle a situation where a bug you wrote affected users?

Save to ▾
Show answer
Situation: a form validation change I made blocked some users from signing up with valid numbers. Task: I needed to fix it and be transparent. Action: I informed my lead immediately, rolled back the change, found that my regex rejected numbers with a +91 prefix, fixed it, and added tests for different formats. Result: signups recovered within an hour, and I now test with real-world data samples.
08

How do you work with QA engineers as a frontend developer?

Save to ▾
Show answer
I treat QA as partners rather than gatekeepers. I share feature details and edge cases early, give them testable builds on staging, and add stable test ids or accessible labels that help automation. When bugs come in, I ask for clear steps and environment details instead of arguing. In my last project, this collaboration cut bug reopen rates because we agreed on acceptance criteria before development.
09

Why are many teams moving from Jest to Vitest?

Save to ▾
Show answer
Vitest reuses the Vite configuration and transform pipeline, so TypeScript, JSX, ES modules and path aliases work without separate Babel or ts-jest setup. It is fast thanks to on-demand transformation and smart watch mode, and its API is largely compatible with Jest, making migration easy. Jest remains mature and widely used, especially in projects not built with Vite. Both support mocking, snapshots and coverage.
10

What is the guiding principle of Testing Library and why query by role?

Save to ▾
Show answer
Testing Library encourages testing the way users interact: find elements by what they see and hear, not by implementation details like class names or component internals. getByRole('button', { name: 'Submit' }) is preferred because it also verifies the element is accessible. Tests written this way survive refactors and catch real accessibility problems. Test ids are a last resort when no accessible query works.
11

When should you mock in frontend tests, and what is Mock Service Worker?

Save to ▾
Show answer
Mock things that are slow, nondeterministic or outside your control, such as network calls, timers and browser APIs, but avoid mocking your own modules heavily, which makes tests pass while the real integration breaks. Mock Service Worker intercepts requests at the network level in both browser and Node, so your real fetch code runs against defined handlers. The same handlers can power tests, Storybook and local development.
12

What are the pros and cons of snapshot testing?

Save to ▾
Show answer
Snapshot tests save a component's rendered output and fail when it changes, which quickly detects unintended changes with little effort. However, large snapshots are hard to review, so developers often update them blindly, and they break on harmless markup changes. They work best for small, stable outputs like serialised config or error messages. For UI behaviour, explicit assertions on visible text and roles are more meaningful.
13

What is visual regression testing?

Save to ▾
Show answer
Visual regression testing captures screenshots of pages or components and compares them pixel by pixel with approved baselines, flagging unexpected visual changes such as broken spacing or wrong colours. Tools include Playwright's toHaveScreenshot, Chromatic with Storybook and Percy. To avoid false failures, run in consistent containers, disable animations, and mask dynamic content like dates. It catches CSS bugs that functional tests miss.
14

Mock fetch in a Vitest test to check error handling.

Save to ▾
Show answer
Stub the global fetch and assert behaviour: import { it, expect, vi, afterEach } from 'vitest'; import { loadCourses } from './api'; afterEach(() => vi.unstubAllGlobals()); it('returns an empty list when the server fails', async () => { vi.stubGlobal('fetch', vi.fn().mockResolvedValue( new Response('Server error', { status: 500 }) )); const result = await loadCourses(); expect(result).toEqual([]); expect(fetch).toHaveBeenCalledWith('/api/courses'); }); For larger suites, MSW handlers are cleaner than stubbing fetch in every test.
15

Write a Playwright end-to-end test for a login flow.

Save to ▾
Show answer
Use role-based locators and web-first assertions: import { test, expect } from '@playwright/test'; test('user can log in and see dashboard', async ({ page }) => { await page.goto('/login'); await page.getByLabel('Email').fill('student@example.com'); await page.getByLabel('Password').fill('Secret@123'); await page.getByRole('button', { name: 'Log in' }).click(); await expect(page).toHaveURL(/dashboard/); await expect(page.getByRole('heading', { name: 'My courses' })).toBeVisible(); }); Assertions auto-wait, so no manual sleeps are needed. Save login state with storageState to reuse in other tests.
16

Test a DOM form with Testing Library and user-event.

Save to ▾
Show answer
Simulate real typing and clicks: import { screen } from '@testing-library/dom'; import userEvent from '@testing-library/user-event'; import { mountSignupForm } from './signup'; it('shows an error for an invalid mobile number', async () => { document.body.innerHTML = '<div id=app></div>'; mountSignupForm(document.getElementById('app')); const user = userEvent.setup(); await user.type(screen.getByLabelText('Mobile'), '12345'); await user.click(screen.getByRole('button', { name: 'Sign up' })); expect(screen.getByRole('alert')).toHaveTextContent('Enter a valid mobile number'); }); toHaveTextContent comes from @testing-library/jest-dom.
17

You must change a complex legacy module that has no tests. How do you proceed safely?

Save to ▾
Show answer
I would first write characterisation tests that capture the current behaviour, including odd cases, by calling the module with real inputs and recording outputs. With that safety net, I make small refactors to separate logic from DOM or network code, adding focused tests as I go. Then I implement the change. Small commits and feature flags let me release gradually and roll back quickly if something breaks.
18

Management requires 100 percent code coverage, but bugs still appear. How do you respond?

Save to ▾
Show answer
Coverage shows which lines ran, not whether the behaviour was verified, so tests can execute code without meaningful assertions. I would explain this with an example and propose a balanced target, perhaps 80 percent on business logic, combined with quality measures like mutation testing, critical user flows covered by end-to-end tests and tracking escaped defects. Effort is better spent on risky areas than on trivial getters.
19

How do you test code that depends on the current date or timers?

Save to ▾
Show answer
Real time makes tests slow and nondeterministic. I would use fake timers, such as vi.useFakeTimers() and vi.setSystemTime(new Date('2026-11-12T10:00:00+05:30')), then advance time with vi.advanceTimersByTime to test debounce, countdowns or expiry logic instantly. Restoring real timers after each test avoids leaking state. Designing functions to accept a clock or date parameter makes them even easier to test.
20

Tell me about a time you pushed back on releasing code without tests.

Save to ▾
Show answer
Situation: near a release deadline, a teammate suggested skipping tests for a new checkout coupon feature. Task: I felt the risk to payments was too high. Action: I proposed covering only the critical paths, valid, expired and invalid coupons, and wrote those tests myself in two hours. Result: one test caught a discount rounding bug before release, and the feature shipped on time.
21

What makes frontend tests flaky?

Save to ▾
Show answer
Flaky tests pass and fail without code changes. Common causes are fixed sleeps instead of waiting for conditions, race conditions with network responses, shared state between tests, reliance on real time or random data, animations, and test order dependencies. Unstable selectors and real third-party services also contribute. Fixes include auto-waiting assertions, isolated test data, mocked clocks, and running tests in parallel to expose hidden shared state.
22

Add automated accessibility checks to Playwright tests.

Save to ▾
Show answer
Use the axe-core integration: import { test, expect } from '@playwright/test'; import AxeBuilder from '@axe-core/playwright'; test('home page has no serious accessibility violations', async ({ page }) => { await page.goto('/'); const results = await new AxeBuilder({ page }) .withTags(['wcag2a', 'wcag2aa']) .analyze(); const serious = results.violations.filter(v => ['serious', 'critical'].includes(v.impact)); expect(serious).toEqual([]); }); Automated tools catch only part of accessibility issues, so keyboard and screen reader checks are still needed.
23

End-to-end tests fail randomly in CI about one run in five. How do you stabilise them?

Save to ▾
Show answer
I would collect traces, videos and screenshots of failures to see what actually happened. Usual fixes are replacing fixed waits with auto-waiting assertions, waiting for specific network responses, seeding isolated test data per test, mocking unstable third-party services, and disabling animations. I would quarantine persistently flaky tests with a tracking ticket rather than letting the team ignore red builds, and retry only as a temporary measure.
24

The frontend test suite takes 20 minutes in CI. How do you make it faster?

Save to ▾
Show answer
I would measure which tests are slowest. Options include running tests in parallel and sharding across CI machines, moving logic checks from end-to-end tests into faster integration tests, reusing logged-in state instead of logging in every time, and running only tests affected by changed files on pull requests with the full suite nightly. Replacing real network calls with MSW and caching dependencies also helps.
25

How have you built a testing culture in a frontend team?

Save to ▾
Show answer
Situation: my team had almost no automated tests and frequent regressions. Task: as tech lead, I wanted testing to become a habit, not a mandate. Action: I set up Vitest and Playwright with examples, ran two short workshops, required tests only for bug fixes at first, and celebrated bugs caught in CI. Result: within six months, most pull requests included tests and production regressions dropped significantly.

Frequently asked questions

How important is Frontend Testing in Frontend Development interviews?

Testing gives teams the confidence to ship often. This topic covers the testing pyramid and trophy, unit, integration and end-to-end tests, Vitest, Testing Library, mocking with MSW, snapshots, visual regression and flaky tests, with hands-on tests in Vitest and Playwright, including accessibility checks with axe.

How should I use the Frontend Testing sheet?

Go top to bottom — easy to hard. Answer before opening each answer, tick what you solved and save misses to Last-Minute Revision.