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

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

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

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

Dart и Flutter используют общий фреймворк тестирования, поэтому в этой главе я начну обсуждение тестирования и его значимости для создания приложений в Dart. Как правило, тестирование Dart/Flutter можно разделить на три различных типа: модульное, интеграционное и пользовательский интерфейс виджета, как показано на рисунке 6-1.

Рисунок 6-1. Тестовая пирамида
Рисунок 6-1. Тестовая пирамида

В этой статье мы рассмотрим аспекты модульного тестирования и интеграции, которые являются первыми двумя типами тестирования, как показано на рисунке 6-1. Наиболее распространенным типом тестирования, с точки зрения разработчика, является модульное тестирование. Модульный тест сравнивает входные данные для отдельной функции/класса с ожидаемым результатом. Такие тесты выполняются на основе разработанного кода и обычно выдают отчет о прохождении/неудаче для представленного сценария.

Сочетание стратегий модульного и интеграционного тестирования обеспечивает хорошую основу для проверки соответствия приложения требованиям. В ходе этой главы мы будем использовать следующий пример приложения “travel.dart”, чтобы продемонстрировать несколько шагов по созданию модульных и интеграционных тестов. Создайте файл dart (test_dart_sample/test_dart_sample.dart) и добавьте следующий код:

const convertToKilometers = 1.60934; const convertToMiles = 0.62137119; class Travel { late double distance; Travel(double newDistance) { distance = newDistance; } double distanceToMiles() { return distance * convertToMiles; } double distanceToKilometers() { return distance * convertToKilometers; } }

В примере кода тест выполняет проверку преобразования расстояния. Класс Travel включает конструктор, который инициализирует свойство distance на основе параметра, используемого в методе. Кроме того, есть два метода, используемых для преобразования сохраненного расстояния в километры и мили, соответственно.

Добавление тестового пакета Dart в ваше приложение

Проблема

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

Решение

Dart предоставляет платформу тестирования, что означает, что тестовые примеры можно легко добавлять в существующие приложения. Ранее мы уже определяли шаблон приложения Flutter. Чтобы использовать Flutter test framework, добавьте flutter_test/dart_test dev_dependencies в pubspec.yaml приложения. Пакеты предоставляют возможность включать тестирование, как часть рабочего процесса разработки.

Добавьте test.dart пакет в pubspec.yaml вашего приложения. Более подробную информацию о том, как выполнить эту задачу, чуть дальше.

Вот пример того, как добавить тестовый пакет в Dart:

dart pub add test --dev

Обсуждение

Добавление тестового пакета Dart выполняется таким же образом, как и добавление любого другого пакета. Следует отметить использование дополнительного параметра --dev, указывающего, что пакет требуется только на этапе разработки.

Dart ожидает, что тесты будут расположены во вложенной папке test. Отсюда модульные тесты можно разделить на несколько файлов или получить доступ к ним как к одному файлу.

Пакет flutter_test предоставляет практически ту же функциональность, что и package:test/test.dart, поэтому вы все равно сможете тестировать в этой среде. Однако вам потребуется, чтобы тестовый код и код приложения были расположены в одном файле.

Создание образца тестового приложения

Проблема

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

Решение

Создайте тестовый файл Dart в корневой папке приложения. В нашем примере приложения мы использовали имя test_dart_sample.dart. Результирующее имя файла и путь к нему в вашей тестовой среде будут test_dart_sample/test_dart_sample.dart.

Вот пример нашего примера кода Dart, который послужит основой для наших тестов:

const convertToKilometers = 1.60934; const convertToMiles = 0.62137119; class Travel { late double distance; Travel(double newDistance) { distance = newDistance; } double distanceToMiles() { return distance * convertToMiles; } double distanceToKilometers() { return distance * convertToKilometers; } }

Обсуждение

В примере кода класс объявлен с конструктором и двумя методами, которые мы будем использовать для написания тестов на протяжении всей главы. Если вы работаете в среде IDE, такой как Android Studio или VS Code, код можно разделить на несколько файлов. Помните при использовании редактора DartPad, что он ограничен одним файлом, поэтому вам нужно будет поместить базовый класс и тестовый код (содержащий основной метод) в один и тот же файл.

Запуск модульных тестов в вашем приложении Dart

Проблема

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

Решение

Добавьте модульный тест Dart в свой каталог тестов. Тесты могут быть определены для обеспечения охвата элемента, подлежащего проверке, в вашем приложении.

Хороший подход при написании модульных тестов - следовать шаблону arrange, act и assert (AAA). Фаза arrange устанавливает значения, которые будут использоваться и позже проверяться. Фаза act выполняет действие - в нашем примере вызов метода travel.distance. Наконец, фаза assert завершает шаблон, проверяя, соответствует ли результат ожидаемому результату.

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

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

В каталоге тестов обратите внимание, что мы будем использовать код приложения. Если ваш код не соответствует этому, замените/добавьте файл с именем test_dart_sample_test.dart со следующим содержимым:

import 'package:test_dart_sample/test_dart_sample.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); }); }

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

dart test

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

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

Обсуждение

В примере кода у нас определен один тест; следовательно, когда мы запустим тест, мы должны увидеть один тест для класса Travel Distance. Результат подтверждает, что объект класса Travel был успешно инициализирован значением distance.

На рисунке 6-2, где показан модульный тест расстояния перемещения, мы выполняем ряд шагов, чтобы убедиться, что класс перемещения работает так, как ожидалось. Сначала мы настраиваем входные данные для условия, которое мы хотим протестировать. Обратите внимание, что расстояние задано как переменная. Я делаю это, чтобы остальная часть теста выполнялась из переменной. Если мне затем понадобится скопировать или изменить этот модульный тест, мне нужно изменить только одну переменную расстояния, а не несколько значений.

Рисунок 6-2. Модульный тест расстояния перемещения
Рисунок 6-2. Модульный тест расстояния перемещения

Этап act модульного теста выполняет нашу операцию. Здесь мы передаем расстояние до нашего класса перемещения, а затем записываем расстояние в переменную результата. Я мог бы просто напрямую использовать переменную расстояния; однако использование промежуточной переменной результата делает код более читабельным и требует меньшего обслуживания, если я изменю содержимое.

Наконец, мы переходим к разделу assert. Основываясь на вводимых данных, мы ожидаем, что ожидаемое расстояние и результат совпадут. Если это так, наш тест помечается как успешный, и мы можем двигаться дальше. Если результаты не совпадают, значит, мы обнаружили ошибку на ранней стадии разработки и можем тут же ее исправить.

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

Написание тестов для кода Dart заставит вас задуматься об общей структуре вашего кода. Я настоятельно рекомендую добавлять модульные тесты в ваш код, поскольку это укрепит ваше понимание и повысит ваши навыки разработки.

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