[Перевод] Онбординг-рулетка: о том, как мы ежедневно удаляем аккаунты своих сотрудников
Я твердо убежден в необходимости автоматических тестов и весьма дисциплинированно подхожу к их написанию. В программировании невероятно сложно соблюдать функциональную корректность и еще сложнее не допускать регрессионных ошибок. Как говорил автор Майкл Физерс, «Legacy-код — это любой код, в котором не хватает теста».
Для некоторых вещей — конечных точек серверов, схем баз данных, компонентов UI-библиотек — тестирование проходит довольно незамысловато. Другие тестировать сложнее, например конечные точки, которые вызывают сторонние API, веб-страницы react со сложными состояниями или асинхронные процессы, требующие подробной записи в базе данных. Когда я работал в Airbnb, то испытывал затруднения при тестировании смены пароля через электронную почту из-за того, что отправка писем обычно осуществляется на стороне.
И всё же функциональность такого рода заслуживает, чтобы ее тестировали, по двум причинам. Во-первых, здесь тоже важно избегать регрессионных ошибок, а их возникновение становится еще вероятнее ввиду сложности. Во-вторых, обязанность тестировать сложную функциональность часто вынуждает разработчиков проектировать ее так, чтобы это было возможно. Раннее подключение тестов может способствовать большей лаконичности интерфейсов и меньшей связанности, что повышает качество кодовой базы в долгосрочной перспективе.
Тестировать или не тестировать?
Нет в мире совершенства — бывает, что на прописывание функциональности время есть, а на внедрение автоматизированных тестов к ней — нет. Почему так? Это как проблема равенства классов P и NP, только наоборот: многие виды функциональности проще создавать, чем тестировать. Представьте себе приложение со списками дел на React, в котором для удаления элемента нужно смахнуть его с экрана. Сделать такое можно за полчаса, но потом часы или даже дни провести за созданием автоматизированных тестов для UI, которые будут проверять, работает ли смахивание. Подобный дисбаланс в сочетании со спешкой, которую насаждает бизнес, приводит к тому, что команды прописывают функциональность и опускают затратные тесты.
Плохо ли это? Если смотреть на вещи прагматично, то не всегда — есть случаи, когда влезть в долг и реализовать функциональность без тестов будет оправданным решением. Может сложиться так, что непротетсированная возможность принесет существенные выгоды, в то время как тесты потребуют больших затрат, а ресурсов у вас мало. Возможно, вам не хватает людей в команде или вы вообще пишете личный проект вечерами. Если вы будете заставлять себя прописывать автоматизированные модульные тесты к своему приложению со списками дел, то оно, возможно, никогда не дойдет до своего первого десятка трендсеттеров. Впрочем, если вы и имея миллион пользователей не будете тестировать смахивание, значит, откровенно напрашиваетесь на неприятности.
Откладывая автоматизированное тестирование легко покатиться по наклонной, но создание продукта подразумевает искусство стратегически просчитывать, когда следует брать в долг. Подобные «займы» позволяют команде быстро проводить валидацию, а ту ценность, которая при этом обнаруживается, можно потом пустить на выплату технического долга (с процентами). Сказанное справедливо для стартапов, собирающих венчурный капитал, а также для команд, работающих над MVP. Если с самого начала тратить слишком много времени на дорогостоящие тесты, его может не хватить на то, чтобы выдавать результат, учиться и маневрировать.
Как гарантировать, что ваш код больше никогда не будет использоваться: «Пришлось приложить дополнительные усилия, но теперь мы сможем пользоваться этим во всех будущих проектах»
Как гарантировать, что ваш код будет жить вечно: «Давай не будем копать слишком глубоко, если этот код еще кто-то будет использовать в таком далеком будущем, у нас появятся проблемы и посерьезнее»
Источник
Проявляем креативность
Имейте в виду, что отсутствие автоматизированных тестов не предполагает полный отказ от тестирования вообще. По умолчанию, отсутствие тестов означает, что вы исподволь заставляете пользователей искать баги за вас. Отслеживание трафика в продакшне и хорошо налаженная система быстрого реагирования могут выступить в роли слабой замены автоматизированного тестирования, но тогда стоит иметь в распоряжении быстрые откаты и флаги и держать руку на пульсе.
Однако лучше отслеживать не весь трафик, а только его часть — зачастую для выявления регрессивной ошибки необязательно, чтобы все пользователи наткнулись на баг, хватит и нескольких. Тут вам хорошо послужат канареечные релизы и бета-тестеры. Но проблема того, что настоящие пользователи также сталкиваются с регрессионными ошибками, остается, поэтому здесь нужен тщательный мониторинг, чтобы заметить, когда пользователям приходится несладко.
Догфудинг — это еще лучше, чем бета-тестеры. Пусть функциональность, для которой вы не хотите прописывать автоматизированные тесты, испытают реальные пользователи — только этими пользователями будете вы сами. Собственный продукт не бросишь в ярости, а собственные глаза отлично работают как инструмент динамического оповещения (не забывайте только закрывать их на восемь часов еженощно).
Борьба за онбординг
Итак, у нас есть целый диапазон способов протестировать функциональность — автоматизированные тесты, канареечные релизы, бета-группы, догфудинг. Команда разработчиков Graphite пользуется всеми этими техниками, и тем не менее в функциональности у нас остаются слепые пятна.
Одним из самых затруднительных для тестирования для нас стал онбординг в продукте. Код там еще тот: включает цикл OAuth с GitHub, асинхронную загрузку метаданных из репозитория, запросы к нашим собственным базам данных, а также кастомные элементы UI, которые больше нигде в приложении не используются. Но, несмотря на все сложности, онбординг имеет ключевое значение, и как-то тестировать его нужно.
Классические синтетические тесты оказываются здесь менее надежными, чем обычно, из-за процедуры обнаружения ботов на GitHub при логине. Тестирование канареечным трафиком мало что дает, так как пользователи, отсеявшиеся на онбординге, редко сообщают о проблеме, а в логах всё зачастую выглядит так, словно они колеблются, а не застряли. Бета-группы редко что-то вылавливают, потому что проходят онбординг всего один раз; то же можно сказать и в отношении догфудинга в его традиционном виде.
Запускаем рулетку
Решение, к которому мы пришли в Graphite — запустить скрипт-рулетку, который каждый день в девять утра случайным образом выбирает один из аккаунтов наших разработчиков на Graphite для удаления. Мы не просто заставляем человека еще раз пройти онбординг, а сносим аккаунт целиком, с токенами, конфигурированными фильтрами, загруженными гифками и прочим.
Раздражает ли это людей в команде? Само собой. Они ведь приходят на работу, чтобы писать код для новой функциональности, а не обнаруживать себя выкинутыми из системы и вынужденными пересоздавать аккаунт с нуля. Поначалу мы вводили эту технику с осторожностью, но преимущества проявились незамедлительно. Отметим, что речь идет только об их аккаунте в продукте Graphite — доступ к GitHub и другим аккаунтам компании остается.
Плохой опыт: перешел к окружению, и там меня встретила страница с затачивающимися карандашами. Ощущение, как будто бэкенд лег.
Неизвестная ошибка при выборе репозиториев по умолчанию.
Кнопка «Продолжить» неактивна, не выдаются подсказки почему. Я застрял и не могу продолжать онбординг.
Разобрался с этим через обновление страницы и выбор других репозиториев.
Теперь на удивление долго сижу на экране «Graphite обновляется — это может занять несколько минут». Уже почти три минуты, и колесико по-прежнему крутится.
Обновил страницу, продолжает крутиться.
Как и большинство других продуктов, Graphite стремится сделать онбординг быстрым, безболезненным и без багов. Для нас самый лучший способ это гарантировать — сделать так, чтобы каждый день кто-нибудь из компании сам отмучился на этой процедуре. Каждый конкретный человек в составе нашей команды, занимающейся конечным продуктом, в среднем подпадает под удаление где-то раз в месяц. Но того, что один сотрудник ежедневно оказывается на острие атаки, как мы выяснили, хватает, чтобы находить баги и мотивировать нас исправлять их.
Удаление аккаунтов сотрудников позволило покрыть догфудингом одну из наиболее важных и наименее доступных для тестирования областей. Мы отловили десятки багов и взрастили эмпатию к пользователю там, где обычно располагается слепое пятно. Я настоятельно рекомендую другим продуктовым командам также рассмотреть вариант с автоматическим удалением аккаунтов сотрудников, чтобы получить те же преимущества.
Текущие ограничения
Работает ли эта схема идеально? Нет. Удаленные сотрудники воссоздают аккаунты в составе существующей организации Graphite. Иными словами, они все-таки пропускают некоторые аспекты, с которыми сталкиваются настоящие пользователи, когда впервые устанавливают Graphite в новой организации, например затяжную первоначальную синхронизацию. В будущем мне хотелось бы опробовать схему с ежемесячным удалением из Graphite всей компании для усовершенствования догфудинга — хотя это создаст уже более серьезные препятствия для утренних правок кода, что вызывает у меня опасения.
Любой ли продукт может себе позволить удалять аккаунты с такой периодичностью, как мы? Полагаю, что нет — на некоторых аккаунтах накапливаются не только конфигурации, но также масса другого ценного пользовательского контента. Instagram или Google Docs, скажем, вряд ли удастся реализовать такой радикальный подход без последствий. Но многие сервисы, особенно такие, где данные, созданные пользователями, не страдают от удаления личных аккаунтов, могли бы им воспользоваться. Продукты вроде Datadog, Vercel, Hex или Superhuman могли бы без проблем удалять аккаунты сотрудников раз в месяц. Конечно, людям бы пришлось заново настраивать свои дэшборды и фильтры, но в этом ведь и смысл.
На будущее
Будем ли мы и дальше продолжать удалять аккаунты сотрудников в Graphite? Предположительно, да. Однако догфудинг не стоит выше автоматизированного тестирования — мы постоянно ведем работу по внедрению нормальных модульных и e2e тестов, не жалея вложений. Но догфудинг отличается от автоматизированного тестирования как раз в достаточной степени, чтобы они давали совокупный эффект. Догфудинг отлавливает неизвестные неизвестные способом, недоступным для автоматизированных тестов. Он порождает среди разработчиков эмпатию по отношению к пользователям –, а также мнения относительно продукта, которые можно учитывать в следующих обновлениях. Если заново создать свой аккаунт оказывается непросто, то каково приходится новому пользователю, начинающему с нуля?