BME Irányítástechnika és Informatika Tanszék A programozás alapjai

Hasonló dokumentumok
A JUnit alapú egységteszteléshez felhasználandó annotációk leírásait az alábbi URL-en találja meg:

JUnit. JUnit használata. IDE támogatás. Parancssori használat. Teszt készítése. Teszt készítése

A feladatok megoldásához felhasználandó annotációk leírásait az alábbi URL-en találja meg:

A megjelenő ablakban a Work with feliratú mezőbe gépeljük be az EclEmma plugin elérési útját:

public class HelloWorld extends TestCase { public void testmultiplication() { // Testing if 3*2=6: assertequals ("Multiplication", 6, 3*2);

Szoftvertechnolo gia gyakorlat

Unit Teszt. Tóth Zsolt. Miskolci Egyetem. Tóth Zsolt (Miskolci Egyetem) Unit Teszt / 22

A legalacsonyabb szintű tesztelés. A programot felépítő egységek tesztelése Unit: egy rendszer legkisebb önálló egységként tesztlehető része.

Osztályok. 4. gyakorlat

JUnit.

Kivételkezelés, beágyazott osztályok. Nyolcadik gyakorlat

Programozási technológia

Stateless Session Bean

Szűgyi Zalán. Unit tesztek Java és C++ környezetben

EDInet Connector telepítési segédlet

Webes alkalmazások fejlesztése 10. előadás. Webszolgáltatások tesztelése (ASP.NET Core) Cserép Máté

OBJEKTUM ORIENTÁLT PROGRAMOZÁS JAVA NYELVEN. vizsgatételek

Java programozási nyelv 6. rész Java a gyakorlatban

Szervlet-JSP együttműködés

Swing GUI készítése NetBeans IDE segítségével

A Novitax ügyviteli programrendszer első telepítése

Tanúsítvány feltöltése Micardo kártyára

Autodesk Inventor Professional New Default Standard.ipt

Objektum Orientált Programozás. 11. Kivételkezelés 44/1B IT MAN

1 Rendszerkövetelmények

A MOKKA hitelesítő szoftver telepítése és használata

Sikeres végrehajtás(pass): ez azt jelenti, hogy a teszt rendben lefutott, és az ellenőrzési feltételek mind teljesültek.

AZ N-WARE KFT. ÁLTAL ELEKTRONIKUSAN ALÁÍRT PDF DOKUMENTUMOK HITELESSÉGÉNEK ELLENŐRZÉSE VERZIÓ SZÁM: 1.3 KELT:

GIROLOCK2 ROOT_CA ÉS ÜZEMI CA TANÚSÍTVÁNY IMPORTÁLÁSI SEGÉDLET

Távolléti díj kezelése a Novitax programban

Ubuntu Érettségi Remix Telepítési és beállítási leírás. Ágazati szakmai komplex távközlési ismeretek érettségihez

Telepítési útmutató a SMART Response 2009 szoftverhez

AZ N-WARE KFT. ÁLTAL ELEKTRONIKUSAN ALÁÍRT PDF DOKUMENTUMOK HITELESSÉGÉNEK ELLENŐRZÉSE VERZIÓ SZÁM: 1.1 KELT:

Telepítési útmutató a SMART Notebook 10.6 oktatói szoftverhez

New Default Standard.ipt

Segédlet kriptográfiai szolgáltatást beállító szoftverhez (CSPChanger)

Eseményvezérelt alkalmazások fejlesztése I 11. előadás. Szoftverek tesztelése

OOP: Java 11.Gy: Enumok, beágyazott osztályok. 13/1 B ITv: MAN

Johanyák Zsolt Csaba: Grafikus felület programozása. Copyright 2008 Johanyák Zsolt Csaba

Java programozási nyelv 5. rész Osztályok III.

Felhasználói leírás a DimNAV Server segédprogramhoz ( )

Az osztályok csomagokba vannak rendezve, minden csomag tetszőleges. Könyvtárhierarhiát fed: Pl.: java/util/scanner.java

Programozási nyelvek Java

A CAPICOM ActiveX komponens telepítésének és használatának leírása Windows7 operációs rendszer és Internet Explorer 8-es verziójú böngésző esetén

OOP: Java 8.Gy: Abstract osztályok, interfészek

Telepítési és indítási útmutató. DataPage+ 2013

15.4.2a Laborgyakorlat: Böngésző beállítása

A TERC VIP költségvetés-készítő program telepítése, Interneten keresztül, manuálisan

Megújított tanúsítvány cseréje a Windows tanúsítványtárban

GIRO GSM MODEM/VPN KAPCSOLAT TELEPÍTÉSI ÚTMUTATÓ

Programozási nyelvek Java

Telepítési útmutató a SMART Notebook 10 SP1 szoftverhez

Modern unit és integrációs tesztelés

MEGÚJÍTOTT GIROLOCK_CA TANÚSÍTVÁNYCSERE

Image Processor BarCode Service. Felhasználói és üzemeltetői kézikönyv

Rövid leírás a Make Your Mark szoftver használatához

OpenVPN kliens telepítése a RITEK Zrt. szervereinek eléréséhez.

Szerző. Varga Péter ETR azonosító: VAPQAAI.ELTE cím: Név: Kurzuskód:

Útmutató az OKM 2007 FIT-jelentés telepítéséhez

Programozás I. házi feladat

1. A Windows programok telepítése

Programozási nyelvek II. JAVA

Mesterséges Intelligencia II. kötelező feladat (3. forduló) - Ajánló rendszer 2.

Megoldások a mintavizsga kérdések a VIMIAC04 tárgy ellenőrzési technikák részéhez kapcsolódóan (2017. május)

A feladatok megoldásához felhasználandó osztályok leírásait az alábbi URL-en találja meg:

Java programozási nyelv 4. rész Osztályok II.

SSL VPN KAPCSOLAT TELEPÍTÉSI ÚTMUTATÓ

Java VI. Egy kis kitérő: az UML. Osztály diagram. Általános Informatikai Tanszék Utolsó módosítás:

QGIS Gyakorló. 1. kép. A vektor réteg (grassland.shp).

TÍPUSDOKUMENTUMOK KÉSZÍTÉSE

Javac és Eclipse útmutató

Programozási nyelvek Java

NINJA kezelői program letöltése és installálása

OpenCL alapú eszközök verifikációja és validációja a gyakorlatban

SDX Professional 1.0 Telepítési leírás

Szoftvertelepítési útmutató NPD HU

Space Invaders Dokumenta cio

Közoktatási Statisztika Tájékoztató 2012/2013. Használati útmutató

Két csomag elemeiből lehet a felületet elkészíteni: awt: heavy weight komponensek; swing: light weight komponensek (időben később).

libgdx alapok, első alkalmazás

1.1.1 Dátum és idő függvények

Programozási technológia

Az Evolut Főkönyv program telepítési és beállítási útmutatója v2.0

TERC V.I.P. hardverkulcs regisztráció

A Telepítés hajlékonylemezről panelen kattintson az OK gombra.

Java és web programozás

WINDOWS TELEPÍTÉSI ÉS AKTIVÁLÁSI ÚTMUTATÓ A FOTOBETYAR.HU - PHOTOSHOP PLUGINJEIHEZ

Internetkonfigurációs követelmények. A számítógép konfigurálása. Beállítások Windows XP alatt

Segédanyag: Java alkalmazások gyakorlat

Azonosí tá srá Visszávezetett Dokumentumhitelesí te s (AVDH) á Perkápu vonátkozá sá bán

3. Osztályok II. Programozás II

Karbantartás. Az ESZR Karbantartás menüjébentudjuk elvégezni az alábbiakat:

QGIS gyakorló. --tulajdonságok--stílus fül--széthúzás a terjedelemre).

Gyökértanúsítványok telepítése Windows Mobile operációs rendszerekre

Hardver és szoftver követelmények

K&H token tanúsítvány megújítás

Objektumorientált programozás C# nyelven

POSZEIDON dokumentáció (12.2)

M-Files Dokumentumkezelő telepítése

Digitális aláíró program telepítése az ERA rendszeren

Átírás:

JUnit tutorial Készítette: Budai Péter, BME IIT, 2015. A JUnit alapú egységteszteléshez felhasználandó annotációk leírásait az alábbi URL-en találja meg: http://junit.sourceforge.net/javadoc/ A JUnit keretrendszer használata során felmerülő legtöbb kérdésre a JUnit FAQ dokumentum (azon belül is elsősorban a 4., 5. és 7. szakasz) nyújt választ: http://junit.sourceforge.net/doc/faq/faq.htm Többek között a parametrikus tesztelés használatára is mutat példát az alábbi JUnit Tutorial: http://www.mkyong.com/tutorials/junit-tutorials/ 1 Egy egyszerű számológép osztály létrehozása Készítsünk egy egyszerű számológép osztályt Java nyelven, mely képes lebegőpontos számok szorzására és osztására. Ezen az osztályon fogjuk bemutatni a JUnit keretrendszer legegyszerűbb lehetőségeit. Ehhez hozzunk létre egy új Java projektet az Eclipse-en belül, legyen a neve JUnitTest. 1

A projektben hozzunk létre egy új, Calculator nevű osztályt a junittest csomagon belül: Végül valósítsuk is meg a számológépünk funkcióit a Calculator osztályban. Ehhez vegyünk fel két metódust, egyet a szorzásnak és egyet az osztásnak. Az osztást megvalósító metódusnál figyeljünk rá, hogy a nullával való osztást elkerüljük. Ilyenkor dobjunk IllegalArgumentException! package junittest; public class Calculator { public double multiply(double a, double b) { return a * b; public double divide(double a, double b) throws IllegalArgumentException { if(b == 0) { throw new IllegalArgumentException(); return a / b; 2

2 A számológép osztály tesztelése a JUnit 4 keretrendszerrel A JUnit egy nyílt forráskódú Java osztálykönyvtár, mely mára a Java nyelven írt programok egységtesztelésének (unit testing) egyik legnépszerűbb megoldásává vált. A JUnit keretrendszer olyan osztályokat tartalmaz, melyek kényelmesebbé, átláthatóbbá és megismételhetővé teszik a programok alapvető egységeinek (osztályoknak és metódusoknak) a tesztelését. A JUnit keretrendszert általában a különböző fejlesztő-környezetek is támogatják, így az Eclipse is. Ha használni szeretnénk, a JUnit osztálykönyvtárát hozzá kell adnunk a projektünkhöz, ahogy az alábbi ábrán is látható. Ehhez a projekt nevén jobb egérgombbal való kattintásra felugró menüből válasszuk a legalsó, Properties menüpontot, majd a megnyíló ablakban navigáljunk a Java Build Path, Libraries, Add Library... lehetőséghez. Az újabb ablakban válasszuk ki a JUnit könyvtárat, a következő képernyőn pedig a legördülő menüből a JUnit 4 verziót. A korábbi verziót másképpen kell használni, ezen laborgyakorlat során nem foglalkozunk vele. Az alábbi ábra segít megtalálni a kérdéses dialógusablakot. 3

Egy szoftver fejlesztése során a tesztosztályokat általában külön kezeljük az alkalmazás logikától, hiszen azok nem kerülnek majd bele a lefordított és összecsomagolt.jar fájlba. Ezért az Eclipse projektünkben létre kell hozni egy új forráskönyvtárat a teszt-állományok számára. Ehhez kattintsunk jobb egér-gombbal a projekten, majd válasszuk a New, Source Folder lehetőséget. A könyvtár neve legyen test, ahogy az alábbi ábrán is látszik. A tesztállományokat itt ugyanolyan package struktúrába szervezhetjük, mint a programunk többi részét. A konvenció szerint a tesztosztályokat ugyanabba a csomagba helyezzük el, ahol a tesztelt osztály is található. Így a tesztosztályok hozzáférhetnek az alapértelmezett (default, package) láthatóságú elemekhez is, a külön forráskönyvtár miatt azonban nem kerülnek bele a végleges szoftverbe. 4

Most pedig hozzunk létre ez új JUnit Test Case-t a test könyvtárunkon belül. A neve legyen CalculatorTest, és tegyük a junittest package-be. Ezt mutatja a fenti ábra. Ha nem találjuk a JUnit Test Case opciót, akkor sincs baj, tökéletesen megfelel, ha csak egyszerűen egy új Java osztályt hozunk létre ugyanilyen névvel, ugyanebben a package-ben. Amikor a JUnit segítségével végezzük a tesztelést, a különböző teszteseteinket külön Java osztályok és metódusok formájában készítjük el, melyeket a megfelelő annotációkkal (@Test és társai) látunk el. Ezek alapján a keretrendszer fogja lefuttatni a teszteket, és a végén összesíti az eredményeket. Egy tesztosztályban több tesztmetódust is elhelyezhetünk. A tesztmetódusokban az org.junit.assert osztály assertxxx() metódusait használhatjuk arra, hogy összevessük a várt és tényleges eredményeket. Ezek a metódusok automatikusan sikertelennek minősítik az tesztesetet, amint a eltéréseket tapasztalnak a várt és tényleges értékek között. A JUnit ráadásul lehetőséget ad arra is, hogy megjelölhessük, ha valamely tesztmetódus során egy kivétel megjelenése a kívánatos esemény. Ilyenkor a kivétel hiánya jelenti a hibás teszteredményt. Ennek pontos módja a FAQ-ban olvasható. Most pedig készítsük el a teszteseteinket. A példa kedvéért most meglehetősen felületesek leszünk, és csak egyetlen számpárra próbáljuk ki mindkét műveletet. Viszont azt külön teszteljük, hogy a nullával való osztást jól kezeli-e az osztályunk, és valóban kivétel keletkezik-e. package junittest; import org.junit.assert; import org.junit.test; public class CalculatorTest { @Test public void testmultiply() { Calculator calc = new Calculator(); double result = calc.multiply(5.0, 8.0); Assert.assertEquals(40.0, result, 0); @Test public void testdivide() throws Exception { Calculator calc = new Calculator(); double result = calc.divide(20.0, 4.0); Assert.assertEquals(5.0, result, 0); @Test(expected=IllegalArgumentException.class) public void testdividebyzero() throws Exception { Calculator calc = new Calculator(); calc.divide(10.0, 0.0); 5

Ha elkészült a tesztosztályunk, akkor az Eclipse Package Explorer ablakában jobb egérgombbal rákattintunk (vagy a projekt nevére), és kiválasztjuk a Run As/JUnit Test lehetőséget. A fejlesztőkörnyezet le fogja futtatni nekünk az osztályban található teszteket, és egy ablakban meg is jeleníti azok eredményeit, ahogy az a következő ábrán látható is: 6

3 Tesztkörnyezetek használata A JUnit keretrendszerben a tesztmetódusok egymástól függetlenül kerülnek végrehajtásra, az egyik teszt eredménye nem befolyásolja a másikét. Ezt úgy éri el a JUnit, hogy minden tesztmetódus végrehajtásához egy teljesen új példányt hoz létre a tesztosztályból. Összetettebb komponensek esetén gyakori eset, hogy egy adott művelet teszteléséhez a vizsgált objektumot előzőleg egy meghatározott kiindulási állapotba kell hozni. Az ehhez szükséges (néha nagy számú) lépések valójában logikailag nem tartoznak a teszthez. Ráadásul ha több teszteset is felhasználja ugyanazt a kiinduló állapotot, ezeket minden egyes tesztmetódusban meg kellene ismételni. A JUnit ezért lehetőséget ad arra, hogy ezeket a tesztinicializáló (és esetleg -lezáró) kódrészleteket külön metódusokba helyezzük el a tesztosztályon belül, melyeket aztán minden tesztmetódus előtt (és után) meghív. Ily módon a tesztek számára egy úgynevezett tesztkörnyezetet (test fixture) alakíthatunk ki. Az inicializáló és lezáró metódusokat szintén annotációk (@Before és @After) jelölik. Most alakítsuk át a tesztosztályunkat úgy, hogy számológép objektum létrehozását ne kelljen minden tesztmetódusban elvégezni, ezt helyezzük át a speciális tesztkörnyezet-inicializáló metódusba! A számológépes példánál ezzel sokat nem nyerünk, de az elvet jól demonstrálja. package junittest; import org.junit.assert; import org.junit.before; import org.junit.test; public class CalculatorTest { Calculator calc; @Before public void setup() { calc = new Calculator(); @Test public void testmultiply() { double result = calc.multiply(5.0, 8.0); Assert.assertEquals(40.0, result, 0); @Test public void testdivide() throws Exception { double result = calc.divide(20.0, 4.0); Assert.assertEquals(5.0, result, 0); @Test(expected=IllegalArgumentException.class) public void testdividebyzero() throws Exception { calc.divide(10.0, 0.0); 7

Figyeljünk arra, hogy a létrehozott számológép példányt elérhetővé kell tenni a tesztmetódusok számára, ezért tagváltozóként kellett felvennünk. Ha mindent jól csináltunk és újra lefuttatjuk a teszteket, akkor az eredmény nem változott, a teszt továbbra is sikeres. 8

4 Kódlefedettség-vizsgálat az EclEmma plugin segítségével Az Emma egy nyílt forráskódú Java osztálykönyvtár, mely képes arra, hogy egy tetszőleges Java program futtatása során (így egy JUnit teszt esetén is) feljegyezze, hogy a végrehajtás mely utasításokat érintette (akár JVM bytecode szinten is), és erről részletes kimutatást ad osztályokra lebontva. Az Emma eszköz használatát megkönnyítendő, Eclipse plugin (EclEmma) is készült hozzá, mely lehetővé teszi, hogy egy kattintással elvégezzük a kódlefedettség-mérést, ráadásul a forráskódban is automatikusan megjelöli azokat a programsorokat, melyeket érintett a végrehajtás. Az EclEmma plugint az Eclipse alapcsomag nem tartalmazza, a plugint magunknak kell telepítenünk. Ehhez indítsuk el az Eclipse-et, majd kattintsunk a Help/Install New Software... menüpontra. A megjelenő ablakban a Work with feliratú mezőbe gépeljük be az EclEmma plugin elérési útját: http://update.eclemma.org/ Ha betöltötte a telepíthető pluginek listáját, akkor válasszuk ki az EclEmma csoportot és annak összes alelemét (lásd fenti ábra), majd kattintsunk a Next-re. A licenszfeltételek elfogadása és még néhány további Next, illetve Finish gombra való kattintás után a plugin feltelepül az Eclipse-be. Indítsuk újra a fejlesztőkörnyezetet, és már használhatjuk is a feltelepített plugint. Az EclEmma plugin használata nagyon egyszerű, a Package Explorer ablakban kattintsunk jobb egérgombbal a projekt nevére, majd most a Run As helyett a Coverage As, JUnit Test menüpontot kell választanunk. A tesztek megszokott módon történő lefutása után megjelenik egy Coverage ablak, ahol fájlokra lebontva megtekinthető a kódlefedettségi statisztika. A fájl nevére duplán 9

kattintva pedig megnyílik a forráskód, melyben megfelelően színezett sorok mutatják a végrehajtás által érintett területeket. Egy példa látható minderre a következő oldali ábrán: 10

5 Paraméteres tesztelés JUnit segítségével Főkent különböző algoritmusok fejlesztése során tipikus feladat, hogy egy bizonyos műveletet több különböző bemeneti adatra is le kell tesztelni, hogy megbizonyosodjunk arról, hogy a program szélsőséges esetekben is helyesen működik. Ilyenkor minden bemeneti adathoz külön tesztmetódust kellene készíteni, ami szélesebb paramétertartománynál már kezelhetetlenné válik. Szerencsére a JUnit kínál megoldást ennek kikerülésére is a paraméteres tesztek (parametrized test) formájában. Paraméteres teszt esetén a tesztosztály egy, a megfelelő annotációval (@Parameters) ellátott statikus metódusán keresztül adjuk meg a bemeneti adatsorokat, és az osztályban szereplő tesztmetódusokat pontosan annyiszor fogja lefuttatni a keretrendszer, ahány ilyen különböző bemeneti adatsor van. A tesztek egyszerre egy adatsoron kerülnek lefuttatásra, melyet a konstruktorban kap meg a tesztobjektum. Mindezeket egy példával is illusztrálja a JUnit Tutorial (lásd fent) megfelelő szakasza. A statikus metódus Object tömbök kollekciójával (Collection<Object[]> vagy List<Object[]>, stb.) tér vissza. A kollekció elemszáma (.size()) adja meg, hogy hányszor kell lefuttatni a tesztet (hányféle különböző adatsor van). A kollekcióban szereplő Object[] típusú elemek pedig egy-egy adatsort tartalmaznak (azért tömb, mert előfordulhat, hogy egy teszthez több paraméter tartozhat, például bemeneti értékek és elvárt kimeneti értékek párjai). Az adatsort tartalmazó, Object[] típusú tömb elemszámának (.length) meg kell egyeznie a tesztosztály konstruktora argumentumainak számával. Ugyanis a JUnit a tömb elemeit fogja sorban értékül adni a konstruktor argumentumainak, amikor példányosítja a tesztosztályt. Tehát ha a konstruktornak három argumentuma van és ezekből összesen négyféle ilyen hármas kombinációval kell lefuttatni a tesztet, akkor a metódus egy négyelemű kollekcióval tér vissza, melyben háromelemű tömbök vannak. A gyakorlatban a konstruktorban kapott paramétereket általában eltároljuk a tesztosztály egy tagváltozójában, hogy később a tesztmetódusokban használhassuk azokat. A parametrikus tesztek speciálisak abból a szempontból, hogy az alapértelmezett JUnit végrehajtó motor nem képes lefuttatni őket. Ezért a tesztosztályunkat egy speciális annotációval (@RunWith) kell ellátni, melynek a paraméterében megadhatjuk, hogy a JUnit azt a végrehajtó osztályt (org.junit.runners.parameterized) használja, amely fel van készülve a parametrikus tesztek kezelésére. Most pedig alakítsuk át a tesztosztályunkat úgy, hogy ne csak egy-egy számpárral végezze el a szorzás és osztás műveletek tesztelését, hanem öt különböző operanduspárral: 11

package junittest; import java.util.arraylist; import java.util.list; import org.junit.assert; import org.junit.before; import org.junit.test; import org.junit.runner.runwith; import org.junit.runners.parameterized; import org.junit.runners.parameterized.parameters; @RunWith(Parameterized.class) public class CalculatorTest { double a; double b; Calculator calc; public CalculatorTest(double a, double b) { this.a = a; this.b = b; @Before public void setup() { calc = new Calculator(); @Test public void testmultiply() { double result = calc.multiply(a, b); Assert.assertEquals(a * b, result, 0); @Test public void testdivide() throws Exception { double result = calc.divide(a, b); Assert.assertEquals(a / b, result, 0); @Test(expected=IllegalArgumentException.class) public void testdividebyzero() throws Exception { calc.divide(a, 0.0); @Parameters public static List<Object[]> parameters() { List<Object[]> params = new ArrayList<Object[]>(); params.add(new Object[] {0.0, 0.0); params.add(new Object[] {10.0, 0.0); params.add(new Object[] {10.0, 3.0); params.add(new Object[] {20.0, 4.0); params.add(new Object[] {40.0, 5.0); return params; 12

Ha lefuttatjuk a parametrikus tesztünket, azt tapasztaljuk, hogy már nem hibátlan eredményt kapunk (lásd az alábbi ábrát). Az első két adatpárnál, ahol a második paraméter értéke nulla volt, az osztást tesztelő metódus nem várt kivételt (IllegalArgumentException) kapott. Ez természetesen nem a Calculator osztály hibája, a teszteseteink vannak rosszul megválasztva, hiába, a jó tesztek tervezése egy külön tudományterület. 13