Скажем, я хочу заявить, что при вводе текста в виджет панели поиска текст-заполнитель исчезает. Это на самом деле просто тестирование инфраструктуры 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)
Есть ли лучший способ сделать это?