Exercise: Testing
by Tomas Trescak· Testing React

0 / 650 XP
The external project has not been reviewed yet
Please follow instructions below to submit your project

Coding Assessment: Building a Blogging Application

Topic: Build a TypeScript-based blogging application with a client side (viewing/filtering posts) and an admin side (creating/modifying posts). You will implement core features and write unit tests using Vitest or Playwright and end-to-end tests using Playwright.

Please fork and clone this repository and continue with instructions below:

 

🎯 Goals

  1. Use both unit testing strategies to test your approach (Reacy-Testing-Library vs Playwright).
  2. Write all necessary End-to-End tests
  3. Try to achieve 100% coverage across the whole app. You can visualise your coverage in the vitest UI.

Narrative

You’re a developer at BlogSphere, a startup creating a platform for writers. Your task is to build a blogging app where users can browse posts (filtered by date or tag) and admins can manage content. Your code must be reliable, so you’ll write tests to ensure everything works. This project mirrors real-world full-stack development, teaching you React, TypeScript, routing, and testing.

Assessment Overview:

  • Client Side: Users can view a list of posts, filter by date (newest/oldest), or filter by tag (e.g., “tech,” “lifestyle”).
  • Admin Side: Admins can create new posts or edit existing ones via a form.
  • Tech Stack: React, TypeScript, React Router, Vitest (unit tests), Playwright (E2E tests).
  • Deliverables: Complete the provided starter code and write tests to verify functionality.

Background

1. Vitest + Testing Library with JSDOM

What is it?

  • Vitest: A fast, modern testing framework optimized for Vite-based projects (like our TypeScript blogging app).
  • Testing Library: A library for testing UI components by simulating user interactions (e.g., clicking, typing).
  • JSDOM: A JavaScript implementation of the DOM, allowing tests to run in a Node.js environment without a real browser.

How it works: You write tests to render React components in a simulated DOM (JSDOM), interact with them (e.g., click a button), and assert outcomes (e.g., a post appears).

Example (Testing a PostList component):

import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import PostList from './PostList';

describe('PostList', () => {
  it('renders posts correctly', () => {
    const posts = [{ id: 1, title: 'First Post', date: '2025-04-13' }];
    render(<PostList posts={posts} />);
    expect(screen.getByText('First Post')).toBeInTheDocument();
  });
});

Advantages:

  1. Speed: Tests run in Node.js, so they’re faster than browser-based tests. No need to launch a browser.
  2. Simplicity: Testing Library encourages user-centric testing, focusing on what users see and do (e.g., “click the publish button”).
  3. Lightweight Setup: No browser dependencies, ideal for CI/CD pipelines.
  4. Great for Unit Tests: Perfect for isolating components (e.g., testing a PostFilter component without rendering the whole app).

Disadvantages:

  1. Not a Real Browser: JSDOM mimics the DOM but isn’t perfect. It may miss browser-specific quirks (e.g., CSS rendering, native events).
  2. Limited End-to-End Testing: JSDOM focuses on components, not full app flows (e.g., navigating from a post to a tag-filtered view).
  3. Mocking Overhead: Complex interactions (e.g., drag-and-drop, animations) often require mocks, which can be brittle.

Pitfalls:

  • Over-Mocking: Students sometimes mock too much (e.g., APIs, hooks), leading to tests that pass but don’t reflect reality.
  • JSDOM Limitations: Subtle bugs (e.g., focus management, media queries) may slip through because JSDOM doesn’t fully replicate browsers.
  • Learning Curve: Testing Library’s philosophy (“test like a user”) can feel abstract for beginners.

2. Playwright Component Testing

What is it?

  • Playwright: A browser automation tool (like Puppeteer) that also supports component testing.
  • Component Testing: Renders React components in a real browser (e.g., Chromium, Firefox) using Playwright’s API, combining unit testing with browser realism.

How it works: You mount a component in a browser, interact with it using Playwright’s methods (e.g., click, fill), and assert results. It’s like Vitest but in a real browser environment.

Example (Testing the same PostList component):

import { test, expect } from '@playwright/experimental-ct-react';
import PostList from './PostList';

test('renders posts correctly', async ({ mount }) => {
  const posts = [{ id: 1, title: 'First Post', date: '2025-04-13' }];
  const component = await mount(<PostList posts={posts} />);
  await expect(component.getByText('First Post')).toBeVisible();
});

Advantages:

  1. Real Browser Environment: Tests run in Chromium, Firefox, or WebKit, catching browser-specific bugs (e.g., rendering, events).
  2. End-to-End Capabilities: Playwright can test full app flows (e.g., admin creating a post, then viewing it as a user), unlike JSDOM’s component focus.
  3. Rich Interactions: Native support for complex actions (e.g., file uploads, hover states) without mocking.
  4. Debugging Power: Built-in tools like screenshots, videos, and browser dev tools make debugging intuitive.

Disadvantages:

  1. Slower: Launching a browser takes time, making tests slower than JSDOM (e.g., 100ms vs. 10ms per test).
  2. Heavier Setup: Requires installing browser binaries, which can complicate CI/CD or student laptops.
  3. Less Isolated: Browser tests may inadvertently test more than intended (e.g., global styles affecting a component).
  4. Overkill for Simple Tests: For small, isolated components (e.g., a Button), a full browser may be unnecessary.

Pitfalls:

  • Flakiness: Browser tests can fail due to timing issues (e.g., animations, network delays), frustrating beginners.
  • Resource Intensive: Running many tests in parallel eats CPU/memory, slowing down development.
  • Temptation to Over-Test: Students may write overly broad tests (e.g., testing navigation in a component test), blurring unit vs. E2E lines.

When to Use Each?

  • Vitest + Testing Library (JSDOM):
    • Best for unit testing individual components (e.g., PostList, FilterByTag).
    • Ideal for fast feedback during development.
    • Use when testing logic-heavy components (e.g., a date sorter) or when browser quirks are unlikely.
    • Example: In our blogging app, use it to test the AdminForm’s validation logic.
  • Playwright Component Testing:
    • Best for integration testing components with browser-specific behaviour (e.g., CSS transitions, focus trapping).
    • Ideal for critical user flows (e.g., ensuring the “Publish Post” button works across browsers).
    • Use when you need confidence in production-like environments.
    • Example: In our blogging app, use it to test the PostList’s tag-filtering UI across Chromium and Firefox.
  • Playwright End-To-End testing
    • Best for final system tests, when all parts of the application are running
    • Use when you need confidence during production deployments.
    • Example: In our blogging app, before every deploy

Practical Tips for Our Blogging App

For your coding assessment (building the blogging app), you’ll write tests for both the client (e.g., filtering posts by date) and admin (e.g., creating posts). Here’s how to approach testing:

  • Use Vitest + Testing Library to test components like PostList or AdminForm in isolation. For example, ensure PostList renders posts sorted by date.
  • Use Playwright to test flows like “admin publishes a post, then views it on the client side.” This catches real-world issues (e.g., browser rendering).
  • Combine Both: Write fast Vitest unit tests for logic, then selective Playwright tests for key interactions. This balances speed and reliability.

Conclusion

Both Vitest with Testing Library and Playwright component testing are powerful, but they serve different needs. Vitest is your go-to for quick, isolated tests, while Playwright shines for browser-realistic scenarios. In our blogging app, you’ll use both: Vitest to ensure your PostFilter logic works, and Playwright to verify the user experience across browsers. Avoid pitfalls like over-mocking in JSDOM or flaky Playwright tests by keeping tests focused and well-structured.

Maggie

Discuss with Maggie
Use the power of generative AI to interact with course content

Maggie is a generative AI that can help you understand the course content better. You can ask her questions about the lecture, and she will try to answer them. You can also see the questions asked by other students and her responses.

Discuss with Others
Ask questions, share your thoughts, and discuss with other learners

Join the discussion to ask questions, share your thoughts, and discuss with other learners
Setup
React Fundamentals
10 points
Next.js
10 points
Advanced React
Databases
10 points
React Hooks
Authentication and Authorisation
10 points
APIs
CI/CD and DevOps
Testing React
Advanced Topics