Какие тесты должен писать тестировщик на 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.
Желаю всем легкого написания тестов и нахождения серьезных багов)))
Немає коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів