Просто лучше. И быстрее! Повысьте свою продуктивность прямо сейчас с помощью рекомендаций по разработке для Android: руководство по повышению производительности.

Каждый программист знаком с этим комиксом XKCD. Время компиляции часто выводит нас из зоны, затягивая нас в море навязчивого просмотра Интернета и социальных сетей или вынуждая сделать еще один перерыв на кофе.

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

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

Не поймите меня неправильно.

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

Давайте представим Джона Доу — младшего разработчика Android. Ему нужно внести несколько изменений в процесс адаптации пользователей. Как будет выглядеть его рабочий день?

  1. Оформить заказ
  2. Синхронизация Gradle
  3. Запустить приложение
  4. Войдите — введите полный адрес электронной почты и длинный безопасный пароль
  5. Дождитесь ответа сервера
  6. Нажмите «Далее» 5 раз— нам нужно отредактировать на 5-м экране фактического процесса
  7. Подтверждено,"значок слишком мал!"
  8. Увеличить размер изображения в редакторе
  9. "Мне нужно удалить приложение, я больше не новый установленный пользователь"
  10. Войдите снова — нажмите, чтобы увидеть результат
  11. "Нет, теперь изображение слишком большое"
  12. Повторяйте шаги снова и снова — и поскольку проект собирается и устанавливается на устройство, «давайте просмотрим забавные гифки с котиками»
  13. "Уже обеденный перерыв, а я ничего не сделал!"

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

Но как мы можем стать лучше?

Используйте вкладку «Предварительный просмотр» для проверки пользовательского интерфейса.

Во-первых, многие разработчики недооценивают возможности Android Studio Preview.

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

Вы могли бы сказать, что это круто для статических экранов, но что, если я полагаюсь на данные, загруженные из API?

Нет проблем, просто ознакомьтесь с префиксом tools — он реально сэкономит время.

  • Хотите предварительно просмотреть текст — короткий, многострочный, с ориентацией справа налево? Просто используйте tools:text="ваш тестовый текст" в теге TextView.
  • Хотите просмотреть, как будет выглядеть изображение после того, как Glide закончит свою работу? Используйте tools:src в ImageView и предоставьте нарисованный образец теста
  • Работаете с RecyclerView? Нет проблем, вы можете использовать tools:listitem="@layout/item_friend_row", чтобы проверить, как будет выглядеть ваш визуализированный автодом.
  • Динамическое отображение/скрытие контента? Используйте tools:visibility="gone|visible|invisible" для предварительного просмотра прогресса, новых пользовательских сообщений на экране без необходимости запускать приложение снова и снова.

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

Используйте модульный тест для тестирования чистого кода без Android.

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

Он вернулся к своим старым привычкам: писать метод предварительной обработки и тестировать на устройстве. После большого количества кликов он заметил ошибку — границы массива были недостаточными. Давайте использовать ‹= вместо и снова протестируем.

А как насчет пограничных случаев? Что делать, если возвращенный массив пуст? Что, если у него есть 2 счастливых пути для проверки?

Тестировать его на устройстве/эмуляторах каждый раз неэффективно. Его метод препроцессинга не имеет зависимостей от Android, не изменяет глобальное состояние, использует java/kotlin pojos в качестве ввода и вывода — т.е. это чистая функция во плоти. Именно тогда jUnit становится очень полезным.

Давайте представим обработку деталей встречи:

data class User( val name: String, val id: Long)
data class MeetingDetails(
 val meetingOwnerName: String,
 val meetingOwnerId: Long,
 val canCancel: Boolean)

И примеры функций, отвечающих за подготовку данных для пользовательского интерфейса, чтобы мы могли легко выполнить привязку к данным:

fun processMeetingInfo(attendees: List<User>, currentUser: User, ownerId: Long): MeetingDetails

На самом деле, есть две вещи, которых нужно достичь. Во-первых, если текущий пользователь встречается с его владельцем — вы можете отменить встречу. Во-вторых, нам нужно найти имя владельца собрания.

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

@Test
 fun shouldAllowCancelMeetingIfCurrentUserIsOwner(){
 //setup phase
 val currentUser = User(“Joe”, 1)
 val attendees = listOf(User(“Joe”, 1), User(“Jane”, 2))
//evaluation phase
 val meeting = processMeetingInfo(attendees, currentUser, 1)
//assertion phase
 assertTrue(meeting.canCancel)
 }

Этот тест состоит из 3 фаз:

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

Подождите секунду, а что, если владельца нет в списке участников?

Мы случайно обнаружили пограничный случай, не запустив приложение на устройстве, и теперь можем уточнить у владельца продукта, как реагировать, модульный тест покроет этот случай!

Я не сторонник TDD, заставляю вас покрывать 80% приложений, сервисов и моделей представлений модульными тестами. Я знаю, что это сложно, отнимает много времени и иногда не стоит затраченных усилий, но современный инженер-программист должен использовать модульные тесты, а простые классы без Android — идеальные кандидаты для начала обучения.

Притворяйся, пока не сделаешь

Что мы можем сделать, чтобы меньше отвлекаться и проводить больше времени «в зоне»?

Мне очень нравится фраза «Притворяйся, пока не получится», так как она также относится к программному обеспечению.

Бедный Джон Доу работает над адаптацией приложения и должен удалять приложение после каждого использования. Но может ли он сэкономить больше времени? Кто решает, показывать ли онбординг?

fun shouldShowOnboarding(prefs: SharedPreferences): Boolean{
 //return prefs.contains(ONBOARDING_SHOWN)
 // TODO — just for testing, remove before going to production!
return false
 }

Мы можем взломать эти методы в целях разработки.

И это еще не все — вы можете временно жестко закодировать длинные учетные данные тестировщика в форму, вернуть поддельные ответы с сервера, начать нашу активность при запуске приложения с предварительно заполненным необходимым вводом. Это одна из причин, по которой ленивые люди часто бывают хорошими инженерами — если задача требует слишком много ручной работы (нажатие кнопок телефона — это, очевидно, ручная работа) — автоматизируйте ее или ищите ярлыки.

Просто помните — если вы делаете подобные ярлыки или хаки во время разработки, всегда помечайте их TODO и внимательно проверяйте перед фиксацией в исходном репозитории. Всегда выполняйте самопроверку кода, прежде чем нажимать «большую красную» кнопку. Также очень полезно запрашивать код-ревью у коллег. На самом деле, вы можете внедрить это как здоровую привычку.

И, конечно же, как только вы будете удовлетворены своим результатом, потратьте некоторое время на тестирование вне среды «безопасного эксперимента»!

Потому что вы не хотели бы доставлять приложение с жестко заданным значением isUserPremium = true для магазина, верно?

Краткое резюме

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

Знайте свои инструменты, тестируйте изолированно на ранней стадии разработки, вводите модульное тестирование для кода без Android. И наконец — не забудьте протестировать на живых данных.

Первоначально опубликовано на https://softwarehut.com 13 июня 2019 г.