Статьи

Начало работы с тестовой разработкой — с чего начать?

Если вы когда-либо создавали программное обеспечение, используя настоящий подход, основанный на тестировании (TDD), помните ли вы первую проблему, которую вам пришлось преодолеть? Было ли это возможно:

С чего начать? Какой первый тест?

Это очень распространенная проблема — просто не зная, с чего начать.

Несколько лет назад я тренировался у клиента в Сент-Луисе, штат Миссури. Я присутствовал на собрании местной группы XP, и это была сессия, посвященная именно этой теме. Его возглавлял Брайан Баттон , и он начал с того, что рассказал о пустом взгляде, который некоторые разработчики встречают, пытаясь понять, с чего начать. Его упражнение состояло в том, чтобы мы спарились и начали строить простую игру в блэкджек, используя только тестовый подход.

Я работал в паре с Брайаном Нелем , который только что работал в Игорной комиссии штата Миссури. Я подумал, что это даст нам преимущество над другими парами. Нашей платформой был выбор C #, хотя примеры, которые я покажу здесь, приведены на Java.

После очень краткого обсуждения правил блэкджека мы немного поговорили о том, с чего мы хотели начать. Ну, нам нужна какая-то игра, так что мы должны начать там? Игра должна быть в состоянии сравнить руки карт, так что, возможно, это место, чтобы начать. Но как насчет игроков? Нам понадобится Дилер и Игрок, и у каждого будет Рука.

Примерно через 2-3 минуты мы решили сосредоточиться на чем-то более фундаментальном — карте. Карта должна иметь ценность, и я считаю, что мы даже начали с концепции костюма. Итак, наш первый тест был примерно таким:

@Test
public void eightOfHeartsIsGreaterThanThreeOfSpades() {
   Card card1 = new Card(8);
   Card card2 = new Card(3);

   assertTrue(card1.getValue() > card2.getValue());
}

Этот тест заставил несколько вещей. Во-первых, компилятор сжал, что не было такого понятия, как класс Card. Таким образом, мы должны были создать это:

public class Card {
}

Это устранило первые ошибки, но теперь нам сказали, что getValueв Card нет метода. Это был наш следующий шаг:

public int getValue() {
   return 0;
}

Ошибки компилятора исчезли, и мы смогли запустить тест. Естественно, тест не удался, поскольку getValueвернул только ноль. Это здорово … у нас теперь был наш первый провальный тест!

Я знаю, о чем ты думаешь … Вау! ПОДОЖДИ МИНУТУ! Вы просто жестко закодировали возвращаемое значение, чтобы угодить компилятору!

Да. Да. И это нормально! TDD — это выражение желаемого поведения с помощью тестов и внесение крошечных изменений, позволяющих пройти тесты. В статически типизированном языке, таком как Java, можно считать ошибки компилятора формой теста.

Но теперь нам нужно было пройти тест. Итак, мы изменили код в классе Card на что-то вроде этого:

   private int value;

   public Card(value) {
      this.value = value;
   }

   public int getValue() {
      return this.value;
   }

Зеленый бар !! Наш тест пройден!

Мы добавили еще пару таких тестов и поняли, что на самом деле ничего не сделали с концепцией костюма (червы, бубны, трефы, пики). Мы решили провести рефакторинг наших тестов, чтобы исключить упоминание костюма, потому что в тот момент он нам просто не понадобился.

@Test
public void eightIsGreaterThanThree() {
   Card card1 = new Card(8);
   Card card2 = new Card(3);

   assertTrue(card1.getValue() > card2.getValue());
}

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

Я считаю, что это было, когда у нас не хватило времени, так как был только час для сеанса кодирования. Цель состояла не в том, чтобы завершить игру в Блэкджек, а в том, чтобы начать с чего-то начинать.
Во время опроса было интересно отметить, что из 6 пар только две стартовали в одном месте. Не менее интересным было то, что не было неправильного места для начала!

Это был смысл упражнения. Если вы застряли на том, с чего начать, просто начните где-нибудьгде угодно !

Через несколько лет я посетилAgile Games 2011 в Бостоне . Адам Срока провел сеанс об использовании TDD для создания игры в Техасский Холдем . Когда мы начинали, я помню, несколько человек пытались спроектировать всю «систему» ​​и составили длинный список того, что нужно было сделать. Там было больше колебания над тем, с чего начать.

Я сел с Моссом Коллумом , другим разработчиком, и просто спросил: «С чего вы хотите начать?» Он вручил мне клавиатуру, и я напечатал:

@Test
public void eightOfHeartsIsGreaterThanThreeOfSpades() {
}

Вывод

С тех пор я пару раз использовал TDD для карточных игр. Сегодня я бы начал с игры или с руки, а не с карты. Опять же, это не потому, что начинать с карты было неправильно, но я мог видеть дальнейшее продвижение за то же время, используя другую отправную точку. А может и нет — наверное, это зависит от отдельных разработчиков.

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