Testning i React

Typer av testning

  • Enhetstestning
    • Enhetstest är en typ av testning som fokuserar på att testa individuella komponenter eller funktioner isolerat.
  • End-to-End-test
    • En typ av testning som simulerar användarinteraktioner i en verklig miljö.
    • E2E-test hjälper till att säkerställa att olika delar av din React-applikation samverkar korrekt.
    • Ett populärt verktyg för E2E-testning är Cypress.

Ramverk - javascript

  • Till att börja med behöver vi ett ramverk för att köra våra tester
    • Mocha
    • Jasmine
    • Jest
    • Vitest

Vi kommer att använda Jest

Ramverk - React

  • För att testa React-applikationer behöver vi ett ramverk som kan hantera React-komponenter
    • Enzyme
    • React Testing Library
    • React Test Utils

Vi kommer att använda React Testing Library

React Testing Library - Vad är det?

  • React Testing Library är ett verktyg för att testa React-komponenter
  • Exempel på funktionalitet
    • Rendera komponenter
    • Hitta element i komponenter
    • Simulera användarinteraktioner
    • Testa att komponenter renderas korrekt
    • Snapshot-testning

Komma igång, steg 1

  • Installera npm-paket:
npm install --save-dev jest @types/jest ts-jest @testing-library/react @testing-library/jest-dom ts-jest jest-environment-jsdom

Komma igång, steg 2

  • Lägg till jest.config.js:
/** @type {import('ts-jest').JestConfigWithTsJest} */
export default {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
};

Komma igång, steg 3

  • Lägg till följande kod i filen package.json så att vi kan köra tester med kommandot npm test:
"scripts": {
  "test": "jest"
}

Testets uppbyggnad

  • Ett test består av tre delar:
    • Arrange
    • Act
    • Assert
test('renders correctly', () => {
  // Arrange
  render(<MyTestedComponent />);

  // Act
  const linkElement = screen.getByText(/click me/i);
  fireEvent.click(linkElement);

  // Assert
  expect(linkElement).toBeInTheDocument();
});

Exempel, rendera en komponent

  • Vi skapar en enkel komponent
// myTestedComponent.spec.tsx

import { render } from '@testing-library/react';
import MyTestedComponent from './MyTestedComponent';

test('renders correctly', () => {
  render(<MyTestedComponent />);
});

Exempel, hitta element i en komponent

// button.spec.tsx

import { render, screen } from '@testing-library/react';

test('renders correctly', () => {
  render(<MyTestedComponent />);
  const element = screen.getByText(/click me/i);
});

screen - Vad är det?

  • screen är ett objekt som innehåller funktioner för att hitta element i en komponent
  • Exempel på funktioner:
    • getByText
    • getByRole
    • getByLabelText
    • getByPlaceholderText
    • getByAltText
    • osv.

https://testing-library.com/docs/queries/about/

Simulera användarinteraktioner

  • Exempel, klicka på en knapp:
import { render, screen } from '@testing-library/react';

test('renders learn react link', () => {
  render(<MyTestedComponent />);
  const linkElement = screen.getByText(/learn react/i);
  fireEvent.click(linkElement);
});

fireEvent - Vad är det?

  • fireEvent är ett objekt som innehåller funktioner för att simulera användarinteraktioner
  • Exempel på funktioner:
    • click
    • change
    • submit
    • osv.

https://testing-library.com/docs/dom-testing-library/api-events/

Exempel, testa att komponenter renderas korrekt

import { render, screen } from '@testing-library/react';

test('renders learn react link', () => {
  render(<MyTestedComponent />);
  const linkElement = screen.getByText(/click me/i);
  expect(linkElement).toBeInTheDocument();
});

expect - Vad är det?

  • expect är ett objekt som innehåller funktioner för att testa att ett värde är av ett visst typ
  • Hör till ramverket Jest
  • Exempel på funktioner:
    • toBe
    • toBeTruthy
    • toBeFalsy
    • osv.

https://jestjs.io/docs/expect

Snapshottestning

  • Med snapshot-testning kan vi testa att en komponent renderas på ett visst sätt
  • Vi behöver inte skiva några förväntade värden
  • Istället sparar vi en “bild” av hur komponenten renderas
  • Om komponenten ändras på ett sätt som inte är avsett kommer testet att misslyckas

Snapshot vs. vanliga tester

Fördelar, snapshot

  • Enkelt att skriva ett test utan en massa kod
  • Enkelt att uppdatera testet om komponenten ändras

Nackdelar, snapshot

  • Går inte att utläsa från testet hur komponenten förväntas fungera
  • Testet måste alltid uppdateras när komponenten ändras

Exempel, snapshottest

import { render, screen } from '@testing-library/react';
import { Button } from './Button';
import '@testing-library/jest-dom';

test('renders button correctly', () => {
    const { asFragment } = render(<Button />);
    expect(asFragment()).toMatchSnapshot();
});

Vad gör koden ovan?

  • ´asFragment´ returnerar en snapshot av komponenten
  • ´toMatchSnapshot´ jämför snapshoten med den senaste versionen av snapshoten
  • Om snapshoten inte finns skapas en ny snapshot
  • Om snapshoten finns jämförs den med den senaste versionen av snapshoten
  • Om snapshoten inte stämmer överens med den senaste versionen av snapshoten kastas ett error
  • Om snapshoten stämmer överens med den senaste versionen av snapshoten går testet igenom

Snapshot-fil

  • Snapshot-fil
  • Snapshot spara som en fil i en mapp som heter ´__snapshots__´
  • Denna ska commitas till git

Mockning


Mockning

Demo - Mockning av API-anrop