Каждому из вас наверняка знакома ситуация, когда через полгода работы над проектом команды из нескольких человек, вы внезапно обнаруживаете, что в разных частях проекта используется разные правила оформления кода, тесты написаны, но отчеты по ним не собираются и не анализируются, в виджетах встречается бизнес-логика и вычислительно сложные задачи вызываются непосредственно в методе build. Кроме этого появились гигантские классы и методы, в коде избыточно много использования типа dynamic или в функциях отсутствует тип возвращаемого результата. И у вас возникает желание открутить маховик времени в начало проекта и сделать все необходимое, чтобы вероятность возникновения такого хаоса была минимальной. В этой статье мы рассмотрим некоторые удобные механизмы анализа кода и результатов тестов для Flutter.
Одним из важных преимуществ инструментальной поддержки Dart является наличие встроенных утилит (ранее они были представлены как самостоятельные приложения, сейчас все возможности добавляются как команды основного инструмента dart), которые позволяют не только выполнить основные задачи (компиляция, запуск тестов), но и помогают в миграции между версиями (например, dart migrate предлагает и реализует автоматическую модификацию проекта для перехода на использование синтаксиса с sound null safety), исправлению потенциальных проблем и исключению использования устаревшего синтаксиса или класса (dart fix). Но наибольший интерес для автоматизации представляют две возможности:
dart format (ранее dartfmt) - выполняет форматирование исходных текстов в соответствии с общепринятыми правилами;
dart analyze - выполняет проверку кода на соответствие наборам правилам (определяются в analysis_options.yaml).
Важно отметить, что инструмент анализа реализован с точки зрения Dart как пакет (analyzer, актуальная версия 4.0.0 выпущена 14.04.2022), который взаимодействует с автономным долгоживущим процессом (analysis_server), реализующим поддержку протокола LSP (Language Server Protocol), который в частности используется в Visual Studio Code для реализации автодополнения и отображения результатов анализа исходных текстов. Процессы взаимодействуют через специальный протокол Analysis Server API, который обеспечивает не только механизмы проверки исходных текстов на соответствие правилам, но и методы для автодополнения в соответствии со сформированным контекстом. В настоящее время создания специализированных расширений сервера еще не предусмотрено, но работы в этом направлении ведутся и можно посмотреть на архитектуру плагина для сервера анализа)
Правила включают в себя требования по избеганию плохих практик (avoid*), рекомендациях по обязательному использованию элементов синтаксиса (например, обязательной запятой в конце списка параметров require_trailing_commas или группа правил prefer* или always*), по оформлению импортов (например, implementation_imports для исключения импортов src-файлов из пакетов), потенциально некорректному использованию асинхронных функций (avoid_slow_async_io для исключения вызова медленных операций из dart:io, use_build_context_synchronously для обнаружения вызова асинхронных функций в build, например при реакции на жест), избежании утечки ресурсов (cancel_subscriptions для обнаружения отсутствия удаления подписки на Stream). Кроме того, могут обнаружиться случаи неудачного использования виджетов (sized_box_for_whitespace при использовании Container вместо SizedBox для создания пустых промежутков).
Существует несколько преднастроенных наборов правил, например Flutter, при этом правила могут подключаться в analysis_options.yaml с использованием директивы include:
include: package:flutter_lints/flutter.yaml
для подключения общих правил для Flutter-приложений или правила Effective Dart для проверки на соответствие официальным рекомендациям, а также пакет lints, описывающие как более свободный, так и строгий вариант проверки кода.
Некоторые разработчики публикуют свои наборы правил, так можно подключить правила от Very Good Ventures:
include: package:very_good_analysis/analysis_options.yaml
Кроме встроенного инструмента для анализа кода существуют множество разработок от сообщества, доступных на pub.dev:
dart_code_metrics - расширение анализатора, добавляет некоторые правила и возможности для подсчета численных метрик кода (среднее количество строк кода в методе и классе, количество методов в классе, цикломатическая сложность и др.), дает возможность обнаруживать очень длинные методы или методы с большим количеством параметров и искать неиспользуемые dart-файлы и локализацию. Правила записываются в объект
dart_code_metrics
вanalysis_options.yaml
, для запуска используется командаdart run dart_code_metrics:metrics analyze lib
;lakos - инструмент для визуализации графа зависимостей и обнаружения циклических зависимостей;
null_safety_percentage позволяет численно оценить использование Sound Null Safety по исходным текстам;
code_quality_report создает json-файл на основе результатов анализа, который можно использовать совместно с возможностью Code Quality в Gitlab (присутствует также в бесплатной версии);
coverage использует данные, опубликованные через отладочный API Dart VM для создания отчетов по покрытию исходных кодов тестами;
test_cov_console формирует отчет по покрытию тестами в консоль (например, может использоваться в конвейнере CI/CD для вывода в отчет);
better_test_reporter или testreport создают отчеты для JUnit по результатам выполнения тестов (dart test).
Любой из этих инструментов может быть запущен внутри сценария сборки в CI/CD при предварительной установке выполняемого образа консольного приложения через
pub global activate
.С каждой новой версией Dart/Flutter возможности анализатора становятся все более значительными и уже сейчас включают в себя ряд проверок на уместное использование виджетов и использование их контекста. А с потенциальной возможностью создания плагинов для сервера анализа, станет возможным и создание более интеллектуальных инструментов, которые позволят обнаружить нарушения и на других уровнях абстракции (например, ошибок и плохих практик при использовании фреймворков для управления состоянием MobX или Redux).
Уже сегодня в 20:00 в OTUS состоится открытый урок «Создаем приложение с управлением сложными жестами (как в Opera)». Приглашаем всех желающих, регистрация — по ссылке.