TDD (Test-Driven Development) – трън в дупето или застраховка „Живот“?
На времето мразех да правя тестове. Много. Не виждах голям смисъл в цялата тая работа. Какво да му тествам, по кода си личи, че работи. Какво може да се прецака в 30 редова функция? Защо да губя време в рефрешване, попълване на форми и разиграване на различни кейсове. Пълна идиотщина.
За съжаление обаче в реалния живот тестовете са необходими. Когато имах по-малко проекти, по които работих всичко беше песен. Пишеш, правиш, струваш, ако изкочи нещо – то ше се чуе и съответно ще се поправи. Чудна работа. Но с времето проектите започват да се трупат. Сайтовете за които трябва да трепериш стават над 100. Във всеки един момент нещо може да се счупи и отговорността ще падне върху твоите плещи. Ами ако всичко се счупи точно в един ден? Какво ще правя? Как изобщо мога да имам застраховка, че всичко работи както трябва? Ами какво ако съм поел още 10 нови проекта, чиито краен срок е съвсем скоро. И ако изкочат да речем 10 бъга по стари 5 проекта, как изобщо ще спазя крайния срок на нещо? Застраховката за цялата тази доста прецакана работа се нарича автоматизирани тестове.
Като всяка една застраховка и тази има условия и разбира се не дава сто процена гаранция за нищо. Но по-добре някаква застраховка от колкото никаква. Нали така? Разбира се, автоматизираните тестове имат цена, която трябва да заплатите. Има три основни пътеки, по които можете да поемете.
Вариант 1
Пишете целия код на проекта, след което да отделите време да напишете тестове. Доста кофти вариант, все пак по-добър от варианта в който изобщо не пишете тестове. Как го виждате… приложението е готово, очевидно работи, а вие тепърва трябва да пишете тестове. Защо, нали си работи.. Доста често мотивацията ще бъде занижена и надали ще ви се занимава. Така или ще свършите без тестове или със тестове, които по-скоро се пишат да минават, без да се хванат всички възможни варианти (винаги така става).
Вариант 2
Пишете малко код, след което пишете малко тестове. Звучи разумно и определено е по-добре от вариант 1. Не се изисква толкова голяма дисциплина за да го постигнете. Хубавото му е, че един вид може да разнообразвяте писането на функционалност с тестове. В днешно време този вариант е доста разпространен. Правите прототип, клиента одобравя, ако одобри, пишете тестове и продължавате напред. Яко, а? Якото тепърва предстои…
Вариант 3
TDD! Пишете тест, естествено той фейлва щото нямате код към него, правите така че да мине, след което го подобравяте и пак на ново. Хитро, а? Обаче както сами се сещате е необходима огромна доза дисциплина за да го постигнете. Няма как да минете тънко тънко и да пропуснете тест. Съответно времето в което правите проекта ще се увеличи. Прототипите ще идват по-бавно, по-работещи, но все пак ще ви отнемат повече време. Случвало ми се е да пиша 300 реда тестове за 20 реда функция. Има и по-кофти случаи. Но цялата тази работ има големи плюсове. Толкова големи, че си струва да го правите. Да знаете по-хубаво нещо от спокойния сън няма
Най-общо казано TDD ще ви осигури доста по-голяма увереност, че това, което правите наистина работи. Ще ви подсигури, че няма да се счупи на случаен принцип след 2 дни, тъй като е изкочило извънредно обстоятелство. И най-важното, поне за мен, когато ви се налага да добавяте/махате фийчъри, да правите рефакторинг на код, знаете кое с какво взаимодейства и какво се чупи, без да има нужда наистина да го помните. Честно казано, не виждам как изобщо съм добавял фийчъри без тестове. Вижда ми се много извънземна работа. Когато ми се налага да го правя, първо правя заклинания да не фейлне всичко. И след всеки фийчър – няколко часа стабилно разцъкване за да видим дали случайно нещо не се е скапало. Окей, а на по-стари проекти, в които одавна сте забравили какво се случва?
Стурва си. Трудно е, отнема време, тегаво е, но си струва. Ако изкочи бъг, добавяте тест и поправяте кода. И сте уверени, че е отстранен. + в повечето случаи правите по-чиста архитектура от колкото сте щели да направите ако не сте писали първо тестовете.
Вариант 4 (бонус)
Съществува и доста по-храдкор вариант. За пример Lithium е писан по подобен начин. Вариантът е точно обратния на вариант 1. Първо пишете всички необходими тестове. Чак след това пишете каквато и да е било функционалност. Така де факто правите първо дизайн на цялото приложение. За да започнете да го практикувате се изисква поне известен опит в tdd, инак ще ви е доста трудничко. Хубавото му е, че лесно може да откриете рано архитектурни проблеми, а и ще създадете доста по-чисто api. Този вариант е доста по-труден за постигане в реални условия, но все пак може да се окаже вашето тайно оръжие.
Та така.. старомодното тестване, което изисква браузър и часове рефрешване е в миналото от доста време. Ако все още го практикувате, замислете се дали да не дойдете в 21 век. Колкото и тегава да ви се вижда цялта тая работа, опитайте и няма да съжалявате. Ресурси по темата – колкото искате, така че всичко е във вашите ръце.

Вариант две ми допада най-много. Прототип, след което да бъде тестван и съответно направен цял скрипт.
Амин!
Хубава статия с много валидни аргументи. Реалността понякога обаче е друга. Какво правим например с някой легаси сайт, който е писан миналия век и има точно 5 php файла, омешени с php, маркъп, джаваскрипт, пък и css.. (omfgwtfplscutmyhandz). Как да го тестваш?
Другия момент, който ти застъпваш в поста е времетето, което никога не ни стига. Ако проекта не е толкова сложен/важен/високоплатен, би ли писал тестове за него или просто би разчитал на опита си като девелопър?
Тестовете са страхотни и както вече каза плюсовете надминават минусите, но мисля, че не са подходящи за всички ситуации, особено когато става дума за легаси приложения.
Поздрави!
Прав си, но мисля, че Веско има предвид именно работата по проекти от нулата. В такъв случай и според мен тестовете са неизбежни.
Веско, направо не ти познах блога, много добра промяна си направил, успех!
@Антони Относно легаси сайтовете: ако имаме потребтност да ги поддържаме по някакъв начин, то би било най-логично да ги пренапишем за да станат малко по-малко легаси. Mark Story има хубава статия по въпроса http://phpadvent.org/2010/legacy-jungle-by-mark-story препоръчвам ти я. Като изобщо целия рефакторинг би започнал с писане на тестове, както и който и да е било друг рефакторинг на код без юнит тестове.
Ако проекта не е толкова сложен/важен/високоплатен бих се постарал да направя 100% code coverage за да не го мисля после и наистина да знам, че съм приключил с него, защото както всички знаем бъговете са скъпо струващи удоволствия
Аз съм от тези с първия вариант правя тествам, правя тествам на ръка. Какво ще рече писане на тестове. Някакви симулиращи работата на скрипта по всевъзможен начин..??
Над сто проекта ? това се нарича успял програмист.
Много полезна информация, продължавай в същия дух! Благодаря!
Имаш мнение? Сподели го: