Unit Tests vs End-to-End Tests
Let’s understand the difference between unit tests and end-to-end (e2e) tests.
Unit Tests (Vitest)
- Test small pieces of code (like single functions)
- Run very quickly
- Don’t use a real browser
- Good for testing business logic
End-to-End Tests (Playwright)
- Test your whole website
- Run in a real browser
- Test how everything works together
- Good for testing what real users do
Why Do We Need Both Types of Tests?
Think of checking a car:
- Unit tests are like testing one part at a time (brakes, lights)
- E2E tests are like driving the whole car to make sure it works
We need both because:
- Unit tests help us find problems in specific parts quickly
- E2E tests make sure everything works together properly
Setting Up Playwright
Let’s set up Playwright in our project.
First, install Playwright:
npm init playwright@latest
During installation, answer these questions:
- Do you want to use TypeScript? → No
- Where to put your end-to-end tests? → tests
- Add a GitHub Actions workflow? → No
- Install Playwright browsers? → Yes
This creates:
- A
tests
folder for your test files - A
playwright.config.js
file with settings
The First Test
Let’s write our first real test.
We’ll check if we can find a link on the Noroff website:
import { test, expect } from "@playwright/test";
test("homepage should show the News link", async ({ page }) => {
// Start at the English homepage
await page.goto("https://www.noroff.no/en");
// Wait for the new page to load and check its content
await expect(page.getByRole("link", { name: "News" })).toBeVisible();
});
Let’s understand this test:
test
- Creates a new test (like in Vitest)"homepage should show the News link"
- Describes what we’re testingasync
- Tells JavaScript to wait for things to complete({ page })
- Gives us a browser page to work withgoto
- Opens a specific URLgetByRole
- Finds elements by their HTML roletoBeVisible
- Checks if we can see something on the page
This simple test is doing what a real user would do:
- Go to the Noroff website
- Check if they can see the News link
Running Tests
npx playwright test
# Runs tests in all browsers in the background (headless mode)
npx playwright test --ui
# Opens Playwright's test interface where you can see tests, run them, and see results
npx playwright test --headed
# Shows the actual browser windows while tests run - useful to see what's happening
npx playwright test --debug
# Runs tests step by step - helpful when tests fail and you need to see why
Run in specific browsers:
npx playwright test --project=webkit # Only Safari
npx playwright test --project=firefox # Only Firefox
npx playwright test --project=webkit --project=firefox # Safari and Firefox
By default, tests run in:
- Chromium (Chrome)
- Firefox
- WebKit (Safari)
You can change this in playwright.config.js
:
// Only run in Chrome and Firefox
export default {
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
},
],
};
Common Matchers
Here are some useful ways to check things on a webpage. These work just like the Vitest matchers we learned about before:
// Check if something is visible
await expect(page.getByRole("button")).toBeVisible();
// Check if something is hidden
await expect(page.getByRole("button")).toBeHidden();
// Check page URL
await expect(page).toHaveURL("https://www.noroff.no/en");
// Check page title
await expect(page).toHaveTitle("Noroff");
// Check text content
await expect(page.getByRole("heading")).toHaveText("Welcome");
// Check if something exists
await expect(page.getByRole("button")).toBeEnabled();
What We Learned
In this lesson, we:
- Understood the difference between unit and e2e tests
- Set up Playwright in our project
- Wrote our first e2e test
- Learned different ways to run tests
- Discovered common matchers that work like Vitest