Тестовые примеры DART | Часть 2

Тестовые примеры DART | Часть 2
Тестовые примеры DART | Часть 2

Привет, если вы на пути изучения Flutter/Dart или вам просто интересно почитать про разработку подписывайтесь на мой канал в telegram, буду рад вас видеть! А сегодня поговорим про тестовые примеры в DART-е!

Предыдущая статья: Тестовые примеры DART | Часть 1

Группировка нескольких модульных тестов

Проблема

Вам нужен способ выполнить несколько модульных тестов для кода вашего приложения.

Решение

Создание нескольких модульных тестов выполняется по той же схеме, что и создание одного модульного теста. В примере мы используем шаблон AAA, что означает, что мы упорядочиваем значение, выполняем действие и подтверждаем достоверность результата.

Вот пример того, как использовать несколько тестов в Dart, используя наш файл с именем travel_test.dart:

import 'package:test_dart_sample/test_dart_sample.dart'; import 'package:test/test.dart'; void main() { test('Travel Distance', () { // Arrange var distance = 10.0; var expectedDistance = distance; // Act var travel = Travel(expectedDistance); var result = travel.distance; // Assert expect(expectedDistance, result); }); test('Travel Distance to Miles', () { // Arrange var miles = 10.0; var expectedMiles = miles * convertToMiles; // Act var travel = Travel(miles); var result = travel.distanceToMiles(); // Assert expect(expectedMiles, result); }); test('Travel Distance to Kilometers', () { // Arrange var kilometers = 10.0; var expectedKiloMeters = kilometers * convertToKilometers; // Act var travel = Travel(kilometers); var result = travel.distanceToKilometers(); // Assert expect(expectedKiloMeters, result); }); }
Тестовые примеры DART | Часть 2
Тестовые примеры DART | Часть 2

Чтобы запустить предыдущий тест, используйте тест dart для запуска кода и просмотра результатов:

dart test

Результат должен свидетельствовать о том, что все тесты успешно пройдены:

00:00 +0: Travel Distance
00:00 +1: All tests passed!

Обсуждение

В примере кода у нас определены три теста, как показано на рисунке 6-3. Аналогично однократному запуску теста, мы сначала проверяем, что объект класса Travel был успешно инициализирован значением расстояния. Кроме того, мы также тестируем методы, связанные с преобразованием в мили и километры соответственно.

Рисунок 6-3. Пример множественных модульных тестов
Рисунок 6-3. Пример множественных модульных тестов

Дополнительные тесты для миль и километров сосредоточены на соответствующих преобразованиях. На рисунке 6-3 показано, как шаблон AAA обеспечивает хорошую основу для того, чтобы наши тесты следовали схожей структуре, несмотря на проверку разных результатов.

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

При создании тестов у вас есть возможность добавить тестовые примеры в один файл или разбить их на несколько тестовых файлов. Лично мне нравится использовать один файл для прямой ссылки на файл модульного теста, основанный на соглашении об именовании файлов Dart. Таким образом, наш файл travel.dart будет содержать соответствующий travel_test.файл dart, содержащий соответствующие тесты для этого определения класса.

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

Проблема

У вас нет доступа к данным, необходимым для тестирования вашего приложения. Фиктивные данные могут быть невероятно полезны там, где базовые данные недоступны или на них распространяются ограничения сервиса, например, когда вам разрешено вызывать API только определенное количество раз (т.е. ограничение скорости API).

Решение

Добавьте макетный интерфейс в свое приложение, чтобы обеспечить выполнение требований к данным с помощью временных данных, созданных специально для тестирования.

Вот пример того, как создать макетный вызов API, который возвращает некоторые данные:

import 'package:test_dart_sample/test_dart_sample.dart'; import 'package:test/test.dart'; Future <double> _loadResource(int testDelay) async { try { await Future.delayed(Duration(seconds: testDelay)); return 10.0; } catch (e) { print(e); return 0.0; } } void main() { test('Travel Distance Delay', () async { // Arrange int customDelay = 5; var distance = await _loadResource(customDelay); var expectedDistance = distance; // Act var travel = Travel(expectedDistance); var result = travel.distance; // Assert expect(expectedDistance, result); }); }

Чтобы запустить предыдущий тест, используйте тест dart для запуска кода и просмотра результатов:

dart test

Результат должен свидетельствовать о том, что все тесты успешно пройдены:

00:00 +0: Travel Distance Delay
00:05 +1: All tests passed!

Обсуждение

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

На рисунке 6-4 для задачи установлена настраиваемая задержка, в данном случае пять секунд, чтобы воспроизвести медленную загрузку. Когда тест будет выполнен в командной строке, вы увидите, что тест испытывает задержку примерно в пять секунд для воспроизведения сценария загрузки в реальном мире. Если вы измените задержку, время, затраченное на тест, будет соответствовать продолжительности, установленной для значения задержки. Вы можете узнать больше о том, как включить Future.

Рисунок 6-4. Использование макетных данных для модульных тестов
Рисунок 6-4. Использование макетных данных для модульных тестов

Чтобы выполнить это действие, имитирующее извлечение внешних данных, используйте Future для запуска асинхронной задачи. Асинхронная операция - это операция, при которой программа может выполнять другую работу, ожидая завершения задачи. Обычно асинхронная задача сопровождается ключевым словом await, которое указывает, что для завершения возвращаемого значения может потребоваться некоторое время.

Внедрение макетного ответа устраняет препятствие для разработки, а также обеспечивает простой механизм обеспечения гарантии качества. Добавление макетного интерфейса может обеспечить целесообразный метод работы с внешними зависимостями, такими как API или базы данных. Захват ответа из внешних зависимостей позволяет вам создать макетный интерфейс, который точно соответствует типу ответа, сгенерированного из фактической зависимости.

Типичный пример использования такого подхода - когда вы работаете с ресурсами, которые не находятся под вашим контролем как разработчика (например, если вы работаете с API, который разрабатывается, но еще не совсем готов, или с серверной базой данных).

11
Начать дискуссию