JUnit е рамка за тестване на модули с отворен код на трета страна. Проектът е стартиран от Кент Бек и Ерих Гама в края на 1995 г. Той бързо привлече интерес в общността на разработчиците, които се занимават особено с разработване, управлявано от тестове. Първоначално JUnit беше въведен в Smalltalk, но по-късно беше пренесен на Java, което бързо прие това като де-факто стандарт за тестване на модули. Популярността на JUnit нарасна до степен, че за да задоволи нуждите на много други съвременни езици като C#, Perl, Python, PHP, Ruby, Visual Basic, C++ и така нататък, беше разработена обща рамка xUnit, където буквата 'x' се заменя с първата буква на езика, като JUnit за Java, RUnit за Ruby и т.н. Тази статия предоставя общ преглед на тази рамка, използвана от фактическия стандарт за тестване на модули на Java.
Общ преглед на тестването
Тестването е важна фаза в жизнения цикъл на разработката на приложение. Основната цел на тестването е да се оцени програма въз основа на необходимите спецификации. Целта е да се създадат определени тестови случаи, които показват грешки, пропуски, всякакви несъответствия или неочакван резултат, доколкото е възможно. Тази проста концепция има някои сложни процеси, свързани с нея. Но, казано накратко, това се прави на три нива. Когато тестването се извършва на много детайлно ниво или ниво на отделен компонент, то се нарича Unit Testing; когато се комбинират, за да се проверят интерфейсите между компонентите спрямо софтуерния дизайн, това се нарича Интеграционно тестване; и накрая, когато цялата система е интегрирана и се извършва тестване, за да се провери дали системата като цяло отговаря на посоченото изискване, това се нарича Системно тестване .
Тестване на модули
Накратко, извършването на единичен тест е начин да се изследва поведението на отделна единица код. В Java, единица код може да означава метод или клас или дори модул, според контекста. Ако това е метод, например, фокусът на теста е върху оценката на правилната препратка към обекта, разрешена за извикване на метода, тип параметри и приемливи стойности, диапазони на примитивни стойности, тип и стойност на връщане и т.н. Идеята е методът да се запече, така че да може да се направи достатъчно здрав, за да се справи грациозно с проблема си и да изхвърли онези, които са извън неговия обхват, освен да изпълни договора си.
Следователно, единичното тестване формира основния градивен елемент на всяка оценка на програмата. Всъщност всеки програмист извършва някакъв вид модулно тестване, докато пише код, за да провери резултата от кода с някои фиктивни данни/случаи. По този начин единичното тестване е формален статут, даден на тази изолирана колекция от тестове. Изключително важно е един код да премине през строгостта на различни фази на тестване. Единичното тестване, освен важността си, е и много обичайно. Хора като Кент Бек и Ерих Гама мислеха да създадат рамка за него, така че програмистите да получат структурирана среда и да могат да автоматизират много от тези задачи. В крайна сметка за това служи рамката. Обикновено той осигурява съгласувана програмна структура, която може да се използва повторно и да се споделя между приложения. Програмистът може да ги включи в съществуващо приложение и да ги разшири според специфичните си нужди.
Бърз пример
Прост код за тестване на единици за проверка на единичния метод в Температура клас без използване на JUnit рамка е както следва:
package org.mano.unittest.examples; public class Circle { double area(double radius) { returnMath.PI* radius * radius; } }
Сега нека напишем кода за единично тестване на областта метод.
package org.mano.unittest.examples; public class CircleTest { public int errCounter= 0; public void testCircleArea() { Circle circle = new Circle(); double area = circle.area(12); if (area < 452 && area > 453) { throw new IllegalStateException("Wrong calculation!: " + area); } } public static void main(String[] args) { TestCircle test = new TestCircle(); try { test.testCircleArea(); } catch (Throwable e) { test.errCounter++; e.printStackTrace(); } if (test.errCounter> 0) { throw new IllegalStateException("There were " + test.errCounter+ " error(s)"); } } }
Това е елементарен пример, но ви дава представа как може да се извърши тестване на модули, без да се използва никаква рамка.
JUnit Testing Framework
Използването на JUnit рамка за тестване на модули има няколко предимства. Той предоставя множество пояснения, които улесняват писането и стартирането на тестови кодове в Java:
- На първо място, той отделя грижата за тестване на модули от действителния код на проекта, като дава възможност да се създаде екземпляр на тестов клас и зареждачи на класове за всеки единичен тест. Те „имунизират“ съществуващия код от ненужни странични ефекти от тестването.
- Анотациите, предоставени от JUnit – като @Before, @After, @BeforeClass, @AfterClass —има методи както за инициализация на ресурс, така и за възстановяване на ресурси.
- Има голямо разнообразие от методи за удостоверяване за проверка на резултата от теста.
- През годините JUnit стана толкова популярен, че множество инструменти на Java, като Ant и Maven; и популярни IDE, като Eclipse , NetBeans , IntelliJ ИДЕЯ , и други подобни, идва с вградена интеграция на JUnit.
За да използвате JUnit Test Framework в Java проект, трябва да добавите JUnit JAR файл в пътя на класа на проекта. Това се изисква изрично, ако IDE не е интегрирана с библиотеката JUnit. Процесът е прост. Изтеглете JAR файла и го добавете към пътя на класа на проекта.
Ето някои важни връзки към рамката на JUnit.
- Официален сайт на JUnit
- JUnit Java API
- Ръководство за потребителя на JUnit
- JUnit изходен код в GitHub
За разлика от JUnit 4 и неговите предшественици, JUnit 5 донесе някои значителни промени. Освен много добавени нови функции – като поддръжка на ламбда, нови анотации и инжектиране на параметри на тестовия метод – архитектурата на ядрото получи някои значителни модификации. JUnit 5 вече е съставна архитектура от три различни модула:JUnit Jupiter, JUnit Vintage и JUnit Platform. Разработчиците на тестови случаи обаче не трябва да се притесняват за тънкостите на промените. Промените означават преди всичко по-добра поддръжка на инструменти, последователност и по-чисти API. Преди всичко, той е напълно обратно съвместим с JUnit 4. Така че, не се притеснявайте. Вижте ръководството за потребителя на JUnit 5 за повече подробности.
Бърз пример
Ето един много прост пример, за да видите как може да се направи тестване на модули с рамката JUnit. Използваме Служител клас за единичния тест и създайте тестов клас, за да дадете представа за неговата работа. Примерът е елементарен до степента на писане на програма „Hello World“. Тестовите случаи в реалния свят или дори приличен пример за единични тестове изискват добро количество код. Може би ще опитаме това в друга статия.
package org.mano.unittest.examples; public class Employee { private final String name; private final double basicPay; public Employee(String name, double basicPay) { this.name=name; this.basicPay=basicPay; } public String getName() { return name; } public double getBasicPay() { return basicPay; } } package org.mano.unittest.examples; import org.junit.Test; import static org.junit.Assert.*; public class EmployeeTest { @Test public void constructorInitTest(){ Employee emp=new Employee("Odin", 2300); assertEquals("Odin", emp.getName()); assertEquals(2300, emp.getBasicPay(), 0.001); } } package org.mano.unittest.examples; public class EmployeeTestMain { public static void main(String[] args){ EmployeeTest et=new EmployeeTest(); et.constructorInitTest(); } }
Обърнете внимание, че класът Employee е неизменим само с две полета, зададени от конструктора. Тъй като само методът на конструктора си струва да се тества, ние ще тестваме само това.
Тестовият клас се нарича EmployeeTest според конвенцията. Пояснението @Test позволява на JUnit да определи метод като тестов метод. В Asert има различни методи за потвърждаване клас. Тук сме използвали само assertEquals .
Има много начини да стартирате тест, написан в JUnit. Обикновено след изпълнение на тестовите случаи той отпечатва резюме. То обаче може да варира в зависимост от начина на провеждане на теста. Може да работи през IDE като Eclipse или IntelliJ или инструменти като Maven, Gradle и т.н. Понякога единствената информация, получена след теста, е, че той е или неуспешен, или издържан.
Заключение
Има няколко други рамки за модулно тестване. JUnit е популярна рамка за тестване на модули сред Java общността. Тестването като фаза на системно инженерство включва много повече процеси. Unit тестването е само част от него и интересното е, че много тестове за игра, които се правят от разработчика, могат да се нарекат като юнит тестване. JUnit, като тестова рамка, добавя стойност към нея. Анотациите и API, предоставени от JUnit, автоматизират много задачи и правят живота много по-лесен за разработчиците на модулни тестове.