Автоматизація процесу розробки під Android: початок


Два тижні тому закінчилася Школа Автоматизації Процесів Розробки (ШАПР) у санкт-петербурзькому Яндексі.
Забігаючи вперед, скажу, що викладачам вдалося головне: за неповних три місяці вони «зіпсували» наше сприйняття процесу розробки, як і обіцяли на початку Школи. Ручне тестування і складання почали страшенно дратувати, викликаючи думки на кшталт «а зараз, замість виконання рутинних операцій, я б міг писати гарний код ...».

Докладніше про те, як їм це вдалося, можна прочитати тут і ще трохи тут.

У практичній частині навчання ми реалізували web-блог, на базі перерахованих за посиланням вище технологій.
Мене, як android-розробника, зацікавила можливість застосування цих технологій і інструментів для організації Continuous Integration для Android.
Натхненний доповіддю Олексія Коровянского на MBLTDev, і, особливо, результатами Google Test Automation Conference 2014 щодо тестування Android-додатків, я реалізував спрощений аналог нашого навчального проекту під іншу платформу, перенісши туди все що зміг і встиг. На цьому передмова закінчується і починається власне опис автоматизації.

1. Автоматизоване тестування
Ми говоримо автоматизація, маємо на увазі — тести; говоримо тести, маємо на увазі — автоматизація.
Тестування, найчастіше, одна з самих ресурсоємних частин процесу розробки. Текст на кнопці можна поміняти за пару хвилин (включаючи час запуску IDE), зібрати проект ще за пару хвилин, а потім кілька годин перевіряти, чи не поїхала верстка у всіх місцях використання цієї кнопки при всіх контрольних дозволах екрану. Якщо цей процес не автоматизований, звичайно.

На щастя, в грудні 2014 Google все-таки порадував android-розробників, включивши фреймворк Espresso в Android Support Repository. Ура! Нарешті у нас є потужний, досить стабільний інструмент написання системних тестів, який підтримує розробник операційної системи (крім усього іншого, це дає надію, що тести не посипляться з виходом нової версії Android).
Про Espresso на Хабре вже писали, так що я обмежуся зауваженням, що в поточній версії він дозволяє синхронізувати операції в тестах не тільки з UI Thread і AsyncTasks, але і з довільними фоновими операціями (http-запитами, наприклад). Приклад реалізації системних та інтеграційних тестів можна подивитися в моєму проекті на github, посилання в кінці статті.

2. Автоматизована зборка
У наш освічений вік, напевно, немає необхідності описувати переваги, які дає використання систем збирання.
У ШАПР ми використовували Maven, але під Android Studio з її підтримкою Gradle «з коробки», щось інше використовувати просто незручно.
Для запуску тестів використовувалися завдання
  • connectedAndroidTest — зі списку типових gradle tasks
  • spoon — з'являється при встановленні відповідного доданка. Дуже корисна розробка команди Square під керівництвом відомого Jake Wharton. Дозволяє запускати тести на декількох підключених android-пристроях одночасно, робити з них скріншоти і багато іншого
Ось так виглядають результати тестів в інтерпретації Gradle 2.2.1image

А так результат запуску тестів для трьох пристроїв (два віртуальних і одне реальне) одночасно покаже Spoon. Деталізація по натисненню на конкретний тест присутнійimage

3. Автоматизований запуск тестів
Якщо ви якимось дивом не використовуєте Maven або Gradle, то далі можете не читати — ні один сервер безперервної інтеграції з вашим проектом дружити не буде.
А якщо використовуєте, то після декількох запусків декількох десятків/сотень тестів до проекту у вас виникає велике бажання, щоб це все відбувалося самостійно, і, бажано, якомога далі від вашого процесора :-). Тут нам на допомогу приходить Jenkins (TeamCity, Atlassian Bamboo, потрібне підкреслити). Я використовував Jenkins, яким нас і вчили в ШАПР. Про Jenkins і навіть безпосередньо його відносини з Android-додатками на Хабре написано теж чимало.
В нашому випадку, крім плагінів «за замовчуванням», використовувалися
  • GitHub plugin, GIT plugin, GitHub Plugin API — для отримання коду і перехоплення подій з github
  • Gradle plugin — для запуску gradle tasks
  • Android Emulator Plugin — для запуску програми на емуляторі (потім відмовився від цієї ідеї на користь spoon)
  • HTML Publisher plugin — для публікації описи результатів виконання тестів довільного формату на сторінці завдання
  • JUnit Plugin — для публікації результатів виконання unit-тестів
Результат виглядає наступним чиномimage

Взагалі запуск тестів на реальних пристроях і віртуальних образах genymotion показав кращі по швидкодії, стабільності та реалістичності результати, ніж стандартний емулятор Android від Google, так що від його використання в тестуванні я на даний момент відмовився.

4. Пару слів про поділ оточень
Мова йде про використання різних, наприклад, баз даних testing і production. Для цього в код необхідно транслювати різні налаштування. У модельному проекті це реалізовано за допомогою gradle build flavors, змінні винесені в окремий файл з константами, який плагін підставляє потрібну збірку.

Отже, як виглядає частково автоматизований процес розробки модельного android-додатки на даний момент:
1. Написаний код йде на github.
2. Jenkins ловить hook з github і запускає збірку на всіх android пристроях, які запущені/підключені до сервера/ноду
3. За результатами складання Jenkins відписується на github/посилає лист розробнику/запалює червону або зелену лампочку над дверима (потрібне підкреслити)
4. У разі успішного складання інсталяційний файл заливається на тестові пристрої, а тестувальникам-ручникам йде оповіщення, що можна приступати до роботи (якщо це необхідно)
5. Можливо навіть автоматично опублікувати зібраний проект в google play Google Play Android Publisher Plugin

TODO: на жаль ще не встиг підняти SonarQube, хоча в ШАПР ми встигли наочно оцінити корисність і важливість інструментів аналізу коду. Так, і code coverage в тестовому проекті поки не вважається. Не встиг використати механізм dependency injection, який дуже зручний для написання добре досліджуваного коду — під Android для цього є чудова бібліотека Dagger. Загалом, є ще чим зайнятися.

Обіцяна посилання на модельний проект (блог з можливістю додавання/видалення постів/коментарів) і дюжину тестів до нього. Не судіть код занадто суворо, адже щоб його мало сенс тестувати, він повинен інколи ламатися, вірно? ;-)

У проекті використовувалися бібліотеки:
  • robospice
  • retrofit і okhttp
  • androidannotations
  • cupboard
  • ну і, звичайно, espresso
Користуючись нагодою, хочу щиро подякувати наших інструкторів в ШАПР і Яндекс в цілому.
Ви в черговий раз зробили світ трішки краще. Спасибі! :-)
Я android-розробник і

/>
/>


<input type=«radio» id=«vv65005»
class=«radio js-field-data»
name=«variant[]»
value=«65005» />
використовую автотесты
<input type=«radio» id=«vv65007»
class=«radio js-field-data»
name=«variant[]»
value=«65007» />
використовую систему безперервної інтеграції (наприклад, Jenkins)
<input type=«radio» id=«vv65009»
class=«radio js-field-data»
name=«variant[]»
value=«65009» />
використовую і автотесты і CI-сервер
<input type=«radio» id=«vv65011»
class=«radio js-field-data»
name=«variant[]»
value=«65011» />
не використовую засоби автоматизації, але хотів би спробувати
<input type=«radio» id=«vv65013»
class=«radio js-field-data»
name=«variant[]»
value=«65013» />
нічого такого не використовую, і так все працює

Проголосувало 19 осіб. Утрималося 4 людини.


Тільки зареєстровані користувачі можуть брати участь в опитуванні. Увійдіть, будь ласка.


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

0 коментарів

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