Прежде всего, я инженер-программист Eiffel, поэтому могу рассказать об этом на собственном опыте.
Предпосылка TDD vs DbC неверна
Эти две технологии не противоречат друг другу, а дополняют друг друга. Дополнение связано с размещением утверждений и целью.
Цель TDD включает как компоненты, так и область применения. Основными компонентами TDD являются логические утверждения и выполнение функции объекта (например, метода). Шаги просты:
- Создайте объект.
- Выполните некоторый код в функции.
- Сделайте утверждения о состоянии данных на объекте.
Утверждения, которые терпят неудачу, не проходят проверку. Цель - пройти все утверждения.
Как и TDD, контракты на разработку по контракту имеют цель, объем и компоненты. Хотя TDD ограничен временем модульного тестирования, контракты могут действовать в течение всего SDLC (жизненного цикла разработки программного обеспечения)! В рамках TDD выполнение методов (функций) объекта будет выполнять контракты. В настройке Eiffel Studio Auto-test (TDD) создается объект, выполняется вызов (точно так же, как TDD в других языках), но на этом сходство заканчивается.
В Eiffel Studio с автотестом и в коде Eiffel с контрактами цель несколько меняется. Мы хотим проверить отношения между клиентом и поставщиком. Наш код TDD притворяется клиентом нашего метода поставщика для своего объекта. Мы создаем наши объекты и вызываем методы, основанные на этой цели, а не просто на упрощенном «тестировании методов в стиле TDD». Поскольку вызовы наших методов (функций) имеют контракты, эти контракты будут выполняться как часть нашего TDD-кода в автоматическом тестировании. Поскольку это правда, утверждения (тесты) контракта, которые мы помещаем в наш код, НЕ должны появляться в нашем тестовом коде TDD. Наша задача (как программиста) просто обеспечить: A) код + контракты выполняются по всем N-путям, и B) код + контракты выполняются с использованием всех разумных типов данных и диапазонов.
Возможно, есть еще что написать об отношениях дополнения TDD-DbC, но я не буду с вами хамить по этому поводу. Достаточно сказать, что TDD и DbC НЕ расходятся с другими - далеко не во всех отношениях!
Сила контрактов DbC за пределами возможностей TDD
Теперь мы можем обратить наше внимание на силу контрактов Design-by-Contract за пределами возможностей TDD!
Контракты живут в коде. Они не внешние по отношению к нему, а внутренние. Самый важный момент (помимо договорных отношений между клиентом и поставщиком) в контрактах - это то, что компилятор спроектирован так, чтобы знать о них! Они НЕ являются неотъемлемым дополнением к Эйфелевой башне! Таким образом, они участвуют во всех аспектах наследования (как в традиционном вертикальном наследовании, так и в боковых или горизонтальных дженериках). Более того, они достигают места, недоступного для TDD - внутри метода (функции).
Хотя TDD может с некоторой легкостью имитировать предварительные и постусловия, TDD не может проникнуть внутрь кода и выполнить контракты, инвариантные к циклам, а также не может выполнять периодические выборочные проверки контрактов по блоку кода во время его выполнения. Это мощная логическая и качественная парадигма и реальность того, как работает дизайн по контракту.
Более того, TDD не может создавать инварианты классов, кроме самых слабых способов. Я изо всех сил старался получить свой код автотеста (который на самом деле является просто версией прикладного TDD от Eiffel Studios) для имитации инвариантного класса. Это невозможно. Чтобы понять, почему вам нужно знать все детали того, как работают инварианты классов Эйфеля. Итак, на данный момент вам просто придется либо поверить мне на слово (или нет), что TDD неспособен к этой задаче, с которой DbC справляется так легко, хорошо и элегантно!
Возможности DbC не ограничиваются приведенными выше понятиями.
Выше мы отметили, что TDD живет во время модульного тестирования. Контракты, поскольку они применяются в коде под наблюдением и контролем компилятора, применяются везде, где код может быть выполнен:
Workbench: вы, как программист, используете код, чтобы увидеть, как он работает (например, до TDD-времени или в сочетании с TDD-временем).
Модульное тестирование: ваше непрерывное интеграционное тестирование, модульное тестирование, TDD и т. Д.
Альфа-тест: ваши первые тестовые пользователи будут спотыкаться о контрактах при запуске исполняемого файла.
Бета-тест: более широкая аудитория пользователей также споткнется о контрактах.
Производство: окончательный исполняемый файл (или производственная система) может подвергаться непрерывному тестированию посредством контрактов (TDD не может).
В каждой из описанных выше ситуаций вы обнаружите, что у вас есть контроль над тем, какие контракты выполняются и из каких источников! Вы можете выборочно и точно включать и выключать различные формы контрактов и с исключительной точностью контролировать, где и когда они применяются компилятором!
И если всего этого было недостаточно, контракты (по замыслу) могут делать то, что не может сделать ни одно утверждение TDD: сообщает вам, где в стеке вызовов и какие отношения клиент-поставщик разорваны и почему em > (что тоже сразу подсказывает, как это исправить). Почему это правда?
Утверждения TDD предназначены для того, чтобы сообщать вам о результатах выполнения кода постфактум. Утверждение TDD может видеть только текущее состояние исследуемого метода. Утверждения TDD не могут сказать вам, какой именно вызов завершился неудачно и почему! Видите ли, ваш первоначальный вызов TDD какого-либо метода вызовет этот метод. Часто этот метод вызывает другой, и еще один, и еще один - иногда, когда стек вызовов поднимается и опускается и то и дело, происходит сбой: что-то записывает данные неправильно, не записывает их вообще или записывает это когда это не должно.
TDD - это как полиция, появляющаяся на месте преступления после того, как убийство уже произошло. Все, что у них осталось, - это улики судебно-медицинской экспертизы, которые, как они надеются, приведут их к подозреваемому и обвинительному приговору. Но что, если бы мы могли присутствовать при совершении преступления? В этом разница между размещением утверждений TDD и утверждений контракта. Контракты предназначены для выявления совершаемого преступления, и они указывают прямо на преступника, совершающего преступление!
Резюме
Подведем итоги.
TDD не расходится с DbC.
Это дополняющий и кооперативный набор технологий, но с разными функциями и целями, а также инструменты для работы с ними.
Контракт расширяется и расскажет больше о вашем коде, когда он сломается.
TDD - это одна из форм катализатора исполнения контрактов.
В конце концов: я хочу и то, и другое! Прочитав все это (если вы выжили), надеюсь, вы тоже.
person
Larry
schedule
23.02.2015