Тестирование телефонов с помощью Arduino
В 2016-м на Хабре привлёк много внимания постАлексея Лавренюка «Измеряем потребление батарейки на мобильных устройствах. Эксперимент в Яндексе». Годом позже на нашей конференции Heisenbug Алексей вместе с коллегой Тимуром Торубаровым представил доклад «Тестирование телефонов с помощью Arduino»: часть этого доклада совпадала с хабрапостом, но было и много новой информации. А теперь круг замкнулся: мы сделали текстовую версию доклада, чтобы вся эта новая информация появилась и на Хабре.
Как правильно измерить энергопотребление приложения? Зачем при этом делать 10 000 замеров в секунду вместо 500? Какие смартфоны сложнее сверлить? Как убить iPhone совершенно непредвиденным способом? В тексте под катом — всё это и многое другое. Также прикладываем видеозапись доклада:
Вступление
Тимур Торубаров:
Хотелось бы начать с ответного приветствия ребятам из Badoo: мы вчера слушали ваш доклад, он был очень крутой. Кто не слышал — рекомендуем, ребята там рассказывали про тестирование геолокации в Badoo и про энергопотребление при геолокации.
Но, в отличие от них, во-первых, мы копнули тему энергопотребления глубже, а во-вторых, у нас при тестировании пострадало много iPhone в физическом смысле!
Алексей Лавренюк:
Люди удивляются «вы же с Тимуром нагрузочные тестировщики, чего это вы айфоны сверлите». С чего у нас это началось? К нам пришли разработчики и сказали: «Мы тут выбираем, какую библиотеку использовать: написать самим или купить платную. Нам надо сравнить прототип и бесплатную версию внешней библиотеки по разным параметрам, в частности, по энергопотреблению». Мы занимались производительностью, поэтому они пришли к нам.
Как измерить энергопотребление приложения? Человек берёт два телефона, на один ставит одну версию приложения, на другой другую, кладёт оба в карманы. Ребята из Badoo вчера сказали, что есть разница между тем, в какой карман положить. На самом деле, есть еще куча вариантов, как может проявляться разница: качали ли вы телефон, клали ли на стол, ревизия телефона и т. д. В общем, двух одинаковых телефонов не бывает. Потом вы три дня ходите с этими двумя телефонами и смотрите, какой быстрее разрядится, то есть у вас на один тест уходит три дня.
Мы тогда потестировали это дело и выбрали писать свой велосипед, но заодно поняли, что нам нужно учиться измерять энергопотребление. Причем быстрее, чем за три дня. Мы походили, поспрашивали, кому это нужно, и поняли, что измерять надо не только на Android, но и на iPhone, на ноутбуках, потенциально на планшетах, на чем угодно вплоть до Apple Watch.
Мы не хотим тратить на это человеческие ресурсы и ходить три дня с ноутбуками, а хотим делать это автоматически, желательно на каждый коммит. И ещё нам нужно измерять энергопотребление с большой частотой, то есть много-много раз в секунду, про это ещё расскажу подробнее.
План нашего доклада:
- Почему мы не взяли готовый мультиметр, которых на рынке полно
- Как мы сделали свой мультиметр
- Как мы его совершенствовали в соответствии с требованиями разных команд
- Что из нашего проекта можно скачать в опенсорсе
- Как этим пользоваться и какие результаты можно получить
Как это делают обычно
Начнем с мультиметров. Как это обычно делается? На телефонах есть куча софтовых метрик, может быть, энергопотребление тоже можно собрать?
Мы тоже так подумали. Вот стандартный интерфейс тулзы для IPhone, который собирает много разных метрик и энергопотребление тоже, черной стрелочкой отмечено энергопотребление:
Подвох в том, что график потребления CPU видно, что он менялся во время теста, а вот энергопотребление за весь тест вообще никак не поменялось 1/20.
Кто-нибудь знает, что такое 1/20? И мы не знали. 1/20 — это не 1/20 мА, не 1/20 Вт/ч или чего-нибудь физического, это значит, что телефон будет работать в таком режиме еще 20 часов. Такая вот encrypted метрика у iPhone.
С Android лучше: это Linux, есть /proc, можно удобно считывать метрики программно. Но есть нюанс.
На Nexus, например, метрика эта изменяется раз в 20 секунд. А нам, как уже говорил, нужно много раз в секунду. На некоторых телефонах эта метрика лежит в других местах, или показывает что-то странное, мы не смогли расшифровать, документации нет.
На некоторых телефонах этой метрики вообще нет, мы ее искали, потом наткнулись на ветку StackOverflow, где человек тоже искал эту метрику на конкретную модель телефона, а в конце концов понял, что просто нет чипа, который ток измеряет в телефоне. И он понял, что единственный способ — это взять мультиметр и измерить.
Нам нужно тестировать много разных устройств, мы никогда не найдем универсального способа собирать метрику быстро. Поэтому мы решили построить свой мультиметр.
Естественно, сначала посмотрели на то, что есть на рынке.
Во-первых, есть цифровые осциллографы: сложные, дорогие, мощные, с полосой пропускания несколько МГц, т.е. можем делать миллионы измерений в секунду. Во-первых, они стоят как крыло «Боинга». А нам же нужно параллельно тесты гонять, много-много тестов на каждый релиз, на каждое приложение Яндекса, то есть это все надо помножить на пару десятков или даже больше в будущем, и получится вообще невменяемая сумма. Кроме того, эти приборы предназначены не совсем для этого. Нам нужно просто собрать метрику, чтобы потом отдельно её анализировать. А эти приборы умеют отображать на экране метрику, её частотные характеристики, то есть они для детального анализа сигналов.
Затем мы наткнулись на проект под названием Power Monitor — это девайс, предназначенный специально для сбора метрики с телефонов. Но он нам тоже не подошёл, потому что он продаётся как black box: в него нельзя залезть, что-нибудь подправить под наши задачи. Софт работает под Windows, а у нас везде Linux, нам нужно это в автоматизацию как-то запихнуть. В общем, сложно.
Уже после того, как мы начали разрабатывать свою штуку, наткнулись ещё на проект batt0r. Они на нас очень похожи, это ребята из разных институтов (включая Стэндфордский). Они опубликовали пару статей, мы почерпнули разную полезную информацию (буду на них немного ссылаться), но потом они пошли работать в Google, и после этого мы не смогли с ними связаться. И статьи пропали, по старым ссылкам уже не открываются.
Как мы сделали свой мультиметр
В общем, мы решили строить свой мультиметр, нашли схему в интернете.
Я до этого никогда ничего из электроники не строил, только программировал. Схема несложная, включает в себя шунт — это резистор, через него проходит ток, которым телефон питается, и образуется разность потенциалов. Эта разность потенциалов маленькая, ее напрямую не померить с помощью Arduino (мы решили для начала использовать Arduino, потому что это простое дешёвое начало). Чтобы считать это Arduino, нам нужно эту разность потенциалов усилить, это делается с помощью инструментального усилителя, он также на схеме.
Мы реализовали эту схему, просто понатыкав провода в макетную доску. Там видно Arduino, усилитель, шунт и подключенный телефон.
Измеряли мы сначала в разрыве провода USB, потому что это просто: порезал провод пополам, вставил туда шунт, и всё измеряется. Это у нас был такой proof of concept.
Мы получили первые графики. Вот на столе у нас лежит Power Monitor, мы сравнивали результаты с ним — поняли, что получается нормально, что-то измеряем, надо продолжать.
Дальше нам нужно избавиться от измерений в разрыве USB. Иначе телефон, прежде чем потребить ток, будет заряжать батарейку, и измерять вы будете этот процесс, а сколько телефон потребляет в данный конкретный момент, не увидите. Поэтому единственный вариант — это вытащить батарейку, питать телефон снаружи от любого источника. В этом случае телефон уже не может накапливать, и увидим реальное текущее энергопотребление.
Вот Тимур разбирает IPhone, чтобы достать оттуда батарейку. Современные батарейки — это умные устройства, это не просто два провода от батарейки, а ещё и микроконтроллер.
Выглядит вот так, мы его отрезали от батарейки IPhone, у него удобный разъем, которым можно подключить его обратно. И подпаялись мы прямо к этому контроллеру, то есть не стали где-то покупать разъём с 4 проводами, и реализовывать какую-то логику внутри.
Итак, мы подпаялись к этому контроллеру. Следующий вопрос: как теперь это разработчикам отдать. Страшно выглядит, смахнёшь со стола — всё сломается, надо как-то обратно закрыть корпусом.
В статье про battOr предлагается сделать гибкую печатную плату, которую можно в щёлочку из корпуса вытащить. Это, во-первых, стоит немало денег, во-вторых, ещё и не из каждого телефона получится вывести, потому что они плотно закрываются. Поэтому мы решили применить русское инженерное решение. Вот такое:
Мы стали сверлить телефоны. Айфоны сверлятся очень хорошо, удобно, они алюминиевые. Некоторые телефоны стеклянные, они плохо сверлятся, трескаются.
Мы вывели из них провод с разъёмом, он втыкается только одной стороной, полярность не перепутаешь. Готовое решение у нас на тот момент выглядело вот так: коробочка, которую разработчик подключает себе в USB-порт компьютера, а телефон подключает к коробке, и у него всё работает на локальной машине.
Параметры у нашего устройства тогда были такие:
Максимальный измеряемый ток — 3А, для телефонов достаточно. Для планшетов уже может быть недостаточно, но у нас есть идеи, как это победить.
Разрядность АЦП в Arduino 10 bit, это значит, что у нас 1024 градации, которыми мы измеряем входное напряжение или ток.
Частота замеров у Arduino, тогда составляла 500 сэмплов в секунду. Это было первое решение в лоб, и мы думали, что этого всем достаточно, как у Билла Гейтса с его »640 килобайтами памяти». Потом к нам пришли из команды мобильного браузера, показали статью про battOr и сказали, что этого мало. Мы сказали «зачем вам больше 500 измерений в секунду, это ведь и так полно». Они говорят: «Ну вот смотрите, battOr приводят такой кейс: взяли Chrome с Safari и сравнили время отрисовки одного кадра видео на ютубе. Увидели, что Safari лучше по энергоэфективности, чем Chrome. Локализовали место в коде, в котором эта энергия потреблялась, выпилили его, починили Chrome, построили новые графики и увидели, что теперь они с Safari совпадают».
Один кадр видео — это 16 миллисекунд, и за эти 16 мсек мы должны успеть сделать много замеров. Если мы будем измерять с частотой 500 сэмплов в секунду, то одну точку получаем за 2 мсек, а здесь нужно больше. Но насколько больше нам нужно?
Мы взяли другую Arduino (Arduino Due), смогли получить с коробки миллион сэмплов в секунду. Построили графики и увидели, что они получаются достаточно гладкими, поэтому, в принципе, хватает 10 тысяч измерений в секунду.
У нас получилось разогнать Arduino Nano, на который мы первоначально запустились на 500 сэмплах в секунду, до 10 000. Для этого нам пришлось не использовать стандартные библиотечные функции, а написать свои, которые напрямую дергают регистры. Библиотечные функции достаточно медленные из-за того, что они универсальные. Путем модификации прошивки у нас получилось увеличить частоту сбора нашей метрики. И у нас есть потенциал роста, мы можем, использовать другие ядра — например, STM32, буквально на неделе спаяли эту штуку и в ближайшее время будем использовать её, надеюсь, что она будет работать ещё лучше, чем Arduino.
Самое интересное, что мы научились в реал-тайме собирать метрику: прямо листая Facebook на телефоне, можно увидеть, какая страничка твоего друга потребляет больше энергии. Правда, пока мы этим не пользуемся, стараемся пользоваться автоматическими методами. Еще интересно, что этот миллион точек на экране в реал-тайме отрисовывается на Python, меня это просто поражает.
Следующая задача, которая перед нами встала после ускорения нашей железяки, это синхронизация. Что вообще там синхронизировать нужно? Дело в том, что на телефоне, на Arduino, и на компьютере часы разные, их нужно либо сначала синхронизировать, а потом измерять, чтобы у вас логи потом сопоставились с графиком потребления, либо сначала забрать логи, а потом их синхронизировать.
Как эти логи можно синхронизировать с телефоном? В статье про battOr описан метод, как они это делают, и мы решили пойти таким же путём. Генерируем на телефоне всплески энергопотребления, например, с помощью фонарика: зажигаем фонарик — потребление возрастает, гасим — потребление уменьшается. Таким образом мы делаем прямоугольный сигнал, и потом генерируем такой же сигнал, но сами уже, чистый. Получается два графика, один реальный, другой сгенерированный, и мы их сопоставляем, двигая наш референс вдоль исходного сигнала. И ищем точку, где они максимально коррелируют друг с другом, вот она:
Мы попробовали так сделать, сначала подход у нас был в лоб: посчитать cross-correlation, подвинуть, посчитать cross-correlation. С этим подходом было две проблемы. Первая: это очень долго считается, несколько минут на один тест. Когда наш тестировщик загрузил результаты, несколько минут он ждёт, пока синхронизация посчитается, это плохо. И, во-вторых, мы не всегда находили тот самый пик, который нам нужен, иногда смещалось в ту или иную сторону. Disclaimer: «я не настоящий сварщик», но попробую объяснить математику, которую мы применили, чтобы эти две проблемы решить.
Во-первых, мы применили быстрое преобразование Фурье. Кросс-корреляция эквивалентна свёртке с развёрнутым вдоль оси Y сигналом. То есть мы ставим минус перед временем в сигнале или в референсе, и считаем свёртку, получаем кросс-корреляцию. Это первая мысль. Вторая: есть алгоритм FFT-свёртки, который намного быстрее, чем если считать в лоб. Наша синхронизация считалась несколько минут, а с этим алгоритмом мы считаем меньше секунды на тест.
Как работает свёртка: мы переводим нашу функцию, наш референс в frequency domain. То есть у нас был график, где горизонтальная ось — это время, а стал график, где горизонтальная ось — это частоты. Потом мы перемножаем эти два получившихся графика, и преобразуем обратно в time domain. Делаем это с помощью быстрого преобразования Фурье, звучит сложно, но на Python одна строчка, вот такая:
Я математику привёл, чтобы показать, что Python — это круто! Таким образом мы решили проблему с производительностью нашей синхронизации. Следующая проблема с неустойчивостью. Откуда она вообще берётся? Вот типичный график, который мы тогда наблюдали, который был неустойчив:
На нем наш референс, видно, что он совпадает с миганием фонарика. Зеленый — график кросс-корреляции. И у этого графика есть проблема: разница между пиками по высоте не такая большая, и у нас есть ещё на нашем графике шумы, связанные с тем, что мы в экран тыкаем, шторку двигаем, где фонарик включается, руками, и этот график может сместиться вправо, например, причем это в разных случаях происходит, иногда происходит, иногда нет.
Мы попробовали мигать программным кодом в рандомной последовательности. Тут тоже была проблема — иногда это хорошо работало, иногда не очень. И мы подумали, что, наверное, есть какая-то оптимальная форма сигнала, чтобы он хорошо сопоставлялся. Я стал искать в интернете, наткнулся на очень интересную лекцию
про то, как самолет летает над льдами Антарктики и измеряет толщину льда.
Оказалось, что они используют тоже самое. Самолет излучает сигнал, принимает сигнал обратно, и ищет корреляцию с референсом.
Вот так выглядит полученная картинка, они нашли толщину льда:
И у них была такая же проблема. Связана она с тем, что, когда вы берете рандомный сигнал, и ищете корреляцию самим с собой…
Вот здесь слева вверху — рандомный сигнал, чуть-чуть шума туда добавлено, и под ниже — кросс-корреляция с самим собой, только сдвинутым. И видно, что пик там не очень ярко выраженный. Зато, когда вы берёте сигнал с увеличивающейся частотой (справа вверху), то вы получаете сигнал с ярко выраженным пиком (справа внизу).
Мы тоже стали мигать программно фонариком с увеличивающейся частотой. Вот так это выглядит на графике:
И наша синхронизация стала работать намного устойчивее. Вертикальные желтые линии на графике — это мигание фонарика из логов, синие линии — это потребление тока. И справа мы видим события из логов, тут отображены только мигание фонарика, но на самом деле вы там можете видеть вообще все события из логов и сопоставлять их с исходным графиком.
Теперь о том, как выглядит типичный тест, с точки зрение тестировщика или разработчика. Во-первых, мы можем гонять наши тесты вручную.
Как это происходит: мы берем телефон, отключаем USB (чуть позже объясню, зачем), стартуем запись измерений, мигаем фонариком вручную или с помощью специального приложения, потом что-то делаем на телефоне, выполняем какие-то сценарии, которые мы хотим замерить, останавливаем запись измерений, подключаем USB обратно, скачиваем логи с телефона, они автоматически синхронизируются и загружаются в нашу систему для отчетов.
С помощью таких тестов мы смогли сделать разные измерения, например, сравнить разные приложения музыки по среднему энергопотреблению за время сценария:
Cравнить потребление браузера во время холодного запуска, переходов по ссылке и других сценариев:
Но мы, понимая, что ручных тестов мало, потому что тестировщиков не напасёшься все померить, поэтому мы стали думать, как это всё автоматизировать.
Для автоматизации в первую очередь нам пришлось решить проблему с тем, что телефон, когда подключен по USB начинает питаться не от батарейки, а от USB. Универсального решения нет: кто-то отключает потребление программными средствами, но это не везде можно сделать, на IPhone тем более.
Поэтому мы придумали вот такой провод, который не дает телефону больше 20 мА. Устроен он просто: там стоит один полевой транзистор (или, если вам нужно переключать уровень тока, несколько полевых транзисторов).
И мы стали всем раздавать эти провода для автоматических тестов. Но это не единственная проблема, которая у нас возникла. На этой схеме есть проблема, заключается она в том, что USB вам подключать нельзя.
Потому что у вас образуется петля по земле, а минус на телефоне, и земля USB на телефоне — это разные вещи, между ними есть разность потенциалов, и у вас начинает идти ток, мы сначала решали это с помощью этих 10 кОм резисторов, т.е. у вас ток такой большой не идет, но это нам портило все измерения.
И мы решили в нашу схему добавить гальваническую развязку. Сделано на базе специального чипа, через него проходит сигнал, но не проходит ток, и нам пришлось вынести наружу наш АЦП. То есть сначала мы использовали аналого-цифровой преобразователь в микроконтроллере, а теперь мы поставили отдельный чип, который измеряет непосредственно напряжение с датчика.
Внешний АЦП мы выбрали получше, чем тот, который в Arduino стоит, и у него битность побольше. Но на картинке выше можно найти фейл. Тимур может, потому что ему конденсатор в лоб прилетел один раз, и теперь он хорошо ищет. Отгадка — под спойлером.
Перепутал местами, как устанавливать микроконтроллеры, в итоге ничего не работало, я не мог разобраться, а Тимур заметил ошибку по одной промелькнувшей в рабочем чате фотографии.
Процесс автоматического теста у нас выглядит примерно так. Мы отправляем тест-лист (сценарий нашего тестирования, config) на сервер. Сервер у нас стартует запись измерений, автоматически мигает фонариком, затем у нас гоняется тестовая сборка, это JAR-ник на телефоне.
Затем все грузится в нашу аналитическую систему, и там мы видим разные графики. У разных команд по-разному, это на примере команды браузера:
У них тесты поделены на так называемые suites. Один suite — это набор тестов на определенную функциональность браузера: что-то тестирует только сеть, что-то только UI. И когда такой suite начинает запускаться, они ставят в логи метку «мы начали тестировать UI», когда заканчивается — «мы закончили тестировать UI». Мы совмещаем логи с графиком потребления и выделяем на графике потребления фрагменты, когда что тестировалось.
Таким образом мы можем следить за регрессиями, за тем, как от версии к версии браузера меняется потребление определённого набора тестов: UI, сеть и т.д.
Вот мы выделяем фрагменты, мы каждый тест можем запустить несколько раз, чтобы набрать статистику по ним, чтобы наиболее устойчивые результаты были, и потом мы строим графики регрессии.
Теперь Тимур расскажет о том, как вам это сделать дома.
Как это сделать
Тимур Торубаров:
Вы, наверное, заскучали, Алексей рассказывал про всякие сложные штуки, про математику, микроконтроллеры. А я буду развлекать.
Алексей уже рассказал, что мы на нагрузочные тестировщики, и мы делаем Яндекс.Танк. И с Volta, так называется наш проект, мы поступили точно так же: мы выкладываем в опенсорс, его можно скачать, потрогать руками.
Но «не повторяйте это дома»: техника дорогая, особенно iPhone, поэтому делайте все на свой страх и риск, и либо будьте очень осторожны, либо приготовьте заранее десять айфонов.
Итак, мы хотим сделать, например, чтобы мой Android доживал до вечера, чтобы телефоны у всех людей жили подольше, чтобы производители заботились, софта в том числе, как работают сами железки, и оптимизировали, как могли со своей стороны свой софт.
Давайте попробуем собрать такую коробку, о которой рассказывал Алексей, собственными руками, быстро и из подручных средств. Здесь три компонента: датчик тока, блок питания и микроконтроллер, каждый из этих компонентов можно купить на AliExpress за 50 рублей.
Для начала нам потребуется питание. Мы взяли готовую плату на базе модуля XL4005, 50 рублей на Aliexpress, это DC-DC step down преобразователь напряжения. Мы питаем его от ноутбучного блока питания, который почти бесплатно добываем в helpdesk, потому что сотрудники при замене ноутбуков сдают старые вместе с блоками питания, их целая гора лежит, мы приходим и коробками забираем. Нам говорят «спасибо», но они, наверное, не знают, что мы с ними делаем потом.
Но подходят не все блоки питания, нужно аккуратно замерять разность потенциалов между минусом на выходе и USB, чтобы не спалить что-нибудь (например, новенький Macbook).
Ноутбучные блоки питания питаются от 220 В, и ребятам из геосервисов это не очень было удобно тестировать свои приложения с геолокацией: они ходили по улице вокруг офиса с большим семикилограммовым UPS со свинцовыми аккумуляторами, с ноутбуком, с нашей коробочкой и телефоном. Вокруг офиса Яндекса нормально так ходить, люди не задают вопросов, но на вокзал с таким лучше не приезжать.
Специально для них мы сделали коробочку, которая питается от аккумулятора. И записывает данные на SD-карту, можно потом прийти куда-нибудь в офис, скачать, загрузить бэкенд и все замечательно работает. Удобно ездить в командировки, ребята с такими штуками ездили в Беларусь, вопросов не возникло. Кстати, она работает от прикуривателя: Kia cee«d Алексея выдержала испытание.
Второй компонент этой коробочки — это датчик тока, покупается на AliExpress за 50 рублей, очень удобный. Он преобразует ток в напряжение, один ампер в один вольт. Мы, соответственно, опрашиваем его микроконтроллером. Диапазон измерений у него от нуля до трёх ампер, нам подходит идеально. Но у него есть проблема: нет гальванической развязки, о которой уже рассказывал Алексей.
Не делайте так.
Дальше микроконтроллер. Можно взять Arduino Nano, к удивлению, он стоит 50 рублей на AliExpress, у него встроенная АЦП и удобно писать прошивки: либо в Arduino Studio, либо в Platformio IDE. Мы взяли Platformio IDE, потому что оно и ставится из консоли одной командой, и прошивки забиваются одной командой, супер.
Собираем всё это, выглядит это так: питание, датчик тока, микроконтроллер и телефон, который через датчик тока питается от блока питания.
Заливаем прошивку на микроконтроллер, готовые прошивки можно взять у нас, есть как для 500 сэмплов в секунду, так и для 10 000, заливается одной командой. Для автоматизации, для каких-то консольных штук — это идеальное решение.
После того, как мы собрали коробку, нам нужно подготовить телефон.
Алексей включил в презентацию это видео, потому что хотел подшутить надо мной, и посмотреть, как я выкручусь… В общем, не знаю, чем я руководствовался, когда делал это на коленях, но точно не техникой безопасности.
Это переносная коробочка, которую мы собираем для гео-сервисов. В общем, нужно подготовить телефон. Алгоритм очень простой: нужно его разобрать, вытащить аккумулятор, отрезать от аккумулятора контроллер, припаять к ним провода и собрать обратно. Но телефоны все разные, и это проблема.
Есть целая пачка проблем (особенно у iPhone): бывают хрупкие элементы, ненадёжные шлейфы. Например, такая история: когда мы разбирали iPhone 5, обнаружили кучу шлейфов, идущих к дисплею, и все они крепятся к материнской плате металлической крышкой. Крышка привинчивается к материнской плате четырьмя болтами, и все четыре одинакового размера, но разной длины. Понимаете, в чём подвох? Если болт вкрутить не туда, он пробивает материнскую плату, а она у iPhone почти цельная: починить эту штуку очень сложно.
При этом разница в длине — что-то в районе 0,1 миллиметра, на глаз её не видно. То есть, если ты не прочитал, то ты не знаешь об этом. А в итоге все форумы забиты любителями, которые разбирали, потом собирали и натыкались на это. И мы так тоже лишились iPhone 5.
Ещё мы очень не любим телефоны со стеклянными корпусами. Одна корейская компания, у которой недавно возгорались аккумуляторы, ещё любит всё клеить и любит стеклянные корпуса. Мы не то чтобы не любим эту компанию, но разбирать её телефоны для нас проблема.
И после того, как у нас подготовлена коробка, подготовлен телефон, нам осталось только установить софт. Мы используем Python и устанавливаем командой «pip install volta».
Вот так это выглядит под капотом:
Я показываю это только для того, чтобы вы поняли, что мы там всё продумали. Не стоит в этом разбираться. Я писал это два месяца.
И сейчас покажу демку, как мы тестируем реальное приложение Яндекс браузера.
Мы используем Jupyter Notebook, Python pandas — все эти приколы, потому что мы нагрузочные тестировщики, мы любим статистику. Будем работать с Volta, как с библиотекой.
Импортируем библиотеку, создаём config, указываем там путь к устройству, тип коробки (binary), и напряжение. Напряжение задаётся произвольно, как вы там накрутили на DC-DC. И создаём класс Voltabox, запускаем сбор данных, start test.
Данные собираются. Мы можем прочитать одну секунду из этих данных, на выходе мы получаем pandas dataframe. Сделаем describe, смотрим и видим, что в dataframe за 1 секунду 10 000 значений (это коробочка 10 кГц), и в среднем потребление 116 мА.
Проводим тесты, останавливаем запись командой volta_box.end_test (), сейчас для скорости не будем этого делать. Остановив тест, выполняем пару функций. Одна из них вычитывает из очереди с результатами данные и подготавливает их, собирает в нужные dataframe. Вторая строит по подготовленным данным графики, мы их покажем.
В принципе, поскольку код лежит в опенсорсе, его сейчас до каждой запятой комментировать не будем. Главное: строим графики, готовим данные, получается вот такая красота, на которой ничего не понятно.
Синие — это потребление тока. Значений очень много, поэтому так шумит, и мы для наглядности построили красный moving average, скользящую среднюю. Сейчас мы будем разбираться, что происходит на этом графике.
В процессе тестов мы собираем с телефона логи, и различные события можем записать в logсat, потом получить их на компьютер, а на графики их потом поставить автоматически (с помощью той синхронизации, о которой говорил Алексей). И мы видим события включения чего-то на телефоне, уже не помню, что именно мы включали здесь. Это был тест с какой-то сборкой Яндекс.Браузера, там был патч, который разработчик написал за ночь (наверное, достигнув пика Балмера).
В общем, он захотел быстро катить в прод, говорит: «Смотрите, у меня вот такой патч, он принесёт много денег, давайте его протестируем». У менеджера загорелись глаза: «Давайте катить», мы начали тестировать. Взяли два приложения, без патча и после, и начали сравнивать. Первый запуск с патчем, второй без патча. Выберем по секунде из этих участков, сведем всё это на один график и посмотрим:
У нас есть некий Baseline, он указан серым, это когда телефон просто лежит с включённым дисплеем. У нас есть синяя линия — это запуск теста без патча. И у нас есть красная линия, которая, наверное, приносит много денег, но почему-то она выше всех. И здесь очень спорная ситуация: если пользы много, может, её можно и выкатить, а в будущем попатчить. Но, скорее всего, разработчик будет что-то переделывать и доделывать, чтобы оно работало оптимально и не задевало пользователей, потому что если у пользователя сядет аккумулятор из-за нас, мы будем страдать. Потому что он уйдет.
Мы наполучали кучу метрик, и дальше мы уже с ними можем работать, сравнивать, считать квантиль, среднее — сейчас не будем глубоко вдаваться в аналитику. Важно то, что у нас получилось из подручных средств собрать устройство, которое позволит замерить энергопотребление и отойти от процентов и трёхдневных тестов к метрикам, с которыми уже можно работать, которые можно сравнивать, по которым можно строить регрессию, back-to-back-тесты и все эти привычные штуки, с которыми приятно и удобно работать.
На прощание демонстрирую Nexus: вы видите, у него нет задней крышки, нет аккумулятора, даже кнопки включения… Включить смог-таки, но пин-код не помню. Ребята из браузера перестраховались.
Полезные ссылки:
Понравился этот доклад? Обратите внимание, что уже на этой неделе пройдёт Heisenbug 2018 Piter, где тоже будет целый ряд интересных выступлений. Например, Яндекс будет представлен и в этот раз, сразу двумя докладами: «Краудсорсинг в тестировании» и «Atlas — ваш новый путеводитель по PageObject».