AndroidAudit. Ваше Android-додаток як місце злочину



Від перекладача: оцінка процесу і результату розробки — досить суб'єктивна річ, якщо не використовується якась міра ваги. Можна довго сперечатися: таби або пробіли, git або mercurial, maven або gradle, але такі спори все одно скочуються до вкусовщине і якимось приватним випадків. Інша справа — дотримання однорідності проекту, ось це вже цілком собі вимірна величина.
Погана методологія краще її відсутності.
Крім загальних речей, знайдуться і специфічні, притаманне тільки мобільного розробці, тільки під Android. Pedro Vicente Gómez Sánchez з Karumi у своїй роботі розібрав по кісточках основні технічні області та поставив влучні питання для правильної, об'єктивної оцінки розробки для платформи Android. Якщо з'явиться завдання: оцінити чужий проект, то рекомендую скористатися його методологією. Я скористався цією методологією, як чек листом. На виході вийшов цілком зрозумілий не професіоналові документ, де навпроти кожної категорії — конкретна величина відповідності правильності від 0 до 1.



Технічний аудит iOS і Android додатків став невід'ємною частиною нашої повсякденної роботи в Karumi. Хоч це і виглядає просто, є чимало деталей реалізації такої перевірки, які варто розглянути. В цьому документі ми розглянемо те, що ми вважаємо найбільш важливим при проведенні аудиту і розділимо це з технічних областях.

Система контролю версій

Використовується система контролю версій, яка система і як організовані робочі процеси — це багато розповість про процес розробки.
  • чи Є у вас правильно налаштований *ignore файл, щоб файли метаданих IDE і інші сторонні елементи не потрапляли в сховище?
  • Сторонні бібліотеки сконфігуровані як зовнішніх залежностей або лежать в сховище?
  • Достатньо короткі і виразні коментарі до коммитам (commits) ви використовуєте?
  • чи Є розмір ваших комітів обґрунтованим?
  • Всі файли в коммите пов'язані з однією і тією ж проблемою або функціональністю?
  • Використовуєте ви які-небудь схеми розгалуження типу "feature branch" або "git-flow"?
  • Достатньо інформативні назви гілок?
  • ви Використовуєте систему pull request/code review до злиття коду в master?
    • чи Є у вас якийсь регламент щодо того, на що потрібно звертати увагу при розгляді PR (pull request)?
    • Скільки коментарів в середньому припадає на кожен PR?

    • Скільки людей розглядає кожен PR?
    • Скільки "+1" до PR вам потрібно для злиття?
    • Хто несе відповідальність за закриття гілки?
  • Ви використовуєте release branches для кожного релізу?
  • Як довго відкритий процес підготовки (staging process)?
  • Скільки виправлень ви вносите у release candidate, перш ніж випустити його?
  • Є можливість переключитися на точний код будь-якої з версій опублікованих вашої програми?
  • Скільки виправлень (hotfix) ви випустили у минулому році?
  • Ви об'єднуєте (squash) коміти до злиття (merging) його в master/develop гілку?
  • Готові master/develop гілки до випуску в будь-який час?


Інструменти складання

Визначальним чинником є можливість запустити процес складання на машині розробника і на будь-який інший зовнішній системі, наприклад у системі безперервної складання (continuous integration).
  • Скільки бібліотек використовуються в проекті?
  • Розділений проект на модулі?
  • Використовують модулі Maven або Gradle для розв'язання залежностей, або використовуються локальні .jar-файли?
  • На небезпечне відстань наближений проект до ліміту кількості методів .dex файлах? Або вже за межею?
  • Ви використовуєте бібліотеки, які не потрібні в проекті?
  • Використовується multidex?
  • Всі зовнішні залежності оновлені до сучасних версій?
  • Всі ліцензії сторонніх бібліотек дотримані?
  • Використовуються застарілі або не підтримуються сторонні бібліотеки?
  • Обумовлений мінімальний SDK вимогами технічного завдання (product description)?
  • Актуальне цільової SDK (target SDK)?
  • Використовується ProGuard або будь-який інший інструмент обфускации (obfuscation — заплутування)? Він включений і правильно налаштований?
  • Облікові дані сховища ключів (keystore credentials) і облікові дані Google Play зберігаються у надійному місці?
  • Сховище ключів додатка (application keystore) і облікові дані зберігаються у надійному місці?
  • Належним чином налаштовані build types?
  • Правильно використовуються flavors?
  • Правильно налаштований релізний тип складання?
  • Включена опція резервного копіювання?
  • Включений Lint? Він успішно проходить перевірку?
  • Є інструмент статичного аналізу? Він налаштований і успішно проходить перевірку?
  • Є Checkstyle? Він налаштований і успішно проходить перевірку?
  • Правильно налаштований id програми та версія name/code?
  • Ви використовуєте якусь структуру або стратегію версионирования id?
  • Використовується інструмент безперервної складання (continous integration), чи правильно він налаштований?
  • Автоматизований процес випуску нових версій?


Використання Android ресурсів

Існує широкий спектр пристроїв в світі Android, кожен з них зі своїм власним розміром екрану, можливостями і т. д. Вам потрібно бути дуже уважними і обережно використовувати деякі з Android інструментів, аби у відвідувачів залишилися найкращі враження від вашого додатки, незалежно від їх устрою.
  • чи Існують які-небудь відсутні ресурси для densities, flavors і build types?
  • Потрібна підтримка додатком екранів з різною щільністю пікселів (density) за технічним завданням?
  • Використовуються в додатку drawable/mipmap, шрифти або векторні ресурси?
  • чи Існують які-небудь відсутні переклади?
  • Автоматизований процес перекладу?
  • Яку мову вибрано за промовчанням для перекладу?
  • Використовує додаток сторонні шрифти?
  • Використовує додаток значення конфігурації всередині файлу строкових ресурсів?
  • Дотримується угоду для присвоєння однорідних імен ресурсів?
  • Є параметри конфігурації, пов'язані з апаратними засобами пристрою, чи правильно вони налаштовані?
  • Підтримуються планшети?


Використання Android Layout

Як ми вже говорили раніше, існує широкий спектр Android пристроїв у світі, кожен з них з власним розміром і щільністю екрану. Визначальним фактором є правильне використання Android Layouts.
  • чи Виникають проблеми з продуктивністю через кількість шарів в макетах (layouts) програми?
  • чи Використовуєте ви теми і стилі?
  • Використовуються повторно макети (layouts) з використанням "include" тега?
  • Ви використовуєте правильний тип угруповань у макетах?
  • Враховані різні розміри екранів у макетах?
  • Використовується будь-яка угода про іменування, щоб присвоюються імена макетів і віджетів залишалися однорідними?
  • Списки реалізовані з використанням ListView або RecyclerView?
  • Правильно використовується Android Support Library?


Права доступу

Запит можливих дій програми (permissions) збільшує довіру користувачів до нього, а також розширює його можливості за рахунок "прозорою" інтеграції з іншими сервісами.
  • Всі запитувані дозволу (permissions) дійсно необхідні?
  • Дозвіл використовується навмисно?
  • Є відсутні дозволи?
  • Якщо цільової SDK більше, ніж 23, то "небезпечні дозволу" запитуються з допомогою системи дозволів сумісності (compatibility permissions system)?
  • Дозвіл запитуються тоді, коли вони будуть використовуватися?
  • чи Є зворотній зв'язок з користувачем, що пояснює, чому будь-який дозвіл необхідно?


Проблеми з безпекою

Як розробники, ми повинні свідомо ставитись до безпеки наших додатків. Ми не хочемо, щоб дані наших користувачів "витекли" або їх сесії були вкрадені.
  • Налаштований HTTP клієнт на використання HTTPS?
  • Налаштований HTTP клієнт на використання вбудованого сертифікат (certificate pinning) та повідомлень аутентифікації з HMAC?
  • Зберігає додаток конфіденційну інформацію користувача? Де?
  • Зберігає додаток інформацію поза внутрішньої системи зберігання даних?
  • Логируется (logging traces) додаток при складанні релізу?
  • Обфусцирован (obfuscated) код програми?
  • Надає ваше додаток постачальника контенту (Android content provider), приймача (receiver) або сервіс іншим програмам?
  • Вимкнено параметр "debuggable" в релизной збірці?


Push повідомлення (Push Notifications)

Push — це чудовий механізм для інформування наших користувачів у будь-який час, але це більш складна проблема, ніж здається на перший погляд.
  • Використовується стороння бібліотека для реалізації системи Push-повідомлень?
  • Використовується система GCM для передачі інформації з додатком, або просто, щоб показувати повідомлення користувачу?
  • Як поводиться додаток при отриманні Push-повідомлення?
  • Як веде себе додаток, коли пов'язана з Push-повідомленням інформація не та, що очікувалася?
  • Показувати повідомлення з використанням API сумісності (compatibility API)?


Продуктивність

Продуктивність має велике значення. Ніхто не захоче використовувати на своїх дорогих пристроях повільне додаток. Продуктивність — це гроші.
  • Є в додатку будь-якого витоку пам'яті?
  • Налаштований в develop збірці якийсь аналізатор пам'яті, як, наприклад, "LeakCanary"?
  • Android Strict Mode підключений і налаштований у develop збірці?
  • у програмі використовуються потоки? Ви використовуєте async tasks, intent services або будь-які інші сторонні бібліотеки?
  • Викликає кількість фонових потоків проблеми з продуктивністю?
  • Використовуєте ви які-небудь політики планувальника (scheduler policy) або просто створюються потоки на вимогу?
  • Підтримуєте ви Android Doze Mode?
  • Прослуховуються події, пов'язані зі станом мережі або будь-якого іншого повторюваний від операційної системи?
  • Основний потік використовується тільки для виконання завдань, пов'язаних з кодом користувальницького інтерфейсу?
  • Є в додатку які-небудь політики кешування?
  • Налаштований клієнт HTTP використання тайм-ауту?
  • Налаштований клієнт HTTP використання GZIP?
  • Працює користувальницький інтерфейс програми зі швидкістю 60 кадрів в секунду?
  • Немає таких custom view, для яких виділяється занадто великий обсяг пам'яті, або які виконують "дорогі" завдання в потоці інтерфейсу користувача (UI thread)?
  • Ви тестуєте ваш додаток на lower-end (бюджетних, непродуктивних) пристроях?
  • "гальмує" чи прокрутка recycler view?
  • Для завантаження зображень використовується яка-небудь стороння бібліотека або у вас є своє власне рішення?
  • Зображення масштабуються під розміри екрана або відразу завантажуються під певний екран пристрою?
  • Розумно використання пам'яті?
  • Правильно використовується модифікатор "Static" в Java?
  • Всі завдання, пов'язані з обробкою зображень, можуть обробляти кілька зображень за раз?
  • Працює система статистики у фоновому потоці і налаштована вона з правильним пріоритетом?
  • Оптимізується код в релизной збірці?


Структура Java Packages

Хороша структура пакетів зробить наш код більш масштабованим.
  • Використовуються пакети для розділення коду по функціоналу (features) або концепцій (наприклад, Login vs User)?
  • Використовуються модифікатори видимості Java, щоб приховати деталі реалізації в межах пакетів?
  • Всі пакети виходять з кореневого пакету?
  • Повторює чи директорія з тестами структуру вихідної папки?
  • Організовані різні функції (features) за допомогою однієї і тієї ж структури пакетів?
  • правильних пакетах лежать класи?
  • Дотримуються угоди про однорідному назві пакетів?
  • Пов'язано назва кореневого пакета з ім'ям компанії?


Code Style

Узгоджена з точки зору стилю кодова база допомагає нашим інженерам читати код простіше. Інженер читає НАБАГАТО більше коду, що пише, так що це важливе поняття.
  • Є codestyle однорідним?
  • чи Використовуєте ви угорську позначення?
  • чи Є який-небудь інструмент Checkstyle? Він налаштований і працює?
  • Відповідає код Java codestyle?
  • Ви використовуєте табуляцію або прогалини?
  • Правильно названі класи?
  • чи Використовуєте ви "І" в якості префікса інтерфейсів або "Impl" як суфікси реалізації?
  • ви Використовуєте правильні імена змінних?
  • ви Використовуєте правильні імена для поля (fields)?
  • ви Використовуєте правильні імена для методів?
  • Використовуються атрибути і модифікатори видимості методів належним чином?
  • Код написаний англійською мовою?
  • чи Використовуєте ви Javadoc?
  • Ви пишете коментарі до коду?
  • чи Використовуєте ви константи або перерахування (enums), щоб уникнути дублювання літералів?


Offline реалізація

Забезпечення гарної роботи в режимі offline є відмінним фактором наших додатків.
  • додаток Може використовуватися, коли немає підключення до мережі Інтернет?
  • Яке поведінка програми при повільному мережеве з'єднання?
  • Яка поведінка програми при втраті запиту із-за збою в мережі?
  • Синхронізуються чи зміни даних програми з бекэндом після того, як з'єднання було відновлено?
  • Налаштований тайм-аут на мережеве з'єднання?
  • Налаштована політика кешування HTTP?
  • Сеанс користувача відновлюється автоматично?


Архітектура

Архітектура додатків, з точки зору коду, є однією з частин аудиту, яка дає нам більш глибоке уявлення про програму. В ході огляду архітектури ми будемо зосереджені на поняттях, пов'язаних з S. O. L. I. D і Clean Code принципами.

Реалізація шару представлення (Presentation Layer Implementation)
  • Використовується який-небудь патерн, пов'язаний з реалізацією графічного інтерфейсу користувача)? Model View Presenter або Model View ViewModel два з найбільш часто використовуваних шаблонів для розробки додатків. Правильно вони реалізовані?
  • Пов'язана реалізація шару представлення (presentation layer) з реалізацією виду (view implementation)?
  • Пов'язана реалізація виду (view implementation) c реалізацією моделі (model implementation)?
  • Включає шар представлення бізнес-логіку?
  • Правильно реалізація виду використовує Android SDK tools?
  • чи Використовуєте ви сторонні бібліотеки для спрощення реалізації виду?
  • Розділена реалізація різних функцій за окремими activities або fragments?
  • Однорідно поведінка користувальницького інтерфейсу?
  • чи Використовуєте ви custom views для повторного використання коду інтерфейсу?


Реалізація предметної області (Domain Implementation)
  • Є окремий шар предметної області (domain layer) або вся бізнес-логіка реалізована в шарі представлення (presentation layer)?
  • Виражені правила предметної області і різні вимоги до додатка до основних об'єктах бізнес-логіки?
  • Реалізований шар предметної області з застосуванням принципів ООП?
  • Пов'язаний шар предметної області з Android SDK або будь-якої сторонньої бібліотекою?
  • Пов'язаний шар предметної області з шаром подання?
  • Є модель предметної області (domain model) "анемічній"?
  • чи Використовуєте ви "товсті" моделі предметної області?
  • Заснований код на слабко зв'язаних і, в той же час, добре взаємодіють один з одним компонентах?
  • Реалізована чи обробка помилок з використанням винятків або якогось іншого механізму обробки помилок?
  • Зіставляються дані (mapped) між різними верствами?
  • Впливає архітектура зовнішніх компонентів (наприклад, схеми бази даних або парсинга JSON) на архітектуру моделі предметної області?
  • Розробники зловживають спадкуванням?
  • Дублюється код?
  • Є dependency injection бібліотеки або сконфігурований locator service?
  • Не занадто висока складність класів і методів?


Реалізація API
  • Прив'язана реалізація API до Android SDK?
  • Відбувається "витік" через API яких-небудь деталей реалізації з-за клієнта HTTP або використовуваної бібліотекою для реалізації мережевого шару?
  • API клієнт надсилає правильні заголовки?
  • Яке поведінка API клієнта для різних відповідей HTTP?
  • API клієнта реалізує механізм аутентифікації?
  • Правильно реалізований процес відновлення сеансу?
  • Є підтримка обфускации JSON?
  • Розділена реалізація API для різних клієнтів?


Реалізація Зберігання
  • Де зберігається інформація?
  • Використовуються транзакції при читанні і запису інформації у сховищі?
  • Надійно зберігання конфіденційної інформації користувача?
  • Використовує шар зберігання якісь сторонні бібліотеки?
  • "Витікають" деталі реалізації через шар зберігання?
  • Правильно спроектовані tables/schemas?
  • Запити, надіслані в сховище, оптимізовані?
  • Використовуються Android SDK APIs для зберігання даних в правильному місці? Зберігаються дані в базу даних, а налаштування (preferences) і невеликі за обсягом дані в Shared Preferences і файли на диску?


Тестованість
  • чи Є у додатку тести?
  • Є додаток тестованим?
  • У програмі використовуються різні види (unit/integration/end-to-end) тестів?
  • Правильно названі тести?
  • Досить тести охоплюють проект?
  • Є надмірне документування (overspecification) в тестах?
  • Час виконання розумно?
  • Не занадто низько покриття коду?
  • чи Існують які-небудь ігноровані тести?
  • Є нестабільні тести (flaky tests)?
  • чи Використовуєте ви сучасні фреймворки для тестування?
  • чи Існують якісь тести без тверджень (tests without asserts)?
  • Тести і продакшен код написані одними і тими ж розробниками?
  • У вас є команда QA?
  • У вас є команда QA, автоматизує частина тестів?
  • чи Є у вас які-небудь системи безперервної інтеграції (continuous integration system)?
  • чи Використовуєте ви builders, factories або mothers, щоб зменшити витрати на створення деяких об'єктів, які необхідні для тестів?
  • Тести тверджень (assertions) правильно написані?
  • ви Проводите більше одного логічного затвердження на тест?
  • У вас є різні набори тестів, пов'язані з одним і тим же проектом?
  • Ви використовуєте різні підходи тестування для різних частин програми?
  • ви Використовуєте який-небудь monkeyrunner?
  • Дотримуєтесь ви який-небудь TDD або BDD методології?
  • чи Використовуєте ви Java, щоб написати тестові варіанти (test cases)?


На підставі цього списку, пов'язаного з різними технічними областями, ми можемо оцінити якість програми. Є й інші моменти, які ми також розглядаємо, але цей список містить найбільш важливі з них. Ви можете дати коректні відповіді на всі ці питання про вашому додатку?

Автор: Pedro Vicente Gómez Sánchez.
Подяки допомоги підготовці перекладуНе можу не згадати тих, без кого цей переклад був би жахливим промтом, яким соромно поділитися з громадськістю.
Дякуємо за допомогу в перекладі і вдумливу вичитку Кочкіної Яні, Заостровскому Роману (@firsto), Полежаеву Максиму (@itsme_42).
Окреме спасибі за обидві КДПВ, яких не було в оригінальній статті, Кочкіної Яні.

Альтернативна КДПВВ пам'ять про колись дуже популярної бібліотеці від JakeWharton.


До речі, якщо ActionBarSherlock живе у вашому проекті і по нині, то рекомендую подумати про освіженні проекту.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.