Unit Testing and Test-Driven Development

By April 18, 2013.NET Framework

test-keyboardКакво е тест? Теста е средство за проверка (и оценка) на определена функционалност чрез определен набор от тестове. В наши дни, при пазаруване на дадена стока(хранителни стоки, дрехи, химикали, техника…) вие правите проверка преди да я закупите, за да получите максимална информация за нея. Ако си купувате химикал, вие тествате дали пише, ако си купувате крушка, също ще искате да проверите дали работи. Дали говорим за хардуер, софтуер или някакъв друг продукт, тестването се превръща в задължително.

Тестването на софтуера е процес на валидация и верификация дали програмата работи правилно без грешки или всъщност процеса на търсене на бъгове и грешки. Тестването не само означава да оправим някой бъг в кода, но също и да проверим дали програмата отговаря на спецификациите. Има различни видове тестване в зависимост от различни видове дефекти: Functional testing, Performance testing, Usability testing, Security testing, Error-Handling testing и много други.

Какво е Unit Testing?

unit_testing_best_practise

Според Microsoft основната цел на Unit Testing-a е да вземете най-малкото смислено парче код и да го тествате изолирано от останалите. Важното е да разберете дали се държи по начина по който очаквате. И така докато тествате всички части на програмата. Хубавото на Unit Testing-a е че намирате рано грешките си в етап в който е лесно да се поправят. По надолу ще говоря и за Test-Driven Development-a при който писането на тестовете предхожда имплементацията.

На картинката можете да видите няколко примерни Unit test-a. Как да си направим Unit Test? В solution-a в който работите си правите нов проект: File -> Add -> New Project -> Unit Test Project. Автоматично ви се създава проект с примерен клас и метод. Важното е пред всеки тестов клас и метод да има атрибутите, съответно TestClass и TestMethod както е показано. Идеята на това е да покажете на Testing Framework-a, че съответния клас е тестов и той може да пусне всички тестове в него. Още нещо което трябва да направите е да добавите референция към проекта си: в случая SampleGame и да добавите using към него.

Можете да разгледате методите на класовете Assert и CollectionAssert и да си поиграете с тях като за начало. Във MSDN можете да видите

FINAL-TEST-PIC

Често използвани атрибути:

  • [TestClass] – Казвате на Unit Testing Framework-a, че класа е тестов, за да може да пуска тестовете му автоматично.
  • [TestMethod] – Също като TestClass казвате, че вашия метод е тестов.
  • [ExpectedException] – Използва се, когато очаквате при изпълнението на теста да се хвърли Exception. Можете да проверите дали при дадена ситуация се хвърля правилния Exception.
  • [Timeout] – С този атрибут можете да поставите времево ограничение на изпълнението на теста. Ако теста не успее да се изпълни за даденото време – той Fail-ва.
  • [Ignore] – Казвате на теста да не се изпълнява. Вместо да го триете или закоментирате, просто му слагате атрибута Ignore.
  • [ClassInitialize] – Преди всички тестове се изпълнява метода на който сте му поставили този атрибут.
  • [ClassCleanup] – След като всички тестове се изпълнят се изпълнява метода с атрибут ClassCleanup.
  • Същото е и с [TestInitialize] и casino online [TestCleanup], с разликата, че метода с един от тези атрибути се изпълнява преди или след изпълнението на всеки тест.
  • [Priority] – Можете да задавате приоритет на изпълнението на тестовете.
  • [Description] – Дава описание какво прави метода.
  • Останалите атрибути и различните класове и методи  можете да видите в UnitTesting namespace-a  MSDN-a.

 Visual Studio Test Explorer testExplorer

В Test Explorer-a можете да виждате резултатите, както и да пускате определени тестове по ваш избор. Ако искате можете да групирате различни тестове. Хубаво е, че можете да debug-нете определен тест и да видите точно какви са различните стойности.

advantageПредимства на Unit testing

  • Намалява броя на грешките във вашия код.
  • Спестява ви време.
  • По-лесно променяте и подобрявате кода си.
  • Можете да пускате тестовете по всяко време.
  • Може да се каже, че замества документацията.
  • Принуждава ви да се изправите лице в лице с проблема.
  • Вдъхва ви увереност и чувство на завършеност.
  • Просто е забавно!

Test-Driven Development

1273122839142Това е процес на разработка на софтуер при който първо се пишат тестовете, а след това логиката на кода. Основната цел на TDD е да представи документацията на разработвания продукт в по-добър и удобен вид на програмиста. Или по друг начин казано да мислите за спецификациите преди да си напишете кода и да ги изпълнявате по един по-лесен начин. Друга цел на Test-Driven Development-a е да пишете по-добре структуриран код, който работи.

Тази методология на писане на софтуер ви дава гъвкавост, която е необходима при използването на Agile методологии, защото при разработването на един продукт спецификациите постоянно се променят, а developer-ите трябва да са гъвкави.

Как да използваме TDD?

  1. Red – Напишете тест според изискванията и го пуснете. Той трябва да Fail-не. Единия начин е да си представите как ще се казват класовете и методите и да пишете тестове за тях. Другия начин, който мисля, че е по-добър е да си направите интерфейсите и структурата, без имплементация и да напишете тестове при което след като ги пуснете, те трябва да гърмят. Все още нямате никаква имплементация, така че това е очаквания ефект.
  2. Green – Време е да започнете да пишете кода. Направете така че тестовете ви да тръгнат. След като се погрижите да напишете логиката, би трябвало тестовете да минат успешно.
  3. Refactor – Сега вече можете да огледате кода и да подобрите неговата структура и качество, като гледате в същото време и тестовете да са успешни. След всяка промяна си пускайте тестовете за да сте сигурни, че всичко е наред.
  4. Повторете цикъла. Всеки цикъл трябва да бъде кратък и за няколко часа трябва да имате много “Red, Green, Refactor” цикли.

Предимства

TestDrivenGameDevelopment

  • Позволява ви да си изясните неща относно кода и дизайна още преди да сте почнали да пишете. Това може да ви спести доста часове.
  • Предразполага ви да допускате по-малко грешки и да удовлетворявате изискванията на тестовете, респективно на документацията. В случай, че си пишете тестовете накрая е възможно да пропуснете някое изискване и трябва да се връщате да поправяте. Ако използвате TDD това е много малко вероятно да се случи.
  • Всеки тест проверяващ малко парче код ви позволява да разберете къде точно е проблема.
  • За да премине кода ви даден тест, той трябва да е достатъчно добър и стабилен. Колкото по-добри тестове пишете, толкова по добър код ще генерирате.
  • Писането на тестове предварително ви дава увереност и отговорност. По всяко време знаете на какъв етап сте от разработката, защото знаете колко от тестовете са минали.
  • TDD ви позволява да погледнете кода от страната на потребите. Като стоите зад бара няма как това да се случи. Застанете пред бара и вижте ситуацията от погледа на потребителите. Това задължително ще подобри дизайна ви.

Недостатъци

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

Code-Coverage

Code Coverage

Това е мярка използвана при тестването на софтуер. Това е начин с който можете да разберете какъв процент (каква част) от кода сте успели да покриете чрез Unit тестове. Той е само ориентировъчен, но би могъл да ви насочи, ако сте пропуснали нещо. Не бих ви препоръчвал да му се доверявате сляпо.

Mocking

Какво е mocking? Сигурно сте забелязали, че при по-големи проекти, независимо колко се стараем класовете да не зависят един от друг, няма как да се избегне напълно, примерно при уеб приложение. Получава се така, че когато тестваме някой клас той зависи от много други неща. За да тествате нещо не е нужно да симулирате цял уеб сървър.

Ето тук идва на помощ Mocking-a. Това е начин или можем да го наречем метод с който можете да подменяте обекти. В Обектно-ориентираното програмиране Mock обектите са симулирани обекти, които имитират поведението на реални обекти. Най-често се ползват Mock обектите, за да се тества поведението на други обекти. Mock objects frameworks позволяват на програмистите да определят кои методи и в какъв ред ще бъдат използвани върху mock обекта, какви параметри ще му се подадат и какви стойности ще бъдат върнати.

Съвети:

  • shutterstock_90058993Кръщавайте си имената на методите винаги започващи с [Test]. Хубаво е да съдържат името на тествания метод, входните и изходните данни. 
  • Не премахвайте успешните тестове. Тези тестове ви уверяват, че всичко работи и ако някой счупи нещо, ще знаете къде е проблема.
  • Не търсете проблема в теста, а в кода си.
  • Давайте смислени съобщения в Assert методите. Те трябва да обясняват какво е трябвало, но не се е случило.
  • Избягвайте да слагате много Asserts във един тест. Трудно е да разберете дали гърми само един или няколко такива.
  • Пишете само по един Assert на тест!

 

One Comment

  • […] Какво е тест? Теста е средство за проверка (и оценка) на определена функционалност чрез определен набор от тестове. В наши дни, при пазаруване на дадена стока(хранителни стоки, дрехи, химикали, … Unit Testing and Test-Driven Development Vladimir Georgiev […]

Leave a Reply