2
votes

Comment trouver un enfant ListView hors écran dans les tests de widget?

Lors de l'affichage de plusieurs enfants dans une ListView, si un enfant est hors écran, il ne peut pas être trouvé par un test de widget. Voici un exemple complet:

main.dart

import 'package:flutter_app/main.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets("Find text", (WidgetTester tester) async {
    final testableWidget = App();

    await tester.pumpWidget(testableWidget);

    expect(find.text("Find me!"), findsOneWidget);
  });
}

main_test.dart

import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: Scaffold(body: Test()));
  }
}

class Test extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        Container(
          height: 600,
          color: Colors.red,
        ),
        Text("Find me!"),
      ],
    );
  }
}

Ce test échoue, cependant si Je change la hauteur du Container dans main.dart en 599 cela fonctionne.

Quelqu'un sait pourquoi cela se produit? Est-ce un bug? Y a-t-il un moyen de contourner cela?


0 commentaires

3 Réponses :


5
votes

Les tests doivent se comporter comme le ferait votre application, sinon vos tests deviennent inutiles (puisque vous ne testez pas le comportement réel). En tant que tel, ce n'est pas un bogue.

Vous devez faire défiler manuellement la ListView à l'intérieur de vos tests pour lui faire charger plus de widgets.

Cela peut être fait en utilisant testeur :

final gesture = await tester.startGesture(Offset.zero /* THe position of your listview */ );
// Manual scroll
await gesture.moveBy(const Offset(0, 100));

await tester.pump(); // flush the widget tree 


2 commentaires

Ahh ok, ça a du sens. Merci.


Il convient de mentionner que vous pouvez également faire glisser un widget qui se trouve dans la vue de liste: wait tester.drag (find.byType (Container), Offset (0.0, -200)); attendre tester.pump ();



2
votes

Le simple réglage de skipOffstate sur false résoudra probablement ce problème:

await tester.ensureVisible(find.text("Find me!", skipOffstage: false));
await tester.pumpAndSettle();

expect(find.text("Find me!"), findsOneWidget);

De plus, vous pouvez utiliser WidgetTester code > pratique ensureVisible pour faire défiler la ListView et assurez-vous que le widget spécifié par le chercheur est visible.

expect(find.text("Find me!", skipOffstage: false), findsOneWidget);


0 commentaires

0
votes

Je vous recommande vivement de faire attention au "plan cartésien" de votre écran / mouvement de glissement.

Laissez-moi vous expliquer:

  1. Vous devez utiliser: attendre tester.drag (keyCartItemProduct1, Offset (-500.0, 0.0));
  2. Cependant, votre commande "Décalage" doit obéir à la même "direction cartésienne" que votre déplacement.

2.1) Par conséquent: (La commande Offset utilise des 'directions' cartésiennes) - voyons: a) Glissement vers la gauche: décalage (-500,0, 0,0) b) Glissement à droite: décalage (+500,0, 0,0) c) Glissement vers le haut: Décalage (0.0, +500.0) d) Glisser vers le bas: Décalage (0.0, -500.0)


0 commentaires