Прежде всего, я инженер-программист Eiffel, поэтому я могу говорить по этому вопросу из опыта .
Предпосылка TDD против DbC * 1007 * неверна
Две технологии не противоречат друг другу, а дополняют друг друга. Дополнение связано с размещением утверждений и целей.
Назначение 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 может достичь!
Контракты живут в коде. Они не внешние, а внутренние. Самая важная часть (помимо их основанных на контрактных отношениях между клиентом и поставщиком) контрактов заключается в том, что компилятор разработан, чтобы знать о них! Они НЕ являются дополнением к Eiffel! Таким образом, они участвуют в каждом аспекте наследования (как в традиционном вертикальном наследовании, так и в боковом или горизонтальном родовом типе). Более того, они достигают места, недоступного TDD, - внутри метода (функции).
Хотя TDD может имитировать предварительные условия и постусловия с некоторой легкостью, TDD не может достичь внутри кода и выполнять контракты, инвариантные к циклам, а также не может выполнять периодические выборочные проверки «чек» по блоку кода, поскольку выполняется. Это мощная логическая и качественная парадигма и реальность о том, как работает дизайн по контракту.
Более того, TDD не может делать инварианты классов, но самым слабым образом. Я изо всех сил старался получить свой код Auto-test (который на самом деле является просто версией прикладного TDD от Eiffel Studios), чтобы выполнить класс-инвариантную мимику. Это невозможно. Чтобы понять, почему вы должны знать все о том, как работают инварианты класса Eiffel. Итак, на данный момент вам просто придется поверить на слово (или нет), что TDD не способен выполнить эту задачу, что DbC справляется так легко, хорошо и элегантно!
Достижение DbC не заканчивается вышеуказанными понятиями
Мы отметили выше, что TDD живет во время юнит-теста. Контракты, поскольку они применяются в коде под наблюдением и контролем компилятора, применяются везде, где может быть выполнен код:
Workbench: вы, как программист, используете код, чтобы увидеть, как он работает (например, до времени TDD или в сочетании с временем TDD).
Юнит-тест: ваше непрерывное интеграционное тестирование, юнит-тестирование, TDD и т. Д.
Альфа-тест: ваши первоначальные тестовые пользователи будут отключаться по контрактам при запуске исполняемого файла
Бета-тест: более широкая аудитория пользователей также опередит контракты.
Производство: конечный исполняемый файл (или производственная система) может иметь непрерывное тестирование, применяемое по контрактам (TDD не может).
В каждой из вышеперечисленных ситуаций вы обнаружите, что контролируете, какие контракты выполняются и из каких источников! Вы можете выборочно и точно включать и выключать различные формы контрактов и управлять с предельной точностью, где и когда они применяются компилятором!
И если всего этого было недостаточно, контракты (по замыслу) могут сделать то, чего не может сделать ни одно утверждение TDD: скажет вам, где в стеке вызовов и какие отношения клиент-поставщик нарушены, и почему (что также сразу подсказывает, как это исправить). Почему это правда?
Утверждения TDD предназначены для того, чтобы рассказать вам о результатах выполнения кода (выполнения) после факта. Утверждение TDD может видеть только текущее состояние рассматриваемого метода. То, что TDD-утверждения не могут сделать с их позиции вне базы кода, это точно сказать вам, какой вызов не удался и почему! Видите ли, ваш первоначальный TDD-вызов какого-либо метода вызовет этот метод. Много раз этот метод будет вызывать другой, и другой, и другой - иногда, когда стек вызовов вращается вверх и вниз, туда и обратно, происходит сбой: что-то пишет данные неправильно, не записывает их вообще или пишет это когда не должно быть.
TDD напоминает полицию, которая появляется на месте преступления после того, как убийство уже произошло. Все, что они оставили, - это судебные улики, которые, как они надеются, приведут их к подозреваемому и осуждению. Но что, если бы мы могли быть там, когда совершалось преступление? В этом разница между размещением утверждений TDD и утверждений контракта. Есть контракты, чтобы поймать преступление в процессе, и они указывают прямо на преступника, когда он совершает преступление!
Резюме
Давайте подведем итоги.
TDD не расходится с DbC.
Это дополнение и совокупность технологий, но с различными функциями и целями, а также инструментами для работы с ними.
Достигните договор и узнайте больше о вашем коде, когда он сломается.
TDD является одной из форм катализатора для исполнения контрактов.
В конце дня: я хочу оба! Прочитав все это (если вы выжили), я надеюсь, что вы тоже.