Какие тесты должен писать тестировщик на Flutter
Привет всем тестерам, которые хотят разобраться в автоматизации на Flutter. Меня зовут Таня и я QA Engineer в компании Appvesto. В этой статье хочу поделиться тем, какие тесты пишу я, и детально разобрать каждый шаг для их написания. Ну что ж, поехали.
Виджет-тесты (Widget testing)
Что ж такое виджет тесты? Виджет тесты тестируют один виджет и направлены на то, чтобы убедиться что интерфейс выглядит и взаимодействует с пользователем так, как было запланировано. Тестирование виджета включает несколько классов и требует тестовой среды, которая предоставляет соответствующий контекст жизненного цикла виджета.
Для тестирования классов виджетов вам понадобится пакет flutter_test
, в котором содержится несколько дополнительных инструментов, такие как:
WidgetTester
, который позволяет создавать виджеты и взаимодействовать с ними в тестовой среде;- Функция
testWidgets ()
, которая автоматически создает новыйWidgetTester
для каждого тестового примера и используется вместо обычной функцииtest ()
; - Классы
Finder
позволяют искать виджеты в тестовой среде; - Константы Matcher для конкретных виджетов помогают проверить, обнаруживает ли Finder виджет или несколько виджетов в тестовой среде.
Теперь рассмотрим как же писать эти самые тесты, и что в результате мы получим:
1. Для начала все же добавим пакет flutter_test
в раздел dev_dependencies
, в pubspec.yaml
файл. Если вы создаете новый flutter проект, то этот пакет уже добавлен.
dev_dependencies: flutter_test: sdk: flutter
2. Создадим виджет, который будем тестировать. Я, для примера, создаю форму с одним полем и кнопкой. Ожидаемым результатом будет отображение вводимого слова на следующей странице.
void main() => runApp( MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { var _textController = TextEditingController(); @override Widget build(BuildContext context) { return new Scaffold( appBar: AppBar( title: Text("Home Page"), ), body: ListView( children: <Widget>[ ListTile( title: TextFormField( key: Key('textField'), controller: _textController, ), ), ListTile( title: RaisedButton( key: Key("button"), child: Text("Next"), onPressed: () { var route = MaterialPageRoute( builder: (BuildContext context) => NextPage(value: _textController.text), ); Navigator.of(context).push(route); }, ), ), ], ), ); } } class NextPage extends StatefulWidget { final String value; NextPage({Key key, this.value}) : super(key: key); @override _NextPageState createState() => _NextPageState(); } class _NextPageState extends State<NextPage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Next Page"), ), body: Text("${widget.value}"), ); } }
И вот результат:
3. Теперь можем приступать к написанию теста. Открываем папку test
, или же создаем если у вас ее нет. В папке хранится файл widget_test.dart
, в котором мы и будем творить наши тесты. Для этого нам понадобится функция testWidgets()
, которая предоставляется пакетом flutter_test
:
import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('Test form', (WidgetTester tester) async { // CODE. }); } }
4. Далее с помощью pumpWidget()
метода мы отображаем созданный нами виджет:
import 'package:flutter_test/flutter_test.dart'; import 'package:test_article/main.dart'; void main() { testWidgets('Test form', (WidgetTester tester) async { await tester.pumpWidget(MyApp()); }); }
С помощью виджета, в тестовой среде, выполняем поиск в дереве виджетов с помощью Finder. Это позволяет проверить правильность отображения виджетов. Для этого используйте метод find()
, предоставляемый пакетом flutter_test
, для создания Finders. Я обычно использую поиск по типу — find.byType()
и по ключу — find.byKey()
, вы же можете использовать также поиск по тексту — find.text()
, по иконке — find.byIcon()
.
import 'package:flutter_test/flutter_test.dart'; import 'package:test_article/main.dart'; void main() { testWidgets('Test form', (WidgetTester tester) async { await tester.pumpWidget(MyApp()); final textfield = find.byType(TextFormField); final button = find.byType(RaisedButton); }); }
Убедитесь, что виджет поля и кнопки отображаются на экране с помощью Matcher
. Это способ проверить ожидаемый результат:
import 'package:flutter_test/flutter_test.dart'; import 'package:test_article/main.dart'; void main() { testWidgets('Counter increments ', (WidgetTester tester) async { await tester.pumpWidget(MyApp()); final textfield = find.byType(TextFormField); final button = find.byType(RaisedButton); expect (textfield,findsOneWidget); expect(button, findsOneWidget); }); }
Рассмотрим как мы можем поменять состояние виджета и взаимодействовать с ним. Вот пару методов для изменения состояния:tap
— отправить виджету нажатие;longPress
— длинное нажатие;fling
— смахивание/свайп;drag
— перенос;enterText
— ввод текста.
Я хочу заполнить поле и нажать на кнопку. И вот результат:
void main() { testWidgets('Counter increments ', (WidgetTester tester) async { await tester.pumpWidget(MyApp()); await tester.enterText(find.byKey(Key("textField")),'test'); await tester.tap(find.byType(RaisedButton)); }); }
И наконец-то запуск теста. Я запускаю из консоли с помощью команды, в которой указываю имя файла:
$ flutter test test/widget_test.dart
Если все ваши тесты пройдены то в консоли вы получите: All tests passed!
Интеграционные тесты (Integration testing)
Теперь предлагаю разобраться, что ж такое интеграционное тестирование. Как по мне, оно более интересное и с помощью него можно проверить все приложение. Могу сказать что оно, в каком-то случае, может заменить вам ручное тестирование.
Это тестирование, которое прогоняет всe приложение на эмуляторе или же на реальном устройстве, и дает результат о прохождении теста.
А теперь разберем как же писать такие тесты....
1. Создаем виджет для тестирования. Я использую тот же, что и для Виджет тестов.
2. Для интеграционных тестов используется пакет test_driver
. Добавим его в раздел dev_dependencies
, в pubspec.yaml
файл.
dev_dependencies: flutter_driver: sdk: flutter test: any
3. Теперь нам понадобятся два файла: main.dart
, main_test.dart
, которые находятся в одной директории test_driver
(необходимо создать).
Первый файл содержит «оснащенную» версию приложения. Инструментарий позволяет вам «управлять» приложением.
Второй файл содержит набор тестов, который запускает приложение и проверяет, работает ли оно должным образом. Имя тестового файла должно соответствовать имени файла, содержащего инструментальное приложение, с добавлением _test
в конце.
4. Добавляем код в main.dart
файл:
import 'package:flutter_driver/driver_extension.dart'; import 'package:test_article/main.dart' as app; void main() { enableFlutterDriverExtension(); app.main(); }
5. И теперь можем начинать писать наши тесты. Для этого открываем наш второй файл main_test.dart
.
С помощью setUpAll()
команды мы подключаемся к приложению до проведения тестов. Для отключения от приложения используем tearDownAll()
.
import 'package:flutter_driver/flutter_driver.dart'; import 'package:test/test.dart'; void main() { group('Counter App', () { final textfield = find.byValueKey('textField'); final button = find.byValueKey('button'); final nextPage = find.byValueKey('nextPage'); FlutterDriver driver; // Подключение к Flutter driver перед выполнением теста setUpAll(() async { driver = await FlutterDriver.connect(); }); tearDownAll(() async { if (driver != null) { driver.close(); } }); // Конец подсоединения driver после выполнения тестов test('fill the field', () async { await driver.waitFor(textfield); //Задержка await waitTime(); await driver.tap(textfield); await waitTime(); await driver.enterText('Test'); await waitTime(); await driver.tap(button); await waitTime(); }); }, timeout: Timeout(Duration(seconds: 10))); } //Задерживает часть асинхронной функции void waitTime([int seconds = 1]) async { await Future.delayed(Duration(seconds: seconds)); }
6. Запустим наш тест. Для начала запустите эмулятор/симулятор. Затем используем команду и наблюдаем как за вас делают тесты: $ flutter drive --target=test_driver/main.dart
Заключение
Ну что ж, вот и все. Если до этого вы еще не писали авто тесты, хочу вас поздравить, вы сделали первый шаг. Или же если вы уже сталкивались с ними, то возможно узнали что-то новое для себя.Мы рассмотрели введение в написание авто тестов на Flutter для тестировщиков. Простые тесты для формы с полем и кнопкой, которые вы можете усложнить и сделать, например, для формы авторизации.
Дополнительную информацию по тестам вы всегда можете найти на официальном сайте Flutter.
Желаю всем легкого написания тестов и нахождения серьезных багов)))
Немає коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів