Рубрики
Uncategorized

Тестирование в облачной родной эре

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

Написано Фернандо Майо

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

Вы всегда тестируете

Когда вы думаете о «жизненном цикле разработки программного обеспечения», вы, вероятно, сделаете что-то подобное:

Согласно традиционной мудрости «тестирование» — это то, что мы делаем после того, как мы закончим развиваться, и прежде чем мы начнем развертывать. Но в мире, где монолитные приложения разбиваются на меньшие «услуги», это традиционное определение тестирования больше не проводится истина. Это связано с несколькими факторами: растущая сложность (количество развертываемых артефактов и API, независимые графики выпуска, количество сетевых вызовов, постоянные магазины, асинхронный коммуникация, множественные языки программирования …), более высокие показатели потребления сторонних API от ошеломляющего разнообразия, Частое развертывание благодаря консультациям CI/CD и смягчающей мощности, когда речь идет о наблюдаемости и мониторинге.

Вы тестируете, когда вы запустите несколько модульных тестов, прежде чем нажать код, или когда CI автоматически запускает набор тестов интеграции каждую ночь. Но вы также проверяете, когда менеджер продукта использует вашу постановку, чтобы попробовать новую функцию, или когда вы постепенно отправляете трафик на новую версию вашего приложения, которая была просто развернута, и вы постоянно контролируете ошибки. Вы также проверяете, когда вы запускаете периодические проверки, которые автоматически подключите UI, чтобы выполнить синтетическую транзакцию на вашем экземпляре производства. И да, когда ваши клиенты используют ваше приложение, они помогают вам также проверить.

На что мы тестируем?

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

  • Правильность : Делает ли это то, что я хочу, чтобы это сделать без дефектов?

  • Производительность : Отвечает ли это на своих потребителей с приемлемой задержкой?

  • Надежность : Деладут ли это изящно, когда зависимости недоступны?

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

Правильность Является ли аспект, который мы обычно ассоциируем Тестирование с участием. Мы немедленно подумаем о единицах и тестовых люксах интеграции, которые гарантируют, что приложение возвращает ожидаемый ответ на набор предопределенных входов. Есть также другие очень полезные подходы к тестированию правильности, например тестирование на основе недвижимости , Fuzz тестирование и Мутация Тестирование , что может помочь нам обнаружить более широкий диапазон дефектов автоматизированным способом. Но мы не должны там остановиться.

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

Производительность Является ли очень важный аспект качества любого программного приложения, но мы не активно не теряем для него столько, сколько мы должны, поскольку это становится сложным усилением для выяснения, какая комбинация данных, шаблонов доступа и конфигурации окружающей среды будет одним Большинство представитель «производства», что в конечном итоге в конечном итоге определяет производительность нашего приложения, как видно конечным пользователем.

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

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

Надежность Очень часто упускается из виду, когда мы предвзяты к тестированию на «Счастливый путь». Это было не большая часть вопроса в мире монолитов — режимов неудачи были немногие и в основном известные. Но в смелом новом мире микросервисов количество способов нашего приложения может потерпеть неудачу, взорвалась. Это также аспект нашего приложения, который, если не правильно и тщательно протестирован, имеет самое прямое влияние на опыт конечного пользователя.

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

Инвестирование в отказ инъекции и Хаос Инжиниринг В производстве есть еще один вариант, если мы считаем, что есть возможные неудачи, которые мы не можем воспроизвести в контролируемой среде, и нам нужно прибегать к тестированию их непосредственно в производстве.

Современное тестирование Toolbox

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

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

Как мы видели ранее, некоторые из этих новых методик обеспечивают безопасное тестирование в производстве, если сделано правильно . Например, развертывание Canary позволяет тестировать приложение в производстве для небольшого процента реальных пользовательских данных. Для этого на работу приложение должно быть разработано таким образом, чтобы поддержать этот вид тестирования, например, путем добавления соответствующих метрик для обнаружения, когда есть проблема, журналы и/или следы для устранения неполадок, что пошло не так, как тест Не удается, и, убедившись, что нет побочных эффектов на любом хранилище данных, если развертывание необходимо откатиться. Хотя могут возникнуть случаи, когда эти методы тестирования могут помочь нам эффективно тестировать, они сложны для настройки и выполнения, и нужно понимать все предпосылки и последствия выполнения таких испытаний.

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

Значение тестирования

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

Мы также знаем, что в какой-то момент наше приложение не будет выполнять, как ожидалось, независимо от того, сколько мы тестируем. Просто слишком много факторов, которые мы не можем предвидеть: слишком много возможных пользовательских входов, слишком много состояний, в котором ваше приложение может оказаться, слишком много зависимостей, которые находятся за пределами вашего управления. Так зачем тестирование, если мы не можем полностью избежать неудачи? Когда мы должны остановиться? Спускается к управлению риск Отказ

Тестирование о уменьшение риска вашего приложения неожиданно выступает на Самая низкая возможная стоимость .

Расходы, связанные с уловами вопросов в производстве

Давайте рассмотрим стоимость решения проблем в производстве. Это происходит в разных формах:

Стоимость обнаружения :

  • Как и когда я получаю уведомление, если он не работает должным образом?

  • Нужно ли пользователю уведомить нас от проблемы?

  • Какова временной задержка между проблемой, введенным в заявке, и кто-то в организации предупрежден?

  • У нас есть автоматическое оповещение, или мы должны активно контролировать приборную панель?

  • Уверенная работа работает правильно?

  • У нас есть правильные метрики?

  • Как мы обнаруживаем неочевидные проблемы, которые не сопровождаются шипом в задержек или повышенной скоростью ошибки?

Устранение неисправностей Стоимость :

  • Как только я знаю, что есть проблема, как я узнаю, что это вызвало?

  • Добавил ли я соответствующую инструментацию (метрики, журналы, следы, исключения) для отладки проблемы?

  • У Metrics имеют правильные теги и разрешение, чтобы помочь с отладкой?

  • У нас есть журналы, или они были удалены из-за хранения политики?

  • Есть соответствующие следы для устранения неполадок были отобраны?

  • Каковы расходы, связанные с обработкой и хранение этой информации?

  • Должен ли я воспроизвести проблему в другой среде, чтобы узнать больше об этом? Сколько времени это займет?

  • Я знаю, у кого есть знания, чтобы отладить это?

  • Когда это было введено?

Стоимость фиксации :

  • Кто в команде ответственность за исправления этого?

  • У них есть пропускная способность, чтобы решить проблему?

  • Могу ли я откатиться благополучно, чтобы временно исправить проблему, или я вынужден придумать посадку как можно скорее и управлять вперед?

  • Проблема повлияла на любые хранилища данных или других услуг, которые сейчас нужно убирать?

  • Как долго исправление будет предпринять для распространения через все пораженные среды?

Стоимость подтверждения :

  • Могу ли я автоматизировать проверку исправления или ему нужна ручная проверка?

  • Сколько времени и ресурсов подтверждают исправление?

  • Должен ли я полагаться на пострадавшего пользователя для проверки?

  • Могу ли я проверить все возможные перестановки вопроса?

  • Могу ли я проверить исправление без побочных эффектов на экземпляр производства?

Стоимость воздействия пользователей :

  • Пользователи влияют на вопрос?

  • Если они, сколько, и как долго?

  • Бизнес теряет деньги?

  • Является ли бренд или репутация компании отрицательно затронуты?

  • Сколько вспомогательных билетов привело к этой проблеме?

  • Какова стоимость переработки и ответа на эти блюда поддержки?

Как вопросы приближаются к конечному пользователю приложения, тем дороже становится все дороже, чтобы устранить их. Ошибка, обнаруженная с помощью тестирования подразделения, что разработчик пробежал локально при работе над филиалом функции, например, является самым дешевым на вопрос: ошибка была обнаружена сразу после того, как разработчик представил его (стоимость обнаружения); Легко отлаживать, так как он точно определяет, где проблема, наряду с богатой информацией отладки (стоимость устранения неполадок); Разработчик только что ввел вопрос, поэтому у них уже есть правильный контекст, чтобы быстро исправить проблему (затраты на фиксацию), может немедленно проверить исправление, повторно запустив тест (верификация), и проблема привела к нулю пользователям.

С другой стороны, проблема, которая возникает неделями после того, как новая версия была выпущена для пользователей, возможно, является самой дорогой. Затраты на обнаружение, устранение неисправностей, фиксации, проверки и воздействия пользователя все будет на самом высоком.

Обратите внимание, что у меня есть Разделены производство от Конечный пользователь Отказ Используя канарские развертывания или флаги функций, проблема может достигать добычи, в то время как мы контролируем, какие конечные пользователи подвергаются, если все равно. В этом случае проблема обнаружена после Развертывание к производству (новый код работает в производственной инфраструктуре), но перед освобождая его всем пользователям (Никаких пользователей или только небольшая доля пользователей обслуживается новым кодом), помогает смягчить стоимость воздействия пользователей, но все другие расходы по-прежнему применяются.

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

Тестирование может быть дешевым, но это никогда не бывает бесплатно

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

  • Создание стоимости : Сколько времени и усилий необходимо для записи теста и сделать систему реагировать?

  • Стоимость исполнения : Сколько времени нужно, чтобы на самом деле запустить тест, чтобы получить отзыв? Сколько вычислительных ресурсов это потребляет?

  • Стоимость обслуживания : Если я изменим свое приложение (рефакторинг, новую функцию и т. Д.), Сколько времени и усилий требуется, чтобы обновить тест соответственно?

Любая команда разработки программного обеспечения должна быть на вершине своих расходов на тестирование и активно управлять им, как любой другой аспект кода, который они пишут. Сокращение стоимости исполнения может быть сделано во многих отношениях: удаление перекрывающихся тестов, убедившись, что тесты работают быстро (делая ввод/вывод, только если это абсолютно необходимо, и использование издеваний, где это возможно), выполняя только тесты, которые охватывают код, который имеет изменился (Мне нравится Go Test , jest или Bazel do), или «неудача быстро» и получая обратную связь перед всеми тестами.

Флакистые тесты (определенные как тесты, которые оба проходят, и сбой с той же кодовой базой), особенно дорого, так как они не просто вводят шум и отвлечение и отвлечение, а необходимость повторных попыток — они уменьшают доверие разработчика в системе, а также будут замедляться Рабочий процесс (сборка должна быть зеленой, чтобы продолжить), или повысить риск (мы знаем, что тесты, провалившись, — так что давайте продолжим в любом случае). Флайвость должна быть Измеряется и сводится к минимуму. Некоторые тесты должны будут выполнять операции ввода/вывода и по своей природе будут иметь некоторую степень вспышки — в этих случаях, добавляя повторные попытки к тесту или сделать операции ввода/вывода более устойчивыми к переходным сбоям, может быть наиболее эффективным способом для их решения Как переписать их полностью удалить вспухлость может быть намного дороже или даже невозможно. Методы, такие как смежные зависимости от Запись и воспроизведение HTTP Traffic (А своего рода Тестирование снимков Но для интеграционных тестов), также может помочь уменьшить вспухлость и ускорить тестирование.

Стратегии для снижения стоимости тестирования

Стоимость выполнения тестов может быть уменьшена путем эффективной стратегии при запуске их. Например, запуская только быстрый модуль и тесты интеграции, на месте, при работе с исправлением ошибки или новой функцией, мы сокращаем время для обратной связи от разработчика. Затем, после нажатия кода в центральный репозиторий, CI может выбивать раунд более глубоких тестов интеграции. Мастер-филиал может иметь ночную пробежку более длительной и более дорогой системы или сквозных испытаний и т. Д.

Идея состоит в том, чтобы сбалансировать стоимость выполнения за время получения обратной связи; Например, путем сокращения стоимости выполнения мы увеличиваем стоимость устранения неисправностей/проверки: путем запуска тестов реже, мы создадим «пробелы» в истории тестируемых казней, которые, в случае сломанного теста, представит более широкий поиск пространство для фактического виновника отказа; Чем менее частые тестовые исполнения, тем шире пробелы в истории, как показано в приведенном выше графе.

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

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

Как мы проверим, что мы не знаем, могут потерпеть неудачу?

Как мы уже видели, тестирование позволяет нам обнаруживать, отладки и исправлять проблемы более дешевым способом, чем ждать их, чтобы их всплыть пользователем. Но как мы тестируем на вещи, которые мы не знаем, что может потерпеть неудачу? Как мы тестируем на Неизвестные неизвестные ?

Наша цель должна заключаться в том, чтобы привести как можно больше информации для известных известных квадранта, которые являются фактами о нашем обслуживании. Когда мы изменим что-то в нашем приложении, предыдущие известные известные являются недействительными. Тестирование помогает нам перейти от Известные неизвестные к Известно известно , то есть. Мы знаем вопросы, которые нужно задать, и выполняя тест, мы получим ответ. Мы можем сделать это автоматическим, быстрым и очень эффективным способом. Например, «делает эту функцию возвращает то, что я ожидаю, когда я предоставлю эти конкретные аргументы?», «Возвращает ли мой сервис 400, когда пользователь отправит неверную полезную нагрузку?» Или «UI показывает сообщение об ошибке, когда пользователь пытается войти в систему с неверным паролем?».

Неизвестные неизвестные Это проблемы, которые появляются, что мы не ожидали, потому что мы даже не знали, что они могут произойти. Мы не можем тестировать для них, как по определению, мы не знаем, что на самом деле может потерпеть неудачу, пока он не будет. Для этого дела хорошие приборы и инструменты в производстве позволит нам отладки (а иногда обнаруживать) новые проблемы, которые мы не могли предвидеть, но это приходит с высокой стоимостью. Если корневая причина, наконец, в конечном итоге в конечном итоге может прийти в будущее (а не просто преходящей оперативной проблемой), всегда хорошая идея написать Самые дешевые Тест возможна для этого, чтобы избежать регрессий и довести его до известные неизвестные Quadrant для будущих версий программного обеспечения, который сэкономит нам драгоценное время.

Сколько достаточно тестирования?

Мы знаем, что тестирование никогда не сможет сказать нам, что наше приложение на 100% надежно, поскольку тестирование касается управления риском. Вот почему традиционное охват тестирования не является хорошей мерой качества или целевой группе, на которой должна сосредоточиться инженерная команда. Как мы видели, тестирование подразделения является лишь одним из многих методов, которые мы должны использовать, чтобы проверить наши услуги — и покрытие кода основано на этом. Он может только сказать нам, насколько обширные наши модульные тесты, но нет, если мы создаем высококачественный сервис.

Что мы можем вместо этого использовать? Мы инстинктивно знаем, что если мы не проверяем наше приложение, его качество не будет соответствовать стандартам наших пользователей. Мы также знаем, что мы могли бы просто продолжать инвестировать в тестирование навсегда, и мы никогда не достигнем совершенства. Есть компромисс где-то посередине, но как его измерить?

Производительность (задержка) и надежность (наличие) аспекты вашего приложения должны быть уже измерены и контролироваться с соответствующим SLO Отказ SLOS предоставляет цель, которую вы должны стремиться к этим размерам. Тестирование должно поддерживать удары этих целей, что будет зависеть от требований к применению. Критические услуги будут иметь очень агрессивные SLOS, что требует высокого уровня инвестиций в тестирование, а некритические услуги будут иметь более расслабленные требования. Только непосредственно связывая бюджет тестирования к объективным целям, таким как SLOS, предоставит правильные стимулы для команд, чтобы решить, сколько риска они хотят удалить.

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

Вывод

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

Только тогда можно тестировать возврат, чтобы быть бесценным союзником, что он когда-то был в доставке высокого качества программного обеспечения.

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

Ваше путешествие к лучшему инженению через лучшее тестирование начинается с объема .

Оригинал: «https://dev.to/kickingthetv/testing-in-the-cloud-native-era-5973»