Les proves de widgets són una part essencial del desenvolupament d'aplicacions en Flutter. Aquest tipus de proves permeten verificar que els widgets es comporten com s'espera en diferents situacions. En aquesta secció, aprendrem com crear i executar proves de widgets per assegurar-nos que la nostra interfície d'usuari funcioni correctament.

Objectius d'Aprenentatge

  • Comprendre la importància de les proves de widgets.
  • Aprendre a configurar un entorn de proves de widgets.
  • Escriure i executar proves de widgets bàsiques.
  • Utilitzar WidgetTester per interactuar amb els widgets durant les proves.

  1. Importància de les Proves de Widgets

Les proves de widgets són crucials per diverses raons:

  • Verificació de la UI: Asseguren que la interfície d'usuari es mostri correctament.
  • Detecció de Regressions: Identifiquen canvis no desitjats en la UI després de modificacions en el codi.
  • Automatització: Permeten automatitzar la verificació de la funcionalitat de la UI, estalviant temps i esforç.

  1. Configuració de l'Entorn de Proves

Abans de començar a escriure proves de widgets, necessitem configurar l'entorn de proves. Flutter proporciona un paquet de proves integrat que facilita aquesta tasca.

Passos per Configurar l'Entorn de Proves

  1. Afegir el paquet de proves: Assegura't que el paquet flutter_test estigui inclòs en el fitxer pubspec.yaml:

    dev_dependencies:
      flutter_test:
        sdk: flutter
    
  2. Crear un fitxer de proves: Crea un fitxer nou dins del directori test/. Per exemple, test/widget_test.dart.

  1. Escriure una Prova de Widget Bàsica

A continuació, escriurem una prova de widget bàsica per verificar que un widget es mostra correctament.

Exemple de Prova de Widget

Suposem que tenim un widget senzill que mostra un text "Hola, món!".

Codi del Widget

import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text('Hola, món!'),
        ),
      ),
    );
  }
}

Codi de la Prova

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/my_widget.dart'; // Assegura't d'importar el widget correcte

void main() {
  testWidgets('MyWidget mostra el text "Hola, món!"', (WidgetTester tester) async {
    // Construir el widget dins del tester
    await tester.pumpWidget(MyWidget());

    // Verificar que el text "Hola, món!" es mostri en pantalla
    expect(find.text('Hola, món!'), findsOneWidget);
  });
}

Explicació del Codi de la Prova

  • testWidgets: Defineix una prova de widget. Accepta una descripció de la prova i una funció que conté el codi de la prova.
  • WidgetTester: Proporciona mètodes per interactuar amb els widgets durant la prova.
  • pumpWidget: Construeix el widget dins del tester.
  • find.text: Cerca un widget de text amb el contingut especificat.
  • expect: Verifica que la condició especificada sigui certa. En aquest cas, que hi hagi exactament un widget amb el text "Hola, món!".

  1. Utilitzar WidgetTester per Interactuar amb Widgets

El WidgetTester proporciona diverses funcions per interactuar amb els widgets durant les proves. A continuació, veurem alguns exemples comuns.

Exemple: Prova d'un Botó

Suposem que tenim un widget amb un botó que incrementa un comptador.

Codi del Widget

import 'package:flutter/material.dart';

class CounterWidget extends StatefulWidget {
  @override
  _CounterWidgetState createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Counter')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('$_counter', key: Key('counter')),
              ElevatedButton(
                onPressed: _incrementCounter,
                child: Text('Incrementar'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Codi de la Prova

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/counter_widget.dart'; // Assegura't d'importar el widget correcte

void main() {
  testWidgets('CounterWidget incrementa el comptador quan es prem el botó', (WidgetTester tester) async {
    // Construir el widget dins del tester
    await tester.pumpWidget(CounterWidget());

    // Verificar que el comptador inicialment és 0
    expect(find.text('0'), findsOneWidget);

    // Prem el botó
    await tester.tap(find.byType(ElevatedButton));
    await tester.pump(); // Re-dibuixar el widget després de l'acció

    // Verificar que el comptador ha incrementat a 1
    expect(find.text('1'), findsOneWidget);
  });
}

Explicació del Codi de la Prova

  • tap: Simula un toc en el widget especificat.
  • pump: Re-dibuixa el widget després d'una acció, permetent que els canvis es reflecteixin en la UI.

Exercicis Pràctics

  1. Prova de TextField: Escriu una prova per verificar que un TextField accepta i mostra correctament el text introduït per l'usuari.
  2. Prova de Checkbox: Escriu una prova per verificar que un Checkbox canvia el seu estat quan es prem.

Solucions

Prova de TextField

testWidgets('TextField accepta i mostra el text introduït', (WidgetTester tester) async {
  // Construir el widget amb un TextField
  await tester.pumpWidget(MaterialApp(
    home: Scaffold(
      body: TextField(key: Key('textField')),
    ),
  ));

  // Introduir text al TextField
  await tester.enterText(find.byKey(Key('textField')), 'Hola Flutter');
  await tester.pump();

  // Verificar que el TextField mostra el text introduït
  expect(find.text('Hola Flutter'), findsOneWidget);
});

Prova de Checkbox

testWidgets('Checkbox canvia el seu estat quan es prem', (WidgetTester tester) async {
  bool isChecked = false;

  // Construir el widget amb un Checkbox
  await tester.pumpWidget(MaterialApp(
    home: Scaffold(
      body: StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return Checkbox(
            value: isChecked,
            onChanged: (bool? value) {
              setState(() {
                isChecked = value!;
              });
            },
          );
        },
      ),
    ),
  ));

  // Verificar que el Checkbox inicialment no està seleccionat
  expect(find.byType(Checkbox), findsOneWidget);
  expect((tester.widget(find.byType(Checkbox)) as Checkbox).value, false);

  // Prem el Checkbox
  await tester.tap(find.byType(Checkbox));
  await tester.pump();

  // Verificar que el Checkbox està seleccionat
  expect((tester.widget(find.byType(Checkbox)) as Checkbox).value, true);
});

Conclusió

Les proves de widgets són una eina poderosa per assegurar la qualitat de la interfície d'usuari en aplicacions Flutter. Hem après a configurar l'entorn de proves, escriure proves de widgets bàsiques i utilitzar WidgetTester per interactuar amb els widgets. Amb aquestes habilitats, estem preparats per crear aplicacions més robustes i fiables.

Curs de Desenvolupament Flutter

Mòdul 1: Introducció a Flutter

Mòdul 2: Conceptes Bàsics de Programació en Dart

Mòdul 3: Widgets de Flutter

Mòdul 4: Gestió de l'Estat

Mòdul 5: Navegació i Enrutament

Mòdul 6: Xarxes i APIs

Mòdul 7: Persistència i Emmagatzematge

Mòdul 8: Conceptes Avançats de Flutter

Mòdul 9: Proves i Depuració

Mòdul 10: Desplegament i Manteniment

Mòdul 11: Flutter per a Web i Escriptori

© Copyright 2024. Tots els drets reservats