Skip to content

contract-tests

Композиция корректности. Как собрать рабочую систему из сервисов с подтверждённой спецификацией

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

— Niklaus Wirth, Systematic Programming

Это финальная статья серии про корректность программ. В предыдущих мы по кирпичу собирали модуль, сервис и спецификацию:

Сервис в результате этой дисциплины имеет спецификацию, подтверждённую тестами в изоляции. Юнит-тесты по формуле «1 + ветки антецедента» подтверждают, что каждый модуль ведёт себя по своему контракту. Компонентные сценарии в Gherkin через Docker Compose подтверждают, что сервис как чёрный ящик ведёт себя по OpenAPI/AsyncAPI и по карте режимов отказа в README.

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

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

И вот здесь индустрия ставит поверх всей пирамиды ещё один этаж: интеграционные тесты, e2e на Playwright, системные стенды, регрессионные прогоны на стейджинге. Тысячи сценариев. Часы прогонов. Десятки человеко-месяцев на поддержку.

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

Эксперимент с ИИ-ассистентом: бег от Pact в сторону валидации AsyncAPI 3.0 спецификаций

ai-contract-tests-experiment.png

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

1973 Никлаус Вирт. Systematic Programming. An introduction.

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

Я с большим энтузиазмом смотрю на прогресс ИИ-ассистентов, провожу эксперименты с передовыми их проявлениями(по крайней мере известными и доступными мне), такими как Claude терминал, Cursor.

Один из наиболее влиятельных сторонников структурного программирования профессор Э. В. Дейкстра написал

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

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

В данной работе я кратко опишу процесс по созданию утилиты на Golang с ИИ-агентом в клод-терминале для валидации контрактов сервисов в ландшафте информационных систем, где у каждого сервиса есть спецификация Async API 3.0.

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