×Закрыть

Какие тесты должен писать тестировщик на Flutter

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті.

Привет всем тестерам, которые хотят разобраться в автоматизации на Flutter. Меня зовут Таня и я QA Engineer в компании Appvesto. В этой статье хочу поделиться тем, какие тесты пишу я, и детально разобрать каждый шаг для их написания. Ну что ж, поехали.

Виджет-тесты (Widget testing)

Что ж такое виджет тесты? Виджет тесты тестируют один виджет и направлены на то, чтобы убедиться что интерфейс выглядит и взаимодействует с пользователем так, как было запланировано. Тестирование виджета включает несколько классов и требует тестовой среды, которая предоставляет соответствующий контекст жизненного цикла виджета.

Для тестирования классов виджетов вам понадобится пакет flutter_test, в котором содержится несколько дополнительных инструментов, такие как:

  1. WidgetTester, который позволяет создавать виджеты и взаимодействовать с ними в тестовой среде;
  2. Функция testWidgets (), которая автоматически создает новый WidgetTester для каждого тестового примера и используется вместо обычной функции test ();
  3. Классы Finder позволяют искать виджеты в тестовой среде;
  4. Константы 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.

Желаю всем легкого написания тестов и нахождения серьезных багов)))

👍НравитсяПонравилось0
В избранноеВ избранном3
Подписаться на тему «Flutter»
LinkedIn

Похожие статьи

Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Подписаться на комментарии