Основы Flutter для начинающих (Часть IX)

от автора

Flutter позволяет вам писать простые и понятные тесты для разных частей приложения.

Сегодня мы попробуем написать несколько unit тестов, которые используются для тестирования классов, методов и отдельных функций.

Также мы попробуем использовать библиотеку Mockito, которая позволяет создавать фейковые реализации.

Ну что ж, приступаем к тестированию!

Наш план
  • Часть 1 — введение в разработку, первое приложение, понятие состояния;

  • Часть 2 — файл pubspec.yaml и использование flutter в командной строке;

  • Часть 3 — BottomNavigationBar и Navigator;

  • Часть 4 — MVC. Мы будем использовать именно этот паттерн, как один из самых простых;

  • Часть 5 — http пакет. Создание Repository класса, первые запросы, вывод списка постов;

  • Часть 6 — работа с формами, текстовые поля и создание поста.

  • Часть 7 — работа с картинками, вывод картинок в виде сетки, получение картинок из сети, добавление своих в приложение;

  • Часть 8 — создание своей темы, добавление кастомных шрифтов и анимации;

  • Часть 9 (текущая статья) — немного о тестировании;

Добавления необходимых зависимостей

Нам понадобиться два дополнительных пакета mockito и build_runner, поэтому добавим их:

# зависимости для разработки # в данном случае подключено тестирование dev_dependencies:   flutter_test:     sdk: flutter   mockito: ^5.0.10   build_runner: ^2.0.4

Теперь мы можем приступать к тестированию

Пишем первый тест

В качестве объекта тестирования будет небольшой класс Stack:

class Stack<T> {   final stack = <T>[];      void push(T t) {     stack.add(t);   }      T? pop() {     if (isEmpty) {       return null;     }     return stack.removeLast();   }      bool get isEmpty => stack.isEmpty;  } 

Обратите внимание: класс Stack является обобщенным.

В корневой директории нашего проекта есть папка test, которая предназначена для тестов.

Создадим в ней новый файл stack_test.dart:

import 'package:flutter_test/flutter_test.dart'; import 'package:json_placeholder_app/helpers/stack.dart';  void main() {   // группа тестов   group("Stack", () {     // первый тест на пустой стек     test("Stack should be empty", () {       // expect принимает текущее значение        // и сравнивает его с правильным       // если значения не совпадают, тест не пройден       expect(Stack().isEmpty, true);     });     test("Stack shouldn't be empty", () {       final stack = Stack<int>();       stack.push(5);       expect(stack.isEmpty, false);     });     test("Stack should be popped", () {       final stack = Stack<int>();       stack.push(5);       expect(stack.pop(), 5);     });     test("Stack should be work correctly", () {       final stack = Stack<int>();       stack.push(1);       stack.push(2);       stack.push(5);       expect(stack.pop(), 5);       expect(stack.pop(), 2);       expect(stack.isEmpty, false);     });   }); }

Довольно просто! Не правда ли?

На самом деле, это один из типов тестирования, который называется unit (модульное).

Также Flutter поддерживает:

  • Widget тестирование

  • Интеграционное тестирование

В данной статье мы рассмотрим только unit тестирование.

Давайте выполним наши тесты командой flutter test test/stack_test.dart:

Успешно!

Тестируем получение постов

Сначала видоизменим метод fetchPosts:

Future<PostList> fetchPosts({http.Client? client}) async {   // сначала создаем URL, по которому   // мы будем делать запрос   final url = Uri.parse("$SERVER/posts");   // делаем GET запрос   final response =  (client == null) ? await http.get(url) : await client.get(url);   // проверяем статус ответа   if (response.statusCode == 200) {     // если все ок то возвращаем посты     // json.decode парсит ответ     return PostList.fromJson(json.decode(response.body));   } else {     // в противном случае вызываем исключение     throw Exception("failed request");   } }

Теперь переходим к написанию самого теста.

Мы будем использовать mockito для создания фейкового http.Client'а

Создадим файл post_test.dart в папке tests:

import 'package:flutter_test/flutter_test.dart'; import 'package:http/http.dart' as http; import 'package:json_placeholder_app/data/repository.dart'; import 'package:json_placeholder_app/models/post.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart';  // данный файл будет сгенерирован import 'post_test.mocks.dart';  // аннотация mockito @GenerateMocks([http.Client]) void main() {   // создаем наш репозиторий   final repo = Repository();   group("fetchPosts", () {       test('returns posts if the http call completes successfully', () async {         // создаем фейковый клиент         final client = MockClient();          // ответ на запрос         when(client.get(Uri.parse('https://jsonplaceholder.typicode.com/posts')))             .thenAnswer((_) async => http.Response('[{"userId": 1, "id": 2, "title": "Title", "content": "Content"}]', 200));          // проверяем корректность работы fetchPosts         // при удачном выполнении         final postList = await repo.fetchPosts(client: client);         expect(postList, isA<PostList>());         expect(postList.posts.length, 1);         expect(postList.posts.first.title, "Title");       });        test('throws an exception if the http call completes with an error', () {         final client = MockClient();          // генерация ошибки         when(client.get(Uri.parse('https://jsonplaceholder.typicode.com/posts')))             .thenAnswer((_) async => http.Response('Not Found', 404));          // проверка на исключение         expect(repo.fetchPosts(client: client), throwsException);       });   }); }

Перед запуском теста необходимо сгенерировать post_test.mocks.dart файл:

flutter pub run build_runner build

После этого выполняем наши тесты командой flutter test test/post_test.dart:

Вуаля!

Заключение

Мы разобрали один из самых простых и известных типов тестирования — unit (модульное).

Как уже было отмечено, Flutter позволяет отдельно тестировать виджеты, а также проводить полноценное тестирование с применением интеграционных тестов.

Полезные ссылки:

Всем хорошего кода!

ссылка на оригинал статьи https://habr.com/ru/post/562352/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *