Я сильно подозреваю, что TDD для команд отличается от TDD для отдельных лиц.
В разработке программного обеспечения есть пословица о том, что:
«TDD — это метод проектирования , а не метод тестирования»
Я согласен. Но это не значит, что это единственная техника дизайна, которая нам нужна. И это также не означает, что все будут использовать его одинаково или получать с ним одинаковые результаты. Например, взгляните на подходы, используемые Себом Роузом , Роном Джеффрисом и Алистером Кокберном для решения ката Letter Diamond. (Нажмите на их имена, чтобы прочитать их сообщения в блоге, а затем вернитесь сюда, если у вас еще останется энергия.) Каждый из них решал один и тот же набор требований совершенно по-разному. Каждый использовал TDD, и все же их конструкции были совершенно разными.
На самом деле, когда я готовил этот пост, Джордж Динвидди тоже попытался , и Рон сделал вторую попытку . Итак, теперь у нас есть 5 различных подходов к дизайну одной игрушечной ката от 4 разработчиков в течение одного уик-энда. (И, вероятно, есть еще кое-что, о чем я не слышал.) Конечно, было бы странно, если бы все они создавали идентичные проекты. Мы все разные, и это определенно хорошо. Но я беспокоюсь, что это может вызвать проблемы у команд, занимающихся TDD.
Пару лет назад я помню, как делал ката для исполнения, в которой я работал в паре с Марком Киршштейном, чтобы заняться ката в супермаркете . Моя роль заключалась в том, чтобы писать тесты, а Марка — в том, чтобы заставить их пройти. В начале сессии я сделал смелое заявление о том, что смогу заставить Марка осуществить проверку так, как он никогда раньше не видел, с дизайном, который он не задумывал. Аудитория и Марк были настроены скептически. Они привыкли думать о проблеме как окаймленной тестами в первоначальной постановке задачи Дейва Томаса. И поэтому они ожидали, что первый тест будет примерно таким:
public class CheckoutTests { @Test public void oneA() { Checkout checkout = new Checkout(); checkout.scan("A"); assertEquals(30, checkout.total()); } }
Но на самом деле мой первый тест был такой:
public class CheckoutTests2 implements ScannerListener { int priceReported = 0; String productReported = null; @Test public void oneA() { Scanner scanner = new Scanner(this); scanner.scan(new SKU("A")); assertEquals(30, priceReported); assertEquals("A", productReported); } public void itemScanned(String product, int price) { productReported = product; priceReported = price; } }
(выражается с использованием шаблона SelfShunt, так как любой, кто посещал любой из моих учебных курсов, сразу узнает). К его удивлению, Марк постепенно привел к созданию реализации оформления заказа, основанной на уведомлениях и слушателях, без использования методов получения или установки.
[Дополнительная задача: внедрить ката в супермаркете без условий!]
Хотя это был (я надеюсь) отличный театр, во всем этом есть более глубокий смысл, когда речь идет о целых командах, работающих над нетривиальными проблемами: если команда должна производить программное обеспечение, которое демонстрирует внутреннюю согласованность и понятно всем его разработчикам затем, так или иначе, эти индивидуальные различия должны быть каким-то образом сданы или гомогенизированы. Каким-то образом команда должна создать дизайн — и стиль дизайна — с которым все согласны.
Имеет ли смысл команды для работы в виде изолированных пар, каждая из которых программирует свои конкретные задачи, независимо от того, как их проекты будут интегрироваться с проектами их товарищей по команде? Я вижу, что слишком много команд делают это; бросая сеансы проектирования на основе чтения книг и блогов TDD, в которых один человек или пара все обдумывали. Я вижу слишком много кодовых баз, в которых личный стиль является основной силой дизайна; где одна и та же концепция предметной области реализуется двумя или более радикально разными способами; где дублирование, таким образом, очень трудно обнаружить и еще труднее удалить.
Возможно, нам нужно больше опубликованных примеров командных TDD, показывающих методы для создания и совместного использования Just Enough Design Up FrontTM.
XP включает в себя ключевые практики Coding Standard и System Metaphor; Достаточно ли их для решения проблемы? Как пары могут беспрепятственно проводить рефакторинг, если в команде нет единого мнения относительно того, что является «хорошим» и «последовательным»?
Что делает ваша команда, чтобы сбалансировать потребности «достаточно дизайна» и «слишком много дизайна заранее»?