Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Bolee bystraya i uverennaya dostavka obnovleniy
Более быстрая и уверенная доставка обновлений

Источник: Fathom Analytics

Более быстрая и уверенная доставка обновлений

Источник: Fathom Analytics

Мы стали выпускать обновления для Fathom Analytics чаще и с большей уверенностью. Вот как мы этого добились.

24 сентября 2026 г.

Мы стали выпускать обновления для Fathom Analytics чаще и с большей уверенностью. Вот как мы этого добились.

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

В этой статье я хочу поделиться тем, какие «узкие места» мы выявили, какие изменения внесли и каких результатов достигли на данный момент.

Выявление областей для улучшения

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

Мы выделили несколько ключевых областей, которые хотели улучшить:

  • Покрытие тестами — наше покрытие тестами составляло около 60%. Хотя это вполне достойный уровень, его можно было улучшить.
  • Отсутствие CI/CD-конвейера — у нас был набор тестов, который мы могли запускать локально. Но не было конвейера непрерывной интеграции/непрерывного развертывания (CI/CD) для автоматического запуска тестов при каждом запросе на слияние (pull request) или отправке кода в основную ветку. Это означало, что перед развертыванием кто-то из нас должен был запускать тесты локально.
  • Отсутствие статического анализа — у нас не было инструментов статического анализа для обнаружения потенциальных ошибок, которые могли не покрываться тестами.
  • Ручной процесс развертывания — развертывание кода в рабочую среду было ручным процессом.

Внесенные нами изменения

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

Увеличение покрытия и качества тестов

Если вы раньше не слышали о «покрытии тестами», это показатель того, какая часть кода вашего приложения выполняется («покрывается») при запуске тестов.

Например, возьмем простую функцию приветствия (greet), которая возвращает приветствие на основе предоставленного имени:

Допустим, у нас есть один тест, который запускает этот код:

В этом случае мы протестировали строки в функции greet, которые выполняются, когда имя — «Fathom», что означает, что эти строки «покрыты». Но мы не протестировали строки, которые обрабатывают любое другое имя. Поэтому эти строки считаются «непокрытыми», а значит, у нас нет информации о том, работают ли они должным образом.

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

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

По этой причине мы провели аудит существующих тестов и при необходимости улучшили проверки (assertions). Хотя это не увеличило напрямую наше покрытие, это дало нам больше уверенности в том, что наш набор тестов действительно проверяет то, что мы предполагали.

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

В результате мы увеличили покрытие тестами с 60% до 88%. Благодаря этому мы теперь чувствуем себя гораздо увереннее при внесении изменений в кодовую базу. Мы можем использовать тесты, чтобы доказать, что наш код работает и что мы не нарушили существующую функциональность. Конечно, что-то все еще может сломаться, а ошибки могут остаться незамеченными тестами. Но улучшив качество нашего набора тестов, мы снизили вероятность этого.

Добавление статического анализа с помощью PHPStan/Larastan

Хотя наш набор тестов может обнаружить многие потенциальные ошибки, некоторые все же могут проскользнуть. По этой причине мы решили добавить статический анализ в нашу кодовую базу с помощью PHPStan (с Larastan для поддержки Laravel).

Если вы не знакомы со статическим анализом, это способ анализа кода без его фактического запуска. В нашем случае мы можем анализировать код, выполняя команду в терминале. Это позволяет выявить потенциальные ошибки, «запахи кода» (code smells) и другие проблемы. Технически Larastan должен запустить фреймворк Laravel, поэтому это не совсем чистый статический анализ. Но для целей этой статьи это очень близко, и мы будем называть это статическим анализом.

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

Как вы можете себе представить, когда мы впервые добавили PHPStan в кодовую базу, было выявлено множество «проблем». Я использую термин «проблемы» в кавычках, потому что многие из них на самом деле не были ошибками, а просто требовали добавления docblock-комментариев. Мы начали с уровня 0 (самый низкий, наименее строгий уровень) и постепенно решали проблемы в перерывах между работой над новыми функциями. Примерно за неделю нам удалось свести количество ошибок к 0. Ура!

Затем мы повысили уровень до 1 и повторили процесс. На момент написания статьи мы находимся на уровне 2. Но, возможно, к тому времени, как вы это читаете, мы уже повысили его снова (я стремлюсь как минимум к 5-му уровню!).

Добавление PHPStan стало для нас огромным достижением. Он обнаружил несколько мелких ошибок, которые пропустили наши тесты, а также помог выявить «мертвый» код, который мы смогли удалить. Удаление мертвого кода — это всегда хорошо, так как кодовая база становится меньше и ее легче поддерживать.

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

Добавление рабочих процессов GitHub Actions

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

Как мы уже упоминали ранее, мы потратили некоторое время на увеличение покрытия тестами, улучшение качества набора тестов, а затем добавили PHPStan. Но все это по-прежнему использовалось как локальные инструменты разработчика. Это означало, что во время проверки кода или перед ручным запуском развертывания в продакшн нам нужно было загрузить последний код и запустить тесты и PHPStan локально. Если они проходили успешно, мы могли продолжить проверку или развертывание. Но, как вы можете себе представить, это было «узким местом».

Поэтому мы автоматизировали этот процесс, создав несколько новых рабочих процессов GitHub Actions, которые:

  • Запускают набор тестов при каждом pull request.
  • Запускают PHPStan при каждом pull request.
  • Проверяют наши зависимости Composer при каждом pull request.
  • Запускают набор тестов при каждом push в основную ветку, а затем развертывают код, если тесты пройдены.

Теперь, когда мы открываем pull request, тесты и PHPStan запускаются автоматически. Поскольку они выполняются относительно быстро, мы получаем обратную связь в течение нескольких минут. Если что-то из этого не проходит, мы можем вернуться и исправить проблемы, прежде чем кто-то начнет проверку кода. Это ускорило процесс проверки, предотвратив просмотр сломанного кода, который в любом случае пришлось бы исправлять.

У нас также есть рабочий процесс, который проверяет наши зависимости Composer, чтобы убедиться, что мы не используем заброшенные пакеты или пакеты с известными уязвимостями безопасности. Этот рабочий процесс запускается при каждом pull request, и если обнаруживаются какие-либо проблемы, мы можем устранить их до слияния кода. Это предотвращает осознанную поставку кода с уязвимостями безопасности.

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

Результаты

Как я упоминал в начале статьи, нашими целями были ускорение выпуска функций, повышение уверенности и снижение риска появления ошибок.

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

Более быстрый выпуск с большей уверенностью

Устранив «узкие места» в нашем рабочем процессе разработки, мы смогли выпускать функции и исправления ошибок гораздо быстрее.

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

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

Обновления PHP и зависимостей стали проще

Еще одно большое преимущество наличия этих процессов заключается в том, что они значительно упростили обновление PHP, Laravel и других зависимостей.

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

Это также значительно упростило процесс обновления Laravel, потому что мы можем быть уверены, что наш код совместим с новой версией. Мы можем запустить тесты и статический анализ, чтобы доказать, что все работает как ожидается.

Что дальше?

Хотя мы внесли значительные улучшения в наш рабочий процесс разработки, мы можем сделать еще больше. Мы постоянно пересматриваем наш рабочий процесс и определяем области для улучшения.

Некоторые вещи, которые мы, возможно, изучим в будущем:

  • Добавление браузерных тестов (используя возможности, подобные новым функциям браузерного тестирования в Pest 4), чтобы получить больше уверенности в том, что наше приложение работает как ожидается с точки зрения пользователя.
  • Добавление мутационного тестирования с использованием Infection, чтобы помочь нам еще больше улучшить качество нашего набора тестов.
  • Использование Rector для автоматического рефакторинга и обновления нашей кодовой базы.

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

Фриланс-веб-разработчик

Эш Аллен пишет контент для Fathom Analytics.

← Все статьи
Dev48

© 2026 · All rights reserved.