Как утверждать, что текст-заполнитель исчезает в тесте виджета Flutter? - PullRequest
0 голосов
/ 03 октября 2019

Скажем, я хочу заявить, что при вводе текста в виджет панели поиска текст-заполнитель исчезает. Это на самом деле просто тестирование инфраструктуры Flutter, но это первый тест виджетов, который я попытался просто понять, как проводить тестирование виджетов, и он касается того, что он не просто работает.

Пройдите тестирование следующего виджета SearchBar:

import 'package:flutter/material.dart';

const BorderRadius _kBorderRadius = BorderRadius.all(Radius.circular(32.0));
const Color _kBorderColor = Color(0xFF33BFCC);

class SearchBar extends StatelessWidget {
  SearchBar({this.onClose, this.onChanged});

  final Function onClose;
  final Function onChanged;

  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: onChanged,
      decoration: InputDecoration(
        suffixIcon: IconButton(
          icon: Icon(Icons.close),
          onPressed: onClose,
        ),
        fillColor: Colors.white,
        filled: true,
        hintText: 'Search',
        contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
        border: OutlineInputBorder(
          borderRadius: _kBorderRadius,
        ),
        enabledBorder: OutlineInputBorder(
          borderSide: BorderSide(color: _kBorderColor, width: 1.0),
          borderRadius: _kBorderRadius,
        ),
        focusedBorder: OutlineInputBorder(
          borderSide: BorderSide(color: _kBorderColor, width: 2.0),
          borderRadius: _kBorderRadius,
        ),
      ),
    );
  }
}

и следующий тест этого виджета:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:my_app/ui_components/search_bar.dart';

void main() {
  testWidgets('entering text removes placeholder text',
      (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(home: Scaffold(body: SearchBar())));

    await tester.enterText(find.byType(TextField), 'hi');
    await tester.pumpAndSettle();

    final placeholderFinder = find.text('Search');
    final textFinder = find.text('hi');

    expect(textFinder, findsOneWidget);
    expect(placeholderFinder, findsNothing);
  });
}

Этот тест не пройден, поскольку текст «Поиск» все еще найден. Глядя на , как Flutter тестирует свои собственные текстовые поля , они, похоже, используют трюк с непрозрачностью. Если я попробую тот же трюк, заменив

expect(placeholderFinder, findsNothing);

на

expect(getOpacity(tester, placeholderFinder), 0.0);

, где getOpacity определяется как:

double getOpacity(WidgetTester tester, Finder finder) {
  return tester
      .widget<FadeTransition>(
        find.ancestor(
          of: finder,
          matching: find.byType(FadeTransition),
        ),
      )
      .opacity
      .value;
}

, я получаю следующую ошибку:

При выполнении теста было сгенерировано следующее StateError: Плохое состояние: слишком много элементов При создании исключения это был стек: 0 Iterable.single (dart: core / iterable.dart: 554:24) 1 WidgetController.widget (пакет: flutter_test / src / controller.dart: 65: 30)

Есть ли лучший способ сделать это?

...