- PVSM.RU - https://www.pvsm.ru -
фото с Unsplash по запросу "pipeline"
Привет! Я начинаю серию постов о пайплайнах в разработке и не только, которые помогают удостовериться в качестве разрабатываемых мобильных приложений. Главная идея в том, чтобы осветить все подходы к мобильной разработке, актуальные сейчас: нативную разработку для Android и iOS, React Native, Xamarin и Flutter. Я начну с Android, но сначала хотел бы дать общее представление, о чём это всё.
Имейте в виду, что это общий обзор инструментов и практик, способных пригодиться вам в процессе разработки Android-приложений, а не туториал по настройке этих инструментов.
Начнём с общеизвестной истины: чем позже находишь дефект в приложении, чем дороже его исправить. Предположим, что вы обнаружили баг уже в продакшне. Вашим тестировщикам надо воспроизвести этот баг локально, зарепортить его, приоритезировать, передать разработчикам, а им, в свою очередь, надо исправить его, сделать новую сборку, передать обратно тестировщикам, чтобы они убедились, что всё исправлено, а затем сделать релизную сборку, и только после этого отправить новую версию пользователям.
Много часов труда можно было бы сэкономить, если бы у вас были механизмы, предотвращающие появление багов в самом начале. Я не говорю, что есть серебряная пуля, избавляющая от всех багов — это невозможно. Но что возможно, так это воздвигнуть барьеры (также известные как quality gates), повышающие вероятность отловить баги в вашем коде как можно раньше.
Вы как разразботчик всегда работаете на своей машине с IDE и инструментами командной строки. Давайте посмотрим, что существует для Android-разработчиков.
Это сейчас вариант по умолчанию для Android-разработчика, и поскольку он основан на платформе IntelliJ, там есть множество инспекций для Java, Kotlin и XML. Советую договориться в команде о конкретных правилах, которые вы хотите использовать, сконфигурировать их на одном компьютере и закинуть файл settings.jar с этими правилами в вашу систему контроля версий или какой-либо инструмент коллаборативной работы (вроде Confluence).
Настройки инспекций в Android Studio
В AS также есть быстрые исправления, которые можно применить к своему коду по нажатию Alt+Enter.
Пример быстрого исправления от Android Studio
Это инструмент статического анализа конкретно для Android-разработки, «из коробки» снабжённый сотнями правил, любые из которых вы можете использовать. Lint может и запускаться из Gradle-задачи (task), и давать подсказки прямо в Android Studio, и генерировать отчёт. У него множество проверок, разделённых по категориям — безопасность, интернационализация, юзабилити, производительность...
Но особенно мощным его делает возможность добавлять свои собственные правила. Например, у Room [1] есть свой набор правил, у библиотеки логирования Timber [2] — свой. Можно создать правила для вашей команды или проекта и быть уверенным, что никто не совершает определённые типичные ошибки. (Кстати, скоро на конференции Mobius будет доклад [3] об этом, объясняющий и теоретическую сторону, и практическую).
Пример отчёта от Android Lint
Конечно, есть много инструментов статического анализа, предназначенных не конкретно для Android, а в целом для Java [4] и Kotlin [5]: PMD [6], FindBugs [7] (заброшен, используйте SpotBugs [8]), Checkstyle [9], Ktlink [10], Detekt [11] и другие. Выберите себе по душе, интегрируйте его в свой пайплайн и обеспечьте его реальное использование (как именно? читайте дальше).
Пример отчёта от FindBugs
Но недостаточно наличия инструмента, предоставляющего данные о том, что надо поправить. Вам также пригодится следующая информация:
И многие другие. Мы в EPAM Systems [12] уделяем внимание качеству, поэтому выбрали SonarQube как инструмент для ответов на эти вопросы. О других преимуществах SonarQube можно узнать здесь [13].
Надеюсь, не требуется вновь убеждать вас, что вашему коду, чёрт возьми, требуются юнит-тесты по различным причинам [13]. Не имеет значения, следуете ли вы TDD, придерживаетесь принципа пирамиды тестирования или новой идеи гриба тестирования [14]. Не так важно, какой уровень покрытия вы ставите целью, в любом случае ваши юнит-тесты — необходимая составляющая. А значит, вам надо их писать и запускать! К счастью, за 11 лет эволюции мы получили довольно удобный механизм запуска тестов из Gradle и Android Gradle-плагина.
В андроид гредл-проекте по умолчанию есть задача testDebugUnitTest (у вас она, естественно, может отличаться в зависимости от флейворов), и именно она запускает тесты. Убедитесь, что её используют и что покрытие кода со временем растёт. Плюс Java юнит-тестов в том, что они работают на JVM рабочей станции, а не на Dalvik/ART, что даёт преимущество в скорости.
В случае с андроидными юнит-тестами есть одна фундаментальная проблема: зависимость от Android SDK. Это одна из причин, по которым появились все эти подходы к UI-слою вроде MVP, MVVM, MVI и прочие MV*. Конкретная проблема в зависимости класса от Android в том, что юнит-тесты просто падают из-за использования стабов этого самого Android, которые просто бросают исключение. Конечно, существует пара вариантов: либо пропустить тесты для этого класса, либо извлечь часть логики в другие классы, либо создавать интерфейсы для Android-зависимых классов для тестирования какой-то высокоуровневой логики, либо использовать Robolectric (что далеко от идеала). Другой вариант — использовать инструментированные тесты, которые могут подходить для проверки поведения Activity, но современный тренд в том, что Activity не должна содержать тестов.
К вопросу о покрытии: вы хотите знать, какое оно у вас в данный момент и как меняется со временем, так что вам пригодился бы инструмент и для этого. Насколько мне известно, jacoco [15] — индустриальный стандарт для Java, и у него есть поддержка Kotlin.
Эти тесты запускаются на эмуляторе Android, что позволяет им использовать Android Framework. К сожалению, они медленные и нестабильные (из-за некоторых проблем с эмулятором), так что большинство известных лично мне разработчиков старается их избегать. Но их поддержка есть в Gradle и Android Studio, так что для вас они, может, и подойдут.
Помимо простых ошибок, опечаток, проблем при копипейсте и тому подобного, есть ещё и большая категория проблем, на которую вам стоит обращать внимание: безопасность. Конечно, Android Lint уже предоставляет некоторые соответствующие подсказки, но лучше озаботиться специализированными инструментами конкретно для этой задачи. Эти инструменты могут работать как в статическом, так и в динамическом режимах; в зависимости от ваших требований к безопасности вы можете хотеть использовать как один из этих режимов, так и оба. Возможно, вы захотите начать, например, с Mobile Security Framework [16], а позже рассмотреть платные варианты.
К счастью, есть список [17] инструментов статического анализа, составленный непосредственно OWASP. Например, можете выбрать Find Security Bugs [18] или использовать OWASP SonarCube Project [19].
Как я уже сказал, чем короче цикл фидбека, тем меньше времени и денег вы тратите на исправление багов. Так что хочется быть уверенным, что код соответствует продакшн-качеству ещё до того, как он попадёт в репозиторий или даже будет закоммичен локально. Конечно, можно просто попросить своих разработчиков выполнять проверки, но есть вариант куда лучше: Git hooks.
Я предлагаю добавить pre-commit hook для всех проверок, которые мы обсудили выше: Lint, статического анализа кода и юнит-тестов. Пример процесса настройки можно найти здесь [20].
Очень сложно представить Android-проект без CI/CD-пайплайна. Ваша цель — повторить все вышеописанные проверки ещё и на этапе сборки. На то есть несколько причин:
Пример отчёта на bitrise.io
К счастью, вам достаточно или упомянуть эти проверки безопасности непосредственно в билд-скрипте Gradle, или вызывать соответствующие задачи в вашем CI/CD-пайплайне. Если у вас есть сложности с выстраиванием пайплайна, недавно на конференции DevOops я выступил с докладом [21] о мобильном DevOps в 2019-м.
Пожалуйста, делайте также следующее:
И удачи в улучшении своего кода!
Если вам понравилась эта статья, подписывайтесь на меня в Твиттере [22], чтобы не пропустить следующие. А если вы в декабре будете в Москве или можете приехать, приходите на нашу конференцию Mobius [23] и узнайте много другого о разработке для Android (и iOS)!
P.S. Спасибо vixentael [24] за подходы к вопросам безопасности, Алексею Никитину [25] за ревью и комментарии, Александру Баканову за пруфридинг.
Автор: Владимир Иванов
Источник [26]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/android/337309
Ссылки в тексте:
[1] Room: https://developer.android.com/topic/libraries/architecture/room
[2] Timber: https://github.com/JakeWharton/timber
[3] доклад: https://mobiusconf.com/en/2019/msk/talks/cfbaqtxfqyvuikcyhvxn1/?utm_source=habr&utm_medium=476624&utm_campaign=mobius19msc
[4] Java: https://blog.codacy.com/review-of-java-static-analysis-tools/
[5] Kotlin: https://proandroiddev.com/kotlin-static-analysis-why-and-how-a12042e34a98
[6] PMD: https://pmd.github.io/
[7] FindBugs: http://findbugs.sourceforge.net/
[8] SpotBugs: https://spotbugs.github.io/
[9] Checkstyle: http://checkstyle.sourceforge.net/
[10] Ktlink: https://ktlint.github.io/
[11] Detekt: https://github.com/arturbosch/detekt
[12] EPAM Systems: https://www.epam.com/
[13] здесь: https://vizteck.com/blog/benefits-using-sonarqube/
[14] гриба тестирования: https://automationrhapsody.com/what-is-the-test-mushroom-and-how-to-improve-your-testing/
[15] jacoco: https://www.eclemma.org/jacoco/
[16] Mobile Security Framework: https://github.com/MobSF/Mobile-Security-Framework-MobSF
[17] список: https://www.owasp.org/index.php/Source_Code_Analysis_Tools
[18] Find Security Bugs: https://find-sec-bugs.github.io/
[19] OWASP SonarCube Project: https://www.owasp.org/index.php/OWASP_SonarQube_Project
[20] здесь: https://medium.com/@alistair.cerio/android-ktlint-and-pre-commit-git-hook-5dd606e230a9
[21] докладом: https://www.youtube.com/watch?v=r7bb1jv4I1A
[22] в Твиттере: http://twitter.com/vvsevolodovich
[23] Mobius: https://mobiusconf.com/?utm_source=habr&utm_medium=476624&utm_campaign=mobius19msc
[24] vixentael: https://medium.com/@vixentael
[25] Алексею Никитину: https://medium.com/@nikialeksey
[26] Источник: https://habr.com/ru/post/476624/?utm_source=habrahabr&utm_medium=rss&utm_campaign=476624
Нажмите здесь для печати.