jeudi 4 février 2021

How to verify a widget is offstage

given the code sample below (also runnable on dartpad)

import 'package:flutter/material.dart';

class MyKeys {
  static const TEST_KEY = ValueKey('test');
  static const FAB_KEY = ValueKey('fab');
}

final _onStage = ValueNotifier<bool>(true);

void main() => runApp(k_MY_APP);

const k_MY_APP = MaterialApp(
  home: Scaffold(
    body: MyStage(),
    floatingActionButton: MyFAB(),
  ),
);

class MyFAB extends StatelessWidget {
  const MyFAB() : super(key: const ValueKey('MyFAB'));

  @override
  Widget build(BuildContext context) => FloatingActionButton(
        key: MyKeys.FAB_KEY,
        onPressed: () => _onStage.value = !_onStage.value,
      );
}

class MyStage extends StatelessWidget {
  const MyStage() : super(key: const ValueKey('MyStage'));

  @override
  Widget build(BuildContext context) => Stack(
        children: [
          ValueListenableBuilder(
            child: const FlutterLogo(
              key: MyKeys.TEST_KEY,
            ),
            valueListenable: _onStage,
            builder: (context, isOnStage, child) => AnimatedPositioned(
              top: MediaQuery.of(context).size.height *
                  (_onStage.value ? .5 : -1),
              child: child,
              duration: const Duration(milliseconds: 100),
            ),
          ),
        ],
      );
}


I have difficulties to test the FlutterLogo being offscreen pressingFAB

here's the test code

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

void main() {
  testWidgets('...', (tester) async {
    await tester.pumpWidget(k_MY_APP);
    expect(
      find.byKey(
        MyKeys.TEST_KEY,
      ),
      findsOneWidget,
      reason: 'widget ${MyKeys.TEST_KEY}  should be found',
    );
    expect(
        find.byKey(
          MyKeys.TEST_KEY,
        ),
        isOnstage,
        reason: 'widget ${MyKeys.TEST_KEY}  should be `onStage`,');

    await tester.tap(find.byKey(MyKeys.FAB_KEY));
    await tester.pumpAndSettle(Duration(milliseconds: 300));
    expect(
        find.byKey(
          MyKeys.TEST_KEY,
        ),
        isOffstage,
        reason: 'widget ${MyKeys.TEST_KEY}  should be `offStage`,');
  });
}

and the logs

00:02 +0: ...                                                                                                                                                                                               
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure object was thrown running a test:
  Expected: offstage
  Actual: _KeyFinder:<exactly one widget with key [<'test'>] (ignoring offstage widgets):
FlutterLogo-[<'test'>](dependencies: [IconTheme])>
widget [<'test'>]  should be `offStage`,

When the exception was thrown, this was the stack:
#4      main.<anonymous closure> (file:///home/francesco/projects/issue/test/widget_test.dart:23:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)
...

This was caught by the test expectation on the following line:
  file:///home/francesco/projects/issue/test/widget_test.dart line 23
The test description was:
  ...
════════════════════════════════════════════════════════════════════════════════════════════════════
00:02 +0 -1: ... [E]                                                                                                                                                                                        
  Test failed. See exception logs above.
  The test description was: ...
  
00:03 +0 -1: Some tests failed.           

what am I missing?

Aucun commentaire:

Enregistrer un commentaire