Разработка чрез тестове

от Уикипедия, свободната енциклопедия
Направо към: навигация, търсене

Разработка чрез тестове, (английски: Test-driven development, TDD) е метод за разработка на софтуер, при който се спазва следният работен цикъл: първо се пишат тестови варианти (test cases), които да покрият изискванията за новия код, а чак след това се пише кодът, който трябва да бъде написан така, че да покрива тези тестове. Кент Бек, който се счита за създател на този метод софтуерна разработка, заявява през 2003-та, че TDD цели един опростен дизайн.

Разработката чрез тестове се свързва с екстремното програмиране, започнато през 1999. Програмистите също прилагат концепцията за подобряване и отстраняване на грешки в код, създаден с по-стари похвати.

Съдържание

Изисквания [редактиране]

Разработката чрез тестове изисква от програмистите да създадат автоматизирани модулните тестове (unit tests), които да дефинират изискванията за кода преди писането на самия код. Тестовете съдържат твърдения, чиито стойности могат да бъдат истина (true) или лъжа (false). Успешното изпълнение на тестовете потвърждава за правилното поведение на софтуера след допълване на нов код. Често програмистите използват тестващи среди, като xUnit, за създаването и автоматичното изпълнение на редица от тестови сценарии.

Цикълът при Разработка чрез тестове [редактиране]

Графично представяне на работния цикъл

1. Добавяне на тест [редактиране]

При Разработка чрез тестове всяка нова функционалност започва с писане на тестове. За да се напише един такъв тест, разработчикът трябва да има ясна представа от спецификацията и изискванията за новата функционалност.

2. Изпълнение на всички тестове с неуспех [редактиране]

Новите тестове не трябва да минават успешно, понеже все още не е реализирана функционалността, която те трябва да удовлетворяват.

3.Писане на новия код [редактиране]

Следващата стъпка е да се напише кодът. Този код трябва да удовлетворява изискванията на новите тестове.

На това ниво новият код може да не е перфектен, а просто да е направен така, че само да минава тестът. На по-късен етап той ще се подобри.

4. Изпълнение на всички тестове с успех [редактиране]

Ако тестовете са успешни, следователно новият код е покрил изискванията. Минаваме към последната стъпка от цикъла.

5. Подобряване на кода [редактиране]

Новият код може да бъде подобрен/рефакториран. След всяка промяна е нужно да се провери дали тестовете минават успешно.

Цикъл [редактиране]

По-горният цикъл може да започне отново с добавяне на нови тестове.

Стил на програмиране [редактиране]

Има много причини, за да се избере методът Разработка чрез тестове. Фокусирайки се върху това да се напише само функционалността, която удовлетворяват тестовете, прави нещата по опростени. За постигането на по-сложна дизайн концепция (пример: шаблони за дизайн), тестовете трябва да бъдат написани така, че да генерират този дизайн.

Напиши първо тестовете. Тестовете трябва да бъдат написани преди функционалността, която ще се тества. Това има две предимства. Първо, създава се възможност програмата да бъде тествана още от самото начало. Второ, гарантира, че ще има тестове за всяка нова функционалност.

Първоначално изпълнение на тестовете с неуспех. Идеята е да се види, че новите тестове наистина работят и грешките могат да бъдат уловени. При Разработката чрез тестове постоянно се добавят нови тестове, които първоначално са неуспешни, а след това успешни. Удовлетворяването на всеки един, вече написан тест, увеличава продуктивността на програмиста.

Практиките за напреднали при Разработката чрез тестове водят до "Acceptance Test-driven development" (ATDD).

Ползи [редактиране]

Проучване през 2005-та посочва, че Разработка чрез тестове означава писане на повече тестове. А когато програмистите пишат повече тестове, това говори за по-добра продуктивност.

По-рядко се налага на програмистите да ползват дебъгери. Ползвайки TDD с допълнение със система за контрол на версиите (version control system), дават възможност на програмистите, ако тестовете fail-нат, бързо да върнат до по-стара версия, която е била успешна. Това често е доста по-добро, отколкото дебъгването.

Разработката чрез тестове предлага нещо повече от валидация на новата функционалност. Възможно е също така да се определи дизайна на програмата. Истина е, че при TDD е необходимо по-голямо количество писане на код, заради писането на unit тестове. Но общото време за имплементация по-малко. Голямото количество тестове ограничават грешките в кода. Ранното тестване осигурява проблемите да бъдат хванати на време по време на цикъла за разработка и съответно поправени. Това намаля времето за дебъгване в по-късен етап от процеса.

При „Разработка чрез тестове”, кодът става по-модулно насочен и по-гъвкав. Това идва от факта, че програмистът мисли за програмата като разделена на малки единици, които трябва да се напишат и изтестват независими един от други, а на по-късен етап – сглобени.

Вземайки предвид факта, че кодът е толкова, колкото да покрие тестовете, идва резултатът, че за "всеки написан ред" има готов тест. Например, ако един TDD програмист иска да добави "else" условие към някой "if", то той трябва да напише тест за него, който първоначално да минава с неуспех.

Уязвимости [редактиране]

  • Разработка чрез тестове е трудно да се използва в ситуациите, когато се изискват тестове върху цялостната функционалност на продукта, които да определят успех или неуспех. Примери за подобни интерфейси са програми, които използват бази данни или някои, които зависят от специфични мрежови настройки.
  • Разбиране от страна на управлението е необходимо. Цялата организацията трябва да вярва в това, че Разработката чрез тестове е правилният подход, който трябва да се избере. В противен случай има риск, управлението да смята, че това е просто една загуба на време в писане на тестове.
  • Има възможност лошо написани тестове да завършват постоянно с неуспех. Понякога, когато едни и същи тестове завършват с неуспех постоянно, те биват пренебрегвани и ако възникне истински проблем, то той няма да бъде забелязан.
  • Степента на покритие на дадени тестове, трудно може да бъде променена на по-късен етап след няколко цикъла в TDD. По тази причина оригиналните тестове стават много важни с течение на времето. Една зле направена архитектура, зле измислен дизайн или стратегия за тестване, могат да доведат до fail-ването на доста тестове (вече същестуващи). Важно е възникналите проблеми да бъдат оправени индивидуално. Не е добре да бъдат премахнати тестовете, защото това би довело до неоткрити грешки при тестването.
  • Неочаквани проблеми при покритието на тестовете може да възникне по редица причини. Примерно, ако някой от програмистите не е добре запознат със стратегията на Разработката чрез тестове и следователно някои тестове не са написани както трябва. Възможно е и някои тестове да са изтрити, спрени инцидентно по някаква причина в процеса на работа.
  • По принцип unit тестове, създадени при Разработка чрез тестове, са написани от програмистът, който ще пише и кода по-късно. Така могат да изскочат проблеми от сорта на: Програмистът не е разбрал, че трябва да се направи проверка за коректност на входните параметри. В този случай нито тестовете ще тестват за това, нито ще бъде имплементирано в по-късно написания код. В този случай и тестовете и желаният код и ще бъдат грешни.
  • Голямото количество успешно завършили тестове може да доведе до грешно впечатление за абсолютна сигурност, което да доведе до недостатъчни действия на QA екипът.

Прозрачност на кода [редактиране]

Тестващият код трябва да има възможност да достъпва кода, който ще тества. От друга страна пък не трябва да се нарушават правилата за енкапсулация, скрита информация и т.н. По тази причина обикновено един модулен тест за TDD e написан в същия проект, в който е и кода, който ще се тества.

При един обектно-ориентиран дизайн достъпът до private данните и методи ще бъде ограничен. По тази причина се изисква допълнителна работа върху модулните тестове. В езици за програмиране като JAVA, private данните могат да бъдат достъпвани чрез reflection. Алтернативно на това unit тестовете могат да бъдат поставени в "inner" клас, създаден за целта, и по този начин те ще имат достъп до недостъпните отвън данни. При .NET Framework и някои други езици за програмиране, могат да бъдат използвани "partial" класове

Важно е да се отбележи, че такива хакове при тестване, не трябва да оставят в крайния код. C# и други езици за програмиране поддържат директиви при компилиране като #if DEBUG … #endif, където може да бъде поставен нужният код за тестване. Това означава, че кодът при един release, се различава от кода, който се използва при тестването.

Криейтив Комънс - Признание - Споделяне на споделеното Лиценз за свободна документация на ГНУ   Тази страница частично или изцяло представлява превод на страницата „Test-driven development“ в Уикипедия на английски. Оригиналната статия, както и този превод, са защитени от Лиценза „Криейтив Комънс - Признание, Споделяне на споделеното“, а за статии създадени преди юни 2009 — от Лиценза за свободна документация на ГНУ. Прегледайте историята на редакциите на оригиналната статия, както и преводната страница, за да видите списъка на съавторите.

Вижте също [редактиране]

Външни препратки [редактиране]