Представьте себе такую ситуацию: вы тестируете программу, использующую «сногсшибательные алгоритмы искусственного интеллекта» для нахождения и исправления проблем с конкурентным доступом. Вы запускаете программу и обнаруживаете, что на заставке слово «интеллект» написано с ошибкой. Несколько дурное предзнаменование, но ведь это лишь опечатка, верно? Затем выясняется, что экран настройки предлагает флажки (checkboxes) вместо переключателей (radiobuttons), а некоторые сочетания клавиш не работают. Все это мелочи, но по мере их накопления вы начинаете задумываться, что за люди создавали программу. Если они неспособны справиться с простыми вещами, каковы шансы, что их искусственный интеллект действительно сумеет найти и исправить такие замысловатые вещи, как проблемы конкурентного доступа?
Возможно, эти гении настолько погрузились в задачи разработки искусственного интеллекта, что не обратили внимания на мелочевку, а «придирчивых тестировщиков» у них не было, так что вам приходится сталкиваться с этой самой мелочевкой. Однако в результате вы начинаете сомневаться в компетентности этих программистов.
Следовательно, как ни странно, тестировщики, полные решимости найти все мелкие недостатки вашего кода, в действительности — ваши друзья.
Один бинарный файл
Стив Фримен
Мне приходилось встречать проекты, где при сборке переписывалась часть кода, чтобы для каждой среды исполнения генерировался собственный бинарный файл. Такой подход всегда излишне усложняет вещи и создает риск появления несовместимых версий при каждой установке. Как минимум при этом собирается несколько почти идентичных экземпляров программы, каждый из которых предназначен для установки в соответствующей ему среде. Возникает слишком много подвижных частей, а значит, больше возможностей для ошибки.
Однажды я работал в команде, где после каждого изменения свойства нужно было сохранять код и проводить полный цикл сборки, поэтому тестировщики простаивали всякий раз, как находилась малейшая неточность (я уже говорил, что к тому же проект собирался невероятно долго?). Работал я и в такой команде, где системные администраторы требовали полной пересборки программы при вводе ее в эксплуатацию (с помощью наших же сценариев сборки), так что невозможно было гарантировать, что в эксплуатацию попадала та версия, которая прошла тестирование. И так далее.
Правило простое: создавать единственный бинарный файл, который можно точно идентифицировать и провести через все этапы конвейера выпуска продукта. Все специфические особенности среды исполнения должны оставаться частью среды. Например, их можно хранить в контейнере с компонентами (component container), в заранее согласованном файле или в определенных папках.
Если во время сборки вашего проекта производятся манипуляции с кодом или настройки целевой среды хранятся в самом коде, значит, приложение было спроектировано недостаточно хорошо: ключевые функции приложения не отделены от функций, определяемых платформой. Или еще хуже: команда знает, как нужно поступить, но не считает внесение нужных изменений достаточно приоритетной задачей.
Бывают, конечно, исключения: иногда приходится делать сборку для нескольких вариантов целевой среды, в которых ограничения по ресурсам существенно разнятся. Однако это не относится к тем из нас (и таких большинство), кто создает приложения типа «отправить данные из базы данных на экран и обратно». Другой вариант — работа с плохо написанным унаследованным (legacy) кодом, в котором навести порядок сразу слишком тяжело. В таких случаях следует двигаться постепенно, но начинайте это движение как можно раньше.
И еще одно: храните информацию о среде выполнения в системе управления версиями, как и код. Нет ничего хуже, чем испортить конфигурацию среды и не иметь возможности узнать, какие в нее были внесены изменения. Настройки среды должны храниться в отдельном репозитории, так как они меняются с другой скоростью и по другим причинам, чем код. Некоторые команды используют для этого распределенные системы управления версиями (например, bazaar и git), поскольку в них проще сохранять в репозиторий изменения, сделанные в производственной (production) среде — а они неизбежно случаются.
Правду скажет только код
Петер Зоммерлад
В конечном счете семантика программы определяется работающим кодом. Если он есть у вас только в виде бинарного файла, его будет непросто прочесть! Однако исходный код, как правило, доступен, если это ваша собственная программа, типичная коммерческая разработка, проект с открытым исходным кодом или программа на динамически интерпретируемом языке. При чтении исходного кода смысл программы должен быть очевиден. Можно с уверенностью узнать, что делает программа, только глядя в исходный код. Даже самое точное описание технических требований не скажет всей правды: в нем содержится не детальное описание того, что фактически делает программа, а общие пожелания составителя требований. Документ с архитектурой может содержать описание планируемой архитектуры, но в нем не будут описаны нужные детали реализации. Эти документы могут устареть в сравнении с текущей реализацией… или просто потеряться. Быть может, их даже и не писали. Возможно, единственное, что осталось, — это исходный код.