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

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

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

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

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

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

Работен цикъл[редактиране | edit source]

  1. Добавяне на тест
    Всяка нова функционалност започва с писането на тест. За да се напише един такъв тест, разработчикът трябва да има ясна представа от спецификацията и изискванията за новата функционалност. Тъй като самата функционалност все още не е написана, резултатът от теста ще е неуспех.
  2. Изпълнение на всички тестове и проверка на новия тест
    Това е проверка за валидността на тестовете и дали новият тест случайно не минава успешно, тогава не е е необходим нов код.
  3. Писане на новия код
    Следващата стъпка е да се напише кодът. Този код трябва да удовлетворява изискванията на новите тестове. На това ниво новият код може да не е перфектен, а просто да е направен така, че само да минава тестът. На по-късен етап той ще се подобри.
  4. Изпълнение на всички тестове с успех
    Ако тестовете са успешни, следователно новият код е покрил изискванията. Минаваме към последната стъпка от цикъла.
  5. Подобряване на кода
    Новият код може да бъде подобрен (преработка на код). След всяка промяна е нужно да се провери дали тестовете минават успешно.
Графично представяне на работния цикъл

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

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

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

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

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

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

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

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

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

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

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

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

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

Недостатъци[редактиране | edit source]

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

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

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

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

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

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

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

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