React Native Academy · Lektion

Gengivelse af komponenter med React Native Testing Library

Brug render fra @testing-library/react-native til at montere komponenter, forespørg efter elementer via tekst eller testID, og verificér, at det forventede indhold er synligt.

Lektion 2 af 413 trin

Gengivelse af komponenter med React Native Testing Library er en gratis React Native Academy-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i React Native Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. React Native Academy-kurset indeholder 4 lektioner i alt.

Hvad er React Native Testing Library?

React Native Testing Library (RNTL) er standardværktøjet til at skrive komponenttest i React Native. Det lader dig rendere en komponent i et simuleret miljø, forespørge på outputtet efter elementer og lave forventninger til det, brugeren ville se.

RNTL følger Testing Library-filosofien: Test komponenter på den måde, brugerne interagerer med dem — via synlig tekst, tilgængelighedslabels og roller — i stedet for via interne implementeringsdetaljer som komponentnavne eller tilstandsværdier. Det giver test, der er robuste over for refaktorering.

Installation af React Native Testing Library

Installér RNTL og dens peer-afhængighed @testing-library/jest-native for at få udvidede matchere. Pakken jest-native tilføjer React Native-specifikke matchere som toBeVisible() og toHaveTextContent().

Tilføj opsætningsfilen til din Jest-konfiguration, så matcherne er tilgængelige i alle testfiler uden manuelle importer. Importér @testing-library/jest-native/extend-expect i Jest-opsætningsfilen.

npm install --save-dev @testing-library/react-native @testing-library/jest-native

// jest.config.js — add setup file
module.exports = {
  preset: 'jest-expo',
  setupFilesAfterFramework: ['@testing-library/jest-native/extend-expect'],
};

// Or in package.json:
'jest': {
  'preset': 'jest-expo',
  'setupFilesAfterFramework': ['@testing-library/jest-native/extend-expect']
}

Rendering af en komponent med render()

Funktionen render() fra RNTL monterer en komponent og returnerer et sæt forespørgselsværktøjer til at undersøge det renderede output. Den tager JSX, ligesom du ville skrive det i din app, inklusive de props eller omsluttende providere, der er nødvendige.

Det returnerede objekt indeholder forespørgselsmetoder og en debug()-funktion, der udskriver det renderede komponenttræ i konsollen. Kald debug() når som helst under en test for at se, hvordan komponenten ser ud på det tidspunkt.

import { render } from '@testing-library/react-native';
import { Greeting } from '../src/components/Greeting';

describe('Greeting', () => {
  it('displays the correct greeting message', () => {
    const { getByText, debug } = render(<Greeting name='Alice' />);

    // Print the component tree for debugging
    debug();

    // Assert that the text 'Hello, Alice!' is visible
    expect(getByText('Hello, Alice!')).toBeTruthy();
  });
});

Forespørgsel efter tekst med getByText

getByText(text) finder et element, der viser den nøjagtige tekststreng. Den kaster en fejl, hvis der ikke findes noget matchende element (hvilket får testen til at mislykkes), eller hvis flere elementer matcher. Brug queryByText, når du vil kontrollere, at teksten ikke er til stede (den returnerer null i stedet for at kaste en fejl).

Du kan også sende et regulært udtryk for at matche dele af teksten: getByText(/Hello/). Det er nyttigt, når teksten indeholder dynamiske værdier som et brugernavn, som du ikke vil hardkode i testen.

import { render } from '@testing-library/react-native';
import { PostCard } from '../src/components/PostCard';

it('renders the post title and author', () => {
  const { getByText, queryByText } = render(
    <PostCard title='My First Post' author='Alice' isDeleted={false} />
  );

  // getByText throws if not found
  expect(getByText('My First Post')).toBeTruthy();
  expect(getByText('Alice')).toBeTruthy();

  // queryByText returns null if not found — use for absence checks
  expect(queryByText('Deleted')).toBeNull();
});

Forespørgsel efter testID

Når der ikke er nogen synlig tekst, du kan forespørge efter, skal du tilføje en testID-prop til elementet og forespørge efter det med getByTestId('testID'). Det er nyttigt til ikoner, billeder, indlæsningsindikatorer og containervisninger.

Hold testID-værdier konsekvente med den komponent, de identificerer. En navngivningskonvention som componentName-element (f.eks. profileCard-avatar) gør test-id'er selvforklarende og forhindrer sammenfald på tværs af testsuiten.

// Component:
export function LoadingScreen() {
  return (
    <View testID='loading-screen'>
      <ActivityIndicator testID='loading-spinner' />
      <Text>Loading your data...</Text>
    </View>
  );
}

// Test:
import { render } from '@testing-library/react-native';

it('shows a loading spinner', () => {
  const { getByTestId } = render(<LoadingScreen />);

  const spinner = getByTestId('loading-spinner');
  expect(spinner).toBeTruthy();
});

Forespørgsler efter tilgængelighed

RNTL anbefaler forespørgsler efter tilgængelighedsattributter, fordi det er dem, skærmlæsere bruger. På den måde kontrollerer dine test også tilgængeligheden. De vigtigste forespørgsler efter tilgængelighed er:

  • getByRole('button', { name: 'Submit' }) — finder et element ud fra dets ARIA-rolle og tilgængelige navn
  • getByLabelText('Email') — finder et element med en matchende accessibilityLabel
  • getByPlaceholderText('Enter email') — finder et TextInput-element ud fra dets pladsholder
it('has an accessible submit button', () => {
  const { getByRole, getByLabelText, getByPlaceholderText } = render(
    <LoginForm />
  );

  // Find by role (button)
  const submitButton = getByRole('button', { name: 'Sign In' });
  expect(submitButton).toBeTruthy();

  // Find TextInput by placeholder
  const emailInput = getByPlaceholderText('Enter your email');
  expect(emailInput).toBeTruthy();

  // Find by accessibility label
  const passwordInput = getByLabelText('Password');
  expect(passwordInput).toBeTruthy();
});

Forventninger med jest-native-matchere

@testing-library/jest-native udvider Jest med semantiske matchere, der er lettere at læse og mere meningsfulde end at kontrollere rå props. Vigtige matchere omfatter:

  • toBeVisible() — elementet er ikke skjult
  • toHaveTextContent('text') — elementet indeholder den angivne tekst
  • toBeDisabled() — knappen eller inputfeltet er deaktiveret
  • toHaveStyle({ color: 'red' }) — elementet har den angivne stil
import { render } from '@testing-library/react-native';
import { StatusBadge } from '../src/components/StatusBadge';

it('shows an error badge in red when status is error', () => {
  const { getByTestId } = render(<StatusBadge status='error' />);

  const badge = getByTestId('status-badge');
  expect(badge).toBeVisible();
  expect(badge).toHaveTextContent('Error');
  expect(badge).toHaveStyle({ backgroundColor: '#ff4444' });
});

Rendering med providere

De fleste komponenter fra virkelige projekter afhænger af kontekstprovidere som NavigationContainer, Redux Provider eller en tilpasset ThemeContext. Hvis du renderer en komponent uden de nødvendige providere, vil testen kaste en fejl.

Opret et tilpasset renderWithProviders-hjælpeværktøj, der omslutter komponenter med alle nødvendige providere. Giv dette hjælpeværktøj til RNTL's render-indstilling via wrapper, eller brug det som en direkte erstatning for render i hele din testsuite.

// test-utils.tsx
import { NavigationContainer } from '@react-navigation/native';
import { ThemeProvider } from '../src/context/ThemeContext';

export function renderWithProviders(
  ui: React.ReactElement,
  options = {}
) {
  function Wrapper({ children }: { children: React.ReactNode }) {
    return (
      <NavigationContainer>
        <ThemeProvider>
          {children}
        </ThemeProvider>
      </NavigationContainer>
    );
  }
  return render(ui, { wrapper: Wrapper, ...options });
}

// In tests:
import { renderWithProviders } from '../test-utils';
const { getByText } = renderWithProviders(<ProfileScreen />);

Snapshot-test

Snapshot-test gemmer en komponents renderede output i en .snap-fil. Ved efterfølgende kørsler sammenligner Jest det aktuelle output med det gemte snapshot og får testen til at mislykkes, hvis de er forskellige. Det fanger utilsigtede ændringer i brugergrænsefladen.

Brug snapshots med omtanke. De er gode til små, stabile komponenter som ikoner eller knapper. For komplekse skærmbilleder bliver snapshot-test ofte skrøbelige — selv små, tilsigtede ændringer kræver, at du opdaterer snapshottet med jest --updateSnapshot, så det er let ved en fejl at acceptere et ødelagt output.

import { render } from '@testing-library/react-native';
import { PrimaryButton } from '../src/components/PrimaryButton';

it('renders a primary button correctly', () => {
  const { toJSON } = render(<PrimaryButton title='Save' onPress={() => {}} />);
  expect(toJSON()).toMatchSnapshot();
});

// First run creates:
// __snapshots__/PrimaryButton.test.tsx.snap
// Subsequent runs compare against that snapshot

Test af betinget rendering

Komponenter renderer ofte forskellig brugergrænseflade baseret på props eller tilstand. Test hver betingede gren eksplicit ved at rendere komponenten med forskellige props og kontrollere, at de korrekte elementer er til stede eller fraværende.

Brug queryByText eller queryByTestId (som returnerer null i stedet for at kaste en fejl) til at kontrollere fravær. Undgå at bruge getBy-forespørgsler til at kontrollere fravær — de kaster en fejl, hvilket ikke giver en tydelig fejlmeddelelse.

describe('ErrorBanner', () => {
  it('shows the error message when error prop is provided', () => {
    const { getByText } = render(
      <ErrorBanner error='Something went wrong' />
    );
    expect(getByText('Something went wrong')).toBeTruthy();
  });

  it('renders nothing when error is null', () => {
    const { queryByTestId } = render(<ErrorBanner error={null} />);
    // Assert the banner container is NOT rendered
    expect(queryByTestId('error-banner')).toBeNull();
  });
});

Varianterne getAllBy og findBy

RNTL's forespørgselsfunktioner findes i tre varianter:

  • getBy — kaster en fejl, hvis elementet ikke findes, eller hvis der er flere match (bruges til enkelte elementer, der skal findes)
  • getAllBy — returnerer et array og kaster en fejl, hvis ingen findes (bruges til lister med elementer)
  • findBy — returnerer et Promise og venter på, at elementet vises (bruges til asynkront indhold)

Varianterne findBy er afgørende, når du tester komponenter, der indlæser data asynkront — de prøver automatisk forespørgslen igen, indtil elementet vises, eller en timeout overskrides.

// getAllBy: asserts there are exactly 3 list items
const items = getAllByTestId('list-item');
expect(items).toHaveLength(3);

// findBy: waits for async content to appear
it('shows posts after loading', async () => {
  const { findByText } = render(<PostFeed />);

  // Waits up to 1000ms for the text to appear
  const postTitle = await findByText('My First Post');
  expect(postTitle).toBeTruthy();
});

Hurtigt tjek

Test din forståelse af begreberne inden for React Native-mobiludvikling fra denne lektion.

Opsummering af lektionen

I denne lektion har du lært: hvordan du renderer komponenter med RNTL's render()-funktion og forespørger efter elementer via tekst, testID og tilgængelighedsattributter, hvordan jest-native-matchere som toBeVisible() og toHaveTextContent() gør forventninger mere læsbare og hvordan du omslutter komponenter med providere i test, der kræver navigations- eller temakontekst. Nu skal du lære at udløse brugerhændelser og teste interaktiv komponentadfærd.

Gratis at komme i gang

Lær JavaScript med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Gengivelse af komponenter med React Native Testing Library” gratis?

Ja — alle 3 lektioner i læringssporet React Native Academy, inklusive “Gengivelse af komponenter med React Native Testing Library”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. React Native Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Gengivelse af komponenter med React Native Testing Library”?

Brug render fra @testing-library/react-native til at montere komponenter, forespørg efter elementer via tekst eller testID, og verificér, at det forventede indhold er synligt. Du øver dig i React Native Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på React Native Academy?

Der kræves ingen tidligere erfaring. React Native Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.

Hvor lang tid tager lektionen “Gengivelse af komponenter med React Native Testing Library”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne React Native Academy-lektion?

Ja. Alle React Native Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Opsætning af Jest i et React Native-projekt
  2. Gengivelse af komponenter med React Native Testing Library
  3. Udløsning af hændelser og test af brugerinteraktion
  4. Mocking af native moduler og asynkron kode
← Tilbage til React Native Academy