Статьи

TDD для команд

Я сильно подозреваю, что 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; Достаточно ли их для решения проблемы? Как пары могут беспрепятственно проводить рефакторинг, если в команде нет единого мнения относительно того, что является «хорошим» и «последовательным»?

Что делает ваша команда, чтобы сбалансировать потребности «достаточно дизайна» и «слишком много дизайна заранее»?