Насколько я должен быть строг в том, чтобы «делать самое простое из возможных» во время выполнения TDD? - PullRequest
17 голосов
/ 10 июня 2010

Для TDD вы должны

  1. Создать тест, который не прошел
  2. Сделайте самое простое, что могло бы сработать, чтобы пройти тест
  3. Добавьте еще варианты теста и повторите
  4. Рефакторинг при появлении шаблона

При таком подходе вы предполагаете охватить все случаи (по крайней мере, мне это кажется), но мне интересно, слишком ли я строгий здесь и возможно ли «думать вперед» некоторые сценарии, а не просто открыть их.

Например, я обрабатываю файл, и если он не соответствует определенному формату, я должен выбросить InvalidFormatException

Итак, мой первый тест был:

@Test 
void testFormat(){
    // empty doesn't do anything nor throw anything
    processor.validate("empty.txt"); 
    try {
        processor.validate("invalid.txt");
        assert false: "Should have thrown InvalidFormatException";
    } catch( InvalidFormatException ife ) {
        assert "Invalid format".equals( ife.getMessage() );
    }
 }

Я запускаю его, и он терпит неудачу, потому что он не выдает исключение.

Итак, следующее, что приходит мне в голову: «Делай самое простое, что могло бы сработать» , поэтому я:

public void validate( String fileName ) throws InvalidFormatException {
    if(fileName.equals("invalid.txt") {
        throw new InvalidFormatException("Invalid format");
    }
}

Doh !! ( хотя реальный код немного сложнее, я обнаружил, что сам делаю что-то подобное несколько раз )

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

Q: Я слишком буквально воспринимаю "Делай самое простое ..." материал?

Ответы [ 7 ]

7 голосов
/ 10 июня 2010

Я думаю, что ваш подход в порядке, если вам это удобно. Вы не тратили время на написание глупого случая и на глупое решение его - вы написали серьезный тест на действительно желаемую функциональность и сделали его, как вы говорите, самым простым способом, который мог бы сработать. Сейчас - и в будущем, по мере того, как вы добавляете все больше и больше реальных функциональных возможностей - вы гарантируете, что ваш код будет иметь желаемое поведение для выдачи правильного исключения для одного конкретного плохо отформатированного файла. Далее следует сделать это поведение реальным - и вы можете управлять этим, написав больше тестов. Когда становится проще написать правильный код, чем подделывать его снова, тогда вы напишите правильный код. Эта оценка варьируется в зависимости от программистов - и, конечно, некоторые решат, что наступит время написания первого провального теста.

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

3 голосов
/ 13 июня 2010

Я тоже новичок TDD, борющийся с этим вопросом.В ходе исследования я нашел этот пост в блоге Роя Ошерова, который был первым и единственным конкретным и осязаемым определением «самой простой вещи, которая могла бы работать», которую я нашел (и даже Рой признал, что это было простоначало).

В двух словах Рой говорит:

Посмотрите на код, который вы только что написали в своем рабочем коде, и спросите себя следующее:

«Могу ли я реализоватьто же решение, что и .. »

  1. « .. Более жестко закодировано .. »
  2. « .. Ближе к началу метода, в котором я его написал.. «
  3. « .. Меньше отступов (как можно меньше «областей видимости», таких как ifs, loop, try-catch) .. »
  4. « .. короче (буквально меньше символов для записи) но все еще читаемо .. »

«… и все же пройти все тесты успешно? »

Если ответом на один из них является« да », то сделайте это и посмотритевсе тесты еще проходят.

3 голосов
/ 10 июня 2010

Конечно, ваша интерпретация правила слишком буквальна.Вероятно, это должно звучать как «Сделай простейшую потенциально полезную вещь ...»

Кроме того, я думаю, что при написании реализации вы должны забыть тело теста, которое вы пытаетесь выполнить,Вы должны помнить только название теста (который должен рассказать вам о том, что он тестирует).Таким образом, вы будете вынуждены написать достаточно общий код, чтобы быть полезным.

2 голосов
/ 21 марта 2013

Одна вещь, на которую следует обратить внимание будущим изучающим TDD - мантра TDD на самом деле не включает «Делай самое простое, что могло бы сработать».В TDD Book Кента Бека есть только 3 шага:

  1. Красный - Напишите небольшой тест, который не работает и, возможно, даже не компилируется вначале.
  2. Зеленый - сделать тест быстрым, совершив все грехи, необходимые в процессе.
  3. Рефакторинг. Устраните все дубликаты, созданные в результате простого запуска теста.

Хотя фраза «Делай самое простое ...» часто приписывается Уорду Каннингемуон на самом деле задал вопрос «Какая самая простая вещь, которая могла бы сработать?» , но этот вопрос позже был превращен в команду, которая, как считает Уорд, может сбить с толку, скорее помочь.

Редактировать: я не могу рекомендовать достаточно прочтение TDD Book Бека - это похоже на сеанс сопряжения с самим мастером, который дает вам его идеи и мысли о процессе разработки через тестирование

2 голосов
/ 10 июня 2010

Вы пропустили точку № 0 в вашем списке: знаете, что делать. Вы говорите, что обрабатываете файл для проверки. После того, как вы определили, что означает «проверка» (подсказка: сделайте это перед написанием любого кода), у вас может появиться лучшее представление о том, как: а) писать тесты, которые, в общем, тестируют спецификацию как реализованную, и б) писать простейшую вещь .

Если, например, валидация «должна быть XML», ваш тестовый пример - это просто какая-то не совместимая с XML строка, а ваша реализация использует библиотеку XML и (при необходимости) преобразует свои исключения в те, которые указаны для вашего » валидация ».

2 голосов
/ 10 июня 2010

много комментариев:

  • Если проверка "empty.txt" выдает исключение, вы его не поймаете.

  • Не повторяйся. У вас должна быть одна тестовая функция, которая решает, делает ли валидация исключение. Затем дважды вызовите эту функцию с двумя разными ожидаемыми результатами.

  • Я не вижу никаких признаков модульного тестирования. Может я скучаю по ним? Но просто использование assert не масштабируется для более крупных систем. Когда вы получаете результат проверки, у вас должен быть способ сообщить в среду тестирования, что данный тест с заданным именем прошел или не прошел.

  • Я встревожен идеей, что проверка имени файла (в отличие от содержимое ) представляет собой «проверку». На мой взгляд, это немного слишком просто.

Что касается вашего основного вопроса, я думаю, вы бы выиграли от более широкой идеи о том, что самое простое. Я также не фундаменталист TDDer, и я бы позволил вам «подумать заранее» немного бит. Это означает, что нужно думать о будущем во второй половине дня или завтра утром, а не думать о будущем на следующей неделе.

1 голос
/ 11 июня 2010

Подобно тому, как метод должен делать только одну вещь, один тест должен проверять только одну вещь (поведение).Чтобы рассмотреть приведенный пример, я бы написал два теста, например, test_no_exception_for_empty_file и test_exception_for_invalid_file.Вторым действительно может быть несколько тестов - по одному на недействительность.

Третий этап процесса TDD должен интерпретироваться как «добавить новый вариант теста», а не «добавить новый вариант теста».Действительно, модульный тест должен быть атомарным (тестировать только одну вещь) и, как правило, следует тройному шаблону А: Организовать - Действовать - Утвердить.И очень важно сначала убедиться, что тест не пройден, чтобы убедиться, что он действительно что-то тестирует.

Я бы также разделил ответственность за чтение файла и проверку его содержимого.Таким образом, тест может передать буфер в функцию validate (), и тестам не нужно читать файлы.Обычно модульные тесты не обращаются к файловой системе, потому что это замедляет их.

...