Part 5: End-to-End Testing

Introduction

End-to-end (E2E) tests validate complete user workflows through your entire systemβ€”from the browser UI through APIs, services, and databases. While slower than unit or integration tests, E2E tests provide the highest confidence that your application works from a user's perspective.

In my TypeScript microservices, E2E tests have caught issues that lower-level tests missed: UI/API integration bugs, authentication flows, complex user journeys, and cross-service interactions.

Why E2E Testing?

E2E tests verify:

  • Complete user workflows - Login, checkout, data submission

  • UI/API integration - Frontend correctly calls backend

  • Cross-service communication - Microservices work together

  • Real browser behavior - JavaScript execution, rendering, events

  • Visual regressions - UI looks correct

When to Write E2E Tests

I write E2E tests for:

  • Critical business workflows (user registration, payment)

  • Complex multi-step processes

  • Features involving multiple services

  • User-facing functionality

I don't write E2E tests for:

  • Every possible scenario (too slow and brittle)

  • Logic already covered by unit tests

  • Edge cases (handle those in unit/integration tests)

Playwright for E2E Testing

I use Playwright for its reliability, speed, and excellent TypeScript support.

Installation:

playwright.config.ts:

Basic E2E Test Example

User Registration Flow

e2e/user-registration.spec.ts:

Testing Authentication Flow

e2e/authentication.spec.ts:

Testing Complex Workflows

E-commerce Checkout Flow

e2e/checkout.spec.ts:

Page Object Model

For better maintainability, use Page Object Model pattern:

pages/login.page.ts:

pages/dashboard.page.ts:

Using Page Objects:

Test Fixtures and Setup

fixtures/auth.fixture.ts:

Using fixtures:

Visual Regression Testing

Installation:

Visual tests:

Mobile Testing

Testing API Calls

Intercepting and mocking API calls:

E2E Testing Best Practices

1. Use Data Attributes for Selectors

2. Wait for Navigation Properly

3. Test User-Visible Behavior

4. Keep Tests Independent

5. Use Meaningful Test Data

Common Pitfalls

1. Waiting for Elements

2. Handling Flaky Tests

Key Takeaways

  1. E2E tests verify complete workflows - From UI to database

  2. Use Playwright for modern E2E testing - Fast, reliable, great DX

  3. Page Object Model improves maintainability - Encapsulate page logic

  4. Test critical user journeys - Not every edge case

  5. Use fixtures for common setup - Authentication, test data

  6. Visual regression catches UI bugs - Automated screenshot comparison

  7. Keep tests fast and independent - Parallel execution, no dependencies

What's Next?

In Part 6: Performance and Load Testing, we'll cover:

  • Load testing with k6

  • Performance benchmarking

  • Stress testing microservices

  • Monitoring and metrics

  • Performance regression testing


This article is part of the Software Testing 101 series.

Last updated