Почему системные аналитики и QA инженеры должны требовать от разработчиков семантическое версионирование
Работая в разработке ПО в течение последних 15 лет, я постоянно вижу, как команды натыкаются на одну и ту же проблему – невозможность точно сказать, как работает конкретная версия системы, включая текущую – невозможность получить полное ТЗ. В зависимости от выбранной методологии разработки, обычно можно увидеть два варианта хранения требований:
- ТЗ на изначальную версию + частное техническое задание (diff) на каждое последующее изменение – стандартный подход для waterfall.
- Отдельные куски требований и алгоритмов для каждого story — стандартный подход для Agile методологий.
Оба варианта не позволяют быстро и без дополнительных трудозатрат получить исчерпывающую информацию о требованиях, которые реализовывались в системе той или иной версии. В лучшем случае, для этого надо потратить время чтобы проследить изменения требований в части той или иной функциональности от изначальных требований до интересующего момента, обычно же все надеются на бывалых аналитиков или разработчиков, знающих систему.
Для чего нужно знать требования к архивным версиям системы
1. Расследования по обращениям клиентов о некорректном поведении систем в прошлом.
2. Ответы на запросы аудиторов в отношении ведения бизнеса в прошлом.
3. Логика поведения системы в прошлом, привела к проблемам в настоящем и для устранения проблем, необходимо понять как именно и почему система работала именно так.
Наличие версионированных требований и их фиксация их изменений позволяет:
1. Требования помогут определить кто является причиной того или иного поведения системы – заказчик, который выдвинул и согласовал соответствующие требования или кто-то со стороны разработки, кто либо ошибся при реализации требований, либо намеренно изменил поведение системы – что особенно важно в случаях, когда разработкой занимается подрядная организация.
2. Определить являлось ли расследуемое поведение ожидаемым с точки зрения заказчика или ошибочным. Если поведение системы соответствовало требованиям:
3. Требования помогут либо напрямую ответить на вопрос “почему система работала именно так”, либо поможет найти источник требований и продолжить изыскания, а их отсутствие замкнет изыскания на том, кто писал код
4. Требования помогут определить в какой момент поведение системы изменилось и каким стало.
Со временем люди могут уходить, состав команды меняться или просто детали функциональности, которую давно никто не трогал могу забываться. В итоге компании получают системы, которые целиком или какие-то конкретные функциональности которых «нельзя трогать», их никто не хочет поддерживать, потому что «никто не знает, как оно работает и/или почему оно так работает».
С подходом фиксировать требования в спецификациях на изменения в системе все понятно, но какая альтернатива?
На мой взгляд, гораздо более правильным подходом является ведение единой централизованной модели требований и генерация ТЗ на конкретную версию системы из нее.
Обычно говоря о ведении централизованной модели требований, озвучивают другие возникающие при этом проблемы, такие как:
Увеличение сложности разработки и ведения модели
Увеличение трудозатрат аналитика на написание ТЗ
Увеличение time-to-market
Сложность версионирования модели требований
Решить все эти проблемы, призван разработанный и описанный мной подход к системному анализу, в том числе он отвечает на вопросы «Как организовать процесс автоматической генерации ТЗ?», «Как увидеть разницу в требованиях между моделями разных версий?» и «Как визуально отобразить разницу в ТЗ на разные версии системы?», в этой же статье я хотел бы подробнее остановиться на проблеме «Сложность версионирования ТЗ» и рассмотреть не то как версионировать с точки зрения механики, а то какой подход к версионированию, на мой взгляд, является оптимальным.
Семантическое версионирование
Очень важно договориться, чтобы и аналитики и программисты (а на самом деле и тест аналитики для своей тестовой модели) использовали единый подход к версионированию. На мой взгляд, подход этот давно известен, хорошо задокументирован и имплементирован во множество DevOpsинструментов, инструментов сборки и управления – семантическое версионирование.
Конечно же, если мы будем погружаться в процессы сборки и автоматического деплоя приложений, у нас будет возникать множество вопросов и найдется огромное количество копий, которые необходимо сломать, к счастью, в этой статье мы обсуждаем версионирование требований и подход к выравниванию версий требований с версией кодовой базы, поэтому для нас важно, по сути, определить взаимоотношение элементов версии и ввести буквально пару правил отличных от манифеста SemVer:
Любое изменение требований, реализация которого возможна с сохранением обратной совместимости, должно приводить к увеличению Minor элемента версии
- Исправление ошибок в требованиях, не являются их изменением.
- Если сохранить обратную совместимость при реализации новых или изменившихся требований невозможно, должен инкрементироваться Major элемент версии.
- Если требования не меняются, ни Major, ни Minor элементы версии изменяться НЕ должны.
Таким образом мы обеспечим простое соответствие:
Версия ТЗ Major. Minor распространяется на все версии Major. Minor. patch. build исходного кода.
Что делать если обнаружился дефект в требованиях?
На самом деле ответ на этот вопрос дан выше, в описанных правилах: Исправление ошибок в требованиях, не являются их изменением.
Очень важно зафиксировать, что изменять требования может только заказчик изменений.
Может ли заказчиком изменений быть команда разработки? Конечно! Команда может добавлять, например, требования к логированию, которые, несомненно, приведут к инкрементированию версии. Важно понимать, что любые изменения, не приводящие к изменению ожидаемого поведения приложения, например, рефакторинг кода, исправление дефектов в коде или в требованиях, не должны отражаться на Major и Minor версии.
Что делать если хотим сделать рефакторинг кода?
Этот вопрос часто порождает сложности и их причины понятны, зачастую рефакторинг приводит к необходимости не просто изменить версию, но и вообще переехать в отдельный репозиторий для хранения кода, и тут возникает вопрос «Как же нам не менять Major. Minor версии, если у нас сменился почти весь код?» и ответа тут может два, выбирать вам:
1. “А вот так и не менять! ” — договариваетесь, что после вывода в продуктив новой версии вы блокируете старый репозиторий его для изменений, при этом в продуктив выводите, увеличив Minor версии. Звучит парадоксально? Возможно, но план надежен как швейцарские часы!
- Начните версионирование с самого начала. Да так тоже можно, но вам придется переименовать приложение, чтобы не возникало путаницы и, возможно, какое-то время указывать две версии (1.0.1.14 New name (4.15 Old name). Ну и для удобства ТЗ проверсионировать также «с самого начала», как раз поменяв в нем название приложения и указав, что после такой- то версии приложение переименовано.
В этой статье я, конечно же, не могу раскрыть абсолютно все аспекты процессов разработки требований и кода, а также их версионирования, но применив этот подход вы увидите, как просто решаются существующие проблемы.
Со своей стороны, я все же планирую в одной или даже нескольких статьях показать,
как этот подход к сквозному версионированию требований-кода-тестов распространять на процессы управления задачами и составом версии (scope) в Jira, как его распространить на учет дефектов в версиях, как учитывать перенос дефектов между версиями, как отображать исключение функциональности из версии и т. п.
Stay tuned!