CTO Vetmanager, PHP Developer, Ironman 70.3

TDD плюсы и минусы

С коллегами для общего развития сейчас решаем интересные задачки. В том числе и для усвоения TDD навыка.

Задачки я опубликовал, если кому-то интересно может тоже поиграться - php-puzzles.

В процессе возник интересный разговор про безоговорочность TDD подхода.

Да, TDD подход имеет свои плюсы и минусы. Лично я против 100%го TDD. Тесты нужно писать тогда, когда их дорого не писать. Вот хороший принцип.

Аругмент:

TDD хороший подход для определенных задач

Возражение:

Я не почувствовал особой разницы написав тесты до кода. Я все равно использовал var_dump.

Аргумент:

test first помогает лучше понять тот код который нужно написать отталкиваясь от результата. При написании кода все равно могут потребоваться var_dump или xdebug, конечно тесты не спасают от этого.

Тесты нужны для кода, который живет и который нужно менять. Вардамп с кода убирается и при каждом рефакторинге нужно как-то код проверять. Даже небольшой рефакторинг потребует тыкать интерфейс и писать вардампы заново.

Возражение:

Какая разница в таком случае когда писать тест, до или после?

Аргумент:

(Если не учитывать плюс того что тест в начале помогает продумать композицию)

Если не подумать про тесты, то тестов и не появится, мы то научены уже :)

Программист без test first пишет:

case 'get_divisible_by_three_range':
   $min = request('min');
   $max = request('max'); 
   $res = [];
    for ($i = $max; $i >= $min; $i--)   {
        if (!($i % 3)) {
            $res[] = $i;
        }
    }
    json_response($res); // ну там на сайт как-то вывести

Пример из одного локального проекта, можно считать это методом контроллера для понимания сути

Что тут уже тестировать? Только плакать, что тесты писать тяжело и больно. А мог бы быть вот такой код покрытый ассертами, который нестрашно рефакторить.

case 'get_divisible_by_three_range':
    json_response(
        divisible_by_three(
            request('max'),
            request('min')
        )
    ); // ну там на сайт как-то вывести

Я тоже против 100% TDD. Есть ситуации когда TDD стоит дешево, а помогает очень сильно, нужно научиться их видеть. Тесты нужно писать тогда, когда их дорого не писать.

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

Последнее вспоминается когда я под phprector рефакторил я написал несколько smoke тестов, потому что бекенд отдавал 500ю ошибку и это было в интерфейсе банально дольше после каждой правки проверять.

Вывод: Так что это просто навык которым нужно уметь пользоваться, он test first сам по себе не лучше чем test after.