Testing in React Native nel 2026: Jest, RNTL, Maestro e Detox
Strategia di testing per app React Native nel 2026: unit con Jest 30, componenti con RNTL 13, E2E con Maestro o Detox. Configurazioni complete, mock dei moduli nativi e pipeline CI EAS + GitHub Actions in meno di 8 minuti.
Testare un'app React Native nel 2026 vuol dire mettere insieme test unitari con Jest, test di componenti con React Native Testing Library e test end-to-end con Maestro o Detox, il tutto cucito in una pipeline CI tipo EAS Build o GitHub Actions. In questa guida trovi esempi runnable per costruire una strategia di testing affidabile su Expo SDK 53 e React Native 0.78, schivando i tranelli più comuni della Nuova Architettura (Fabric e TurboModules).
Premessa onesta: nell'ultimo progetto che ho seguito, una suite Detox ben configurata ha intercettato un crash da split JS bundle a tre giorni dal lancio. Non sarebbe mai uscito da test manuali. Da lì in poi non ho più consegnato un'app mobile senza una pipeline E2E, anche minima.
Jest 30 con il preset jest-expo resta lo standard per i test unitari e di snapshot in React Native 0.78.
React Native Testing Library 13 spinge verso query basate sul comportamento (getByRole, getByLabelText) e ha pieno supporto a Fabric.
Maestro 1.39 è la scelta più semplice per E2E: file YAML dichiarativi, zero dipendenze dal codice nativo dell'app.
Detox 20.30 resta lo strumento più potente per scenari complessi su iOS e Android, con sincronizzazione automatica dell'UI.
I mock dei moduli nativi e di expo-modules-core sono indispensabili per evitare crash nei test Node.
Una pipeline EAS Build + GitHub Actions può eseguire unit + Maestro Cloud in meno di 8 minuti.
La piramide del testing applicata a React Native
La classica piramide di Mike Cohn si traduce in tre livelli molto specifici per le app React Native. Alla base, i test unitari con Jest verificano funzioni pure, hook personalizzati e logica di business: sono veloci (decine di millisecondi) e dovrebbero coprire circa il 70% della suite. Al centro, i test di componenti con React Native Testing Library renderizzano un albero JSX in modo isolato (senza dispositivo né simulatore) per verificare il comportamento osservabile: clic, input, accessibility. All'apice, una manciata di test end-to-end con Maestro o Detox esegue flussi reali su un simulatore iOS o un emulatore Android.
Nel 2026 la differenza rispetto al passato è che la Nuova Architettura di React Native introduce Fabric come renderer di default e TurboModules per i bridge nativi. Questo cambia il modo in cui i mock vengono caricati: il vecchio approccio basato su react-native/jest/setup.js non basta più. Va usato il preset jest-expo aggiornato, che configura automaticamente i transformer per i moduli ESM di Expo SDK 53 e fornisce shim per i TurboModules più comuni. Se non hai ancora migrato all'architettura moderna, dai un'occhiata alla nostra guida a JSI, TurboModules, Fabric e Codegen prima di affrontare il testing.
Distribuzione tipica che mi funziona: 70% unit, 20% componenti, 10% E2E. Investire troppo in E2E significa pipeline lente e flaky. Ignorarli del tutto significa scoprire i bug solo dopo lo store review. Il TDD puro è raro nei team mobile veri: la prassi è scrivere test contestualmente al codice, con la review che blocca PR senza copertura sui nuovi moduli critici.
Configurare Jest e scrivere test unitari
Jest 30, rilasciato a gennaio 2026, porta supporto nativo ai moduli ESM e un runner molto più veloce. Per un progetto Expo, l'installazione si fa in una riga di shell:
npx expo install --dev jest jest-expo @testing-library/react-native @testing-library/jest-native
Il file jest.setup.ts centralizza i mock globali (vedi più avanti). Un primo test unitario su un hook personalizzato che formatta un prezzo:
// src/hooks/useFormatPrice.ts
import { useMemo } from 'react';
export function useFormatPrice(amount: number, currency = 'EUR') {
return useMemo(
() => new Intl.NumberFormat('it-IT', { style: 'currency', currency }).format(amount),
[amount, currency]
);
}
// src/hooks/useFormatPrice.test.ts
import { renderHook } from '@testing-library/react-native';
import { useFormatPrice } from './useFormatPrice';
describe('useFormatPrice', () => {
it('formatta euro con due decimali', () => {
const { result } = renderHook(() => useFormatPrice(1234.5));
expect(result.current).toBe('1.234,50 €');
});
it('supporta valute alternative', () => {
const { result } = renderHook(() => useFormatPrice(10, 'USD'));
expect(result.current).toMatch(/USD|\$/);
});
});
Jest individua automaticamente i file *.test.ts e *.test.tsx. Su una macchina Apple Silicon M3, la suite di un'app media (200 test) gira in meno di 4 secondi. Per il riferimento ufficiale del runner trovi tutto su la guida Jest.
Test di componenti con React Native Testing Library
React Native Testing Library (RNTL) 13 segue la filosofia "test the behavior, not the implementation". Invece di interrogare i nodi tramite testID, l'API raccomandata si appoggia a query semantiche: getByRole, getByLabelText, getByText. Effetto collaterale positivo: l'accessibilità migliora, perché obbliga ad assegnare ruoli e label corretti.
Esempio di un componente LoginForm che valida l'email e mostra un messaggio d'errore:
Se ti occupi anche di validazione lato form con librerie come React Hook Form, dai un'occhiata alla nostra guida su React Hook Form e Zod 4 in React Native: il pattern dei test con userEvent resta identico.
E2E semplici con Maestro
Maestro è uno strumento open-source di Mobile.dev che ha rapidamente eroso quote a Detox grazie a una caratteristica fondamentale: non richiede di modificare il codice nativo dell'app. Bastano file YAML dichiarativi. È particolarmente adatto a progetti Expo Managed Workflow dove non si vuole, o non si può, fare l'eject.
Installazione su macOS:
curl -Ls "https://get.maestro.mobile.dev" | bash
Un flusso E2E completo di login si scrive in 12 righe:
Esegui il test su un simulatore o dispositivo connesso:
maestro test .maestro/login.yaml
Maestro 1.39, rilasciato a marzo 2026, ha introdotto il comando maestro studio che apre una UI desktop con il rendering live del dispositivo e suggerisce automaticamente i selettori. Una bella comodità quando devi scrivere il primo flusso e non sai bene quali ID sono esposti. Per la CI esiste anche Maestro Cloud, che esegue i flussi su una farm di dispositivi reali senza configurazione locale.
Il limite di Maestro è la gestione di scenari molto dinamici (animazioni lunghe, WebView interne complesse): qui Detox resta superiore. Inoltre Maestro non ha un meccanismo nativo per intercettare le richieste di rete: se devi stubbare un'API, lo farai a monte tramite un mock server (msw, mockoon) o un build flavor dedicato.
E2E avanzati con Detox
Detox 20.30 è la scelta giusta quando hai un progetto bare (o un Expo Dev Client) e vuoi il massimo controllo. La sua arma vincente è la sincronizzazione automatica: Detox sa quando il bridge JS è idle, quando l'animazione è terminata e quando la rete è quieta, eliminando la maggior parte degli sleep() arbitrari.
Setup minimo:
npm install --save-dev detox jest-circus
npx detox init -L jest
Detox compila un binario di test (.app o .apk) e lo installa sul simulatore. La prima build richiede 2-3 minuti, ma le esecuzioni successive sono molto rapide grazie alla cache. Per dettagli sulla configurazione e i comandi detox build, fai riferimento alla documentazione ufficiale di Detox.
Come si fa il mock dei moduli nativi?
Il problema numero uno quando si configura Jest la prima volta è il crash di moduli nativi non disponibili nel runtime Node. Tipici colpevoli: expo-secure-store, react-native-mmkv, react-native-reanimated, expo-notifications. Ci sono cascato esattamente la prima volta che ho aperto un repo legacy senza setup, e mi ha portato via mezza mattinata.
La soluzione è centralizzare i mock in jest.setup.ts:
Per le richieste di rete, usa msw (Mock Service Worker) invece di stubbare fetch a mano: i test rispecchieranno la forma reale delle risposte API e sarai protetto da regressioni quando il backend cambia. Se invece testi liste performanti, ricorda che gli snapshot vanno presi su componenti già montati. Leggi la nostra analisi di FlatList vs FlashList v2 vs Legend List per capire come mockare gli observer del viewport.
Integrare i test in CI/CD con EAS Build e GitHub Actions
Una pipeline solida esegue tre job in parallelo: lint + type-check, unit + RNTL, E2E (Maestro Cloud). Esempio di workflow GitHub Actions:
name: CI
on: [push, pull_request]
jobs:
unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run type-check
- run: npm test -- --coverage --maxWorkers=2
- uses: codecov/codecov-action@v5
maestro:
runs-on: ubuntu-latest
needs: unit
steps:
- uses: actions/checkout@v4
- uses: mobile-dev-inc/action-maestro-cloud@v1
with:
api-key: ${{ secrets.MAESTRO_API_KEY }}
app-file: artifacts/app-release.apk
L'APK lo produce eas build --platform android --profile preview. Per i dettagli sulla pipeline EAS, vedi la nostra guida a EAS Build e Submit. In media, una suite di 250 unit test più 8 flussi Maestro completa in 6-8 minuti. Tieni d'occhio anche la concurrency policy di GitHub Actions per non sprecare minuti su push consecutivi sullo stesso branch.
Code coverage e soglie di qualità
La copertura del codice non è un fine in sé. È però un indicatore utile. Configura le soglie minime in package.json sotto jest.coverageThreshold:
Se la copertura scende sotto la soglia, Jest fa fallire il job e GitHub Actions blocca la PR. Strategia pragmatica: 80% sui moduli core (business logic, hook, riduttori) e 50% sui componenti puramente presentazionali. Icone e wrapper di stile non hanno bisogno di test, mentre la business logic dovrebbe avere copertura prossima al 100%. Strumenti come Codecov producono badge per il README e annotano direttamente le PR con i delta di copertura, rendendo il dato visibile durante la code review.
Maestro vs Detox: tabella di confronto
Caratteristica
Maestro 1.39
Detox 20.30
Linguaggio test
YAML dichiarativo
JavaScript/TypeScript
Richiede codice nativo
No (funziona su Expo Managed)
Sì (build personalizzata)
Sincronizzazione automatica
Parziale (timeout configurabile)
Completa (idle bridge + animazioni)
Curva di apprendimento
Bassa (1-2 ore)
Media (1-2 giorni)
Esecuzione su dispositivi reali
Sì, via Maestro Cloud
Solo con setup esterno (BrowserStack)
Velocità di esecuzione
~15-30s per flusso
~10-20s per test
Best fit
Smoke test, regression suite Expo
Suite E2E corposa, app bare workflow
Per la maggior parte dei team Expo, la combinazione che consiglio nel 2026 è: Jest + RNTL per i livelli bassi della piramide, Maestro per gli E2E. Detox entra in gioco solo se Maestro non riesce a coprire flussi specifici, ad esempio interazioni biometriche complesse, deep linking con scheme custom, gesture multi-touch. In ogni caso, il valore di una suite di test non sta nella sua dimensione ma nella sua affidabilità: dieci test deterministici sono molto più utili di cento test flaky che vengono ignorati a ogni red build.
Domande frequenti
Qual è la differenza tra Jest e Detox?
Jest è un test runner JavaScript che esegue test unitari e di componenti in un ambiente Node, senza dispositivo. Detox è un framework di end-to-end testing che installa l'app su un simulatore reale e simula le interazioni utente. Si usano insieme, non in alternativa.
Maestro è meglio di Detox per React Native?
Per la maggior parte dei progetti Expo, sì: Maestro è più semplice da configurare, non richiede di modificare il codice nativo e ha una sintassi YAML accessibile. Detox resta superiore per app bare con flussi complessi che richiedono sincronizzazione granulare con il bridge JS.
Come si fanno gli snapshot test in React Native?
Con Jest e React Native Testing Library basta chiamare expect(toJSON()).toMatchSnapshot() sul risultato di render(). Lo snapshot viene salvato in una cartella __snapshots__ e confrontato a ogni run. Usali solo per componenti stabili: su UI in continua evoluzione generano molto rumore nelle code review.
È necessario testare anche su dispositivi reali?
Sì, almeno prima di ogni release importante. Simulatori ed emulatori non riproducono fedelmente performance, GPU, sensori biometrici e ricezione push. Servizi come Maestro Cloud, BrowserStack o EAS Build con device profile coprono questa esigenza senza dover acquistare hardware.
Quanto codice dovrei coprire con i test?
Una soglia ragionevole per progetti React Native in produzione è 75-80% di linee per la business logic e 50-60% per i componenti UI. Più importante della percentuale assoluta è coprire i percorsi critici: autenticazione, pagamenti, sincronizzazione offline e flussi di onboarding.
Priya is a staff mobile engineer with nine years working in React Native, currently consulting for fintech and healthtech teams shipping on both stores from a single codebase. She spent four years at Klarna on the merchant-facing app, where she led the migration off a legacy Java Android codebase to React Native 0.68 and later drove the New Architecture rollout (Fabric + TurboModules) for roughly 14 million MAU.
Before Klarna she was at Coinbase on the wallet team, writing native bridges to Secure Enclave and Android Keystore. She maintains two small open-source libraries for biometric auth and contributes occasional PRs to react-native-screens. She writes here mostly about performance profiling with Flipper and Hermes, EAS Build pipelines, and the practical headaches of running a brownfield RN app inside a 12-year-old iOS host.