720 likes | 801 Views
Nyílt Fejlesztőrendszerek Plugin fejlesztés. Extension point-ok. Safe platform rule „ As the provider of an extension point, you must protect yourself against misbehavior on the part of extenders ” A felkínált kiegészítési pontnak biztonságosnak kell lenni, még a kiegészítés hibája esetén is!
E N D
Extension point-ok • Safe platform rule • „As the provider of an extension point, you must protect yourself against misbehavior on the part of extenders” • A felkínált kiegészítési pontnak biztonságosnak kell lenni, még a kiegészítés hibája esetén is! • Invitation rule • „Whenever possible, let others contribute to your contributions”
Extension point-ok • Fair play rule • „All clients play by the same rules, even me.” • Ne legyen saját „hátsó bejárat”, rejtett interfész • Explicit Extension Rule • „Declare explicitly where a platform can be extended” • A deklaráció a plugin.xml-ben • Diversity Rule • „Extension points accept multiple extensions”
Extension point-ok • Hogyan kérdezhetjük le a ponthoz tartozó kiegészítéseket? • Platform.getExtensionRegistry() • IExtensionRegistry.getExtensionPoint(String) • IExtension[] IExtensionPoint.getExtensions() • IExtension.getConfigurationElements() • Az adott elem attribútumait, gyerekeit tartalmazza • Validáció kérhető
Extension point-ok • Hogyan példányosítjuk a megadott osztályt? • Csak egy osztálynév van • A mi classloader-ünk nem találhatja meg, mert nincs a függő plugin-ok listáján • Nem is biztos, hogy kívülről látszik az osztály • Megoldás: kérjük meg az extension plug-in saját classloader-ét, hogy végezze el a piszkos munkát! • IConfigurationElement.createExecutableExtension(String)
Extension-ök értesítése/hívása • Hogyan értesítjük az extension-t? • Adott hívási felület (interface) • Fel kell készülni a hibákra, exception-ökre • Kivételkezelés! • Minden extension hívást külön try-catch blokkban • Fault containment region… • Good fences rule: „When passing control outside your code, protectyourself.” • Intézményesített gyanakvás: ISafeRunnable
Extension-ök értesítése/hívása • ISafeRunnable • public void run() – ebbe tegyük a futtatandó kódot • public void handleException(Throwable) • Kezeli a kivételeket, amik futtatás közben keletkeztek • Például kidobhatjuk az extension-t, ha bajt okozott
Példa: ISafeRunnable for (Iterator all=getListeners().iterator();all.hasNext()) { IMyExstension ext = (IMyExtension)all.next(); ISafeRunnable runnable = new ISAfeRunnable() { public void handleException(Throwable exception){ all.remove(); } public void run() throws Exception { ext.execute(); //hívom az extensiont } }; Platform.run(runnable); }
Példa: ISafeRunnable for (Iterator all=getListeners().iterator();all.hasNext()) { IMyExstension ext = (IMyExtension)all.next(); ISafeRunnable runnable = new ISAfeRunnable() { public void handleException(Throwable exception){ all.remove(); } public void run() throws Exception { ext.execute(); //hívom az extensiont } }; Platform.run(runnable); } Végigmegyünk az extension-ökön
Példa: ISafeRunnable for (Iterator all=getListeners().iterator();all.hasNext()) { IMyExstension ext = (IMyExtension)all.next(); ISafeRunnable runnable = new ISAfeRunnable() { public void handleException(Throwable exception){ all.remove(); } public void run() throws Exception { ext.execute(); //hívom az extensiont } }; Platform.run(runnable); } Kivesszük a következőt
Példa: ISafeRunnable for (Iterator all=getListeners().iterator();all.hasNext()) { IMyExstension ext = (IMyExtension)all.next(); ISafeRunnable runnable = new ISAfeRunnable() { public void handleException(Throwable exception){ all.remove(); } public void run() throws Exception { ext.execute(); //hívom az extensiont } }; Platform.run(runnable); } Csinálunk egy új burkoló-osztályt
Példa: ISafeRunnable for (Iterator all=getListeners().iterator();all.hasNext()) { IMyExstension ext = (IMyExtension)all.next(); ISafeRunnable runnable = new ISAfeRunnable() { public void handleException(Throwable exception){ all.remove(); } public void run() throws Exception { ext.execute(); //hívom az extensiont } }; Platform.run(runnable); } Aki hibázik, azt eldobjuk
Példa: ISafeRunnable for (Iterator all=getListeners().iterator();all.hasNext()) { IMyExstension ext = (IMyExtension)all.next(); ISafeRunnable runnable = new ISAfeRunnable() { public void handleException(Throwable exception){ all.remove(); } public void run() throws Exception { ext.execute(); //hívom az extensiont } }; Platform.run(runnable); } Meghívjuk az extension egyik metódusát
Példa: ISafeRunnable for (Iterator all=getListeners().iterator();all.hasNext()) { IMyExstension ext = (IMyExtension)all.next(); ISafeRunnable runnable = new ISAfeRunnable() { public void handleException(Throwable exception){ all.remove(); } public void run() throws Exception { ext.execute(); //hívom az extensiont } }; Platform.run(runnable); } Végrehajtjuk a runnable-t.
Csomagolás, publikálás • Ha készen áll a plugin-ünk a felhasználásra • Be kell csomagolni • Hangolni kell a plugin.xml opcióit • Telepítési cél • Saját gépünk • Más gépek • Automatikus telepítés/frissítés
Csomagolás, publikálás • Könyvtárak – library • A csomagolás első lépése • Osztályainkat jar fájlokba csomagtatjuk • Lehet bináris vagy forrás csomag • Megmondhatjuk, mely osztályok látszódhatnak kívülről • A kész libeket és egyéb fájlokat csomagolhatjuk össze az exporthoz • Lehet bináris és forrás bundle
Csomagolás, publikálás • Finomhangolás • Nem használt függőségek kiirtása • Automatikus ellenőrző eszközökkel • Plugin neve, készítő, … • Verziószám beállítása • Export • File -> Export -> Deployable plug-ins and fragments • Az eredmény egy könyvtár, ami tartalmazza a plugint.
Feature • Egy témához kapcsolódó plug-inek gyűjteménye • Könnyebb menedzselhetőség érdekében jött létre • Az automatikus letöltés és telepítés atomi egysége
Feature • Kiegészítő információk • License aggreement • License rule „always supply a license with every contribution” • Upgrade site-ok listája • Feature saját verziója • Szükséges pluginok verziója
Update site • Automatikusan létrehozott weblap • Feature-ök elhelyezésére • Publikálás • Letöltés • Upgrade • Lista az elérhető feature-ökről és verziókról • Megkönnyíti a szoftver elosztást
Eddig • Egyszerű plugin létrehozása • Kiterjesztések létrehozása • Kiterjesztési pontok létrehozása • Plugin csomagolás • Feature létrehozás • Update site
JUnit • Regressziós teszt keretrendszer • Erich Gamma és Kent Beck írta • Unit tesztelésre használatos Java-ban • Nyílt forráskódú • IBM CPL licensz alatt elérhető
JUnit • Web: http://junit.org/index.htm • Az Eclipse tartalmazza a JUnit-ot • GUI-t is kínál a tesztek futtatásához • Eclipse-n kívül is futtathatóak a tesztek
Eclipse - JUnit • A JUnit beállítása a Preferences ablakban lehetséges • Általában jók az alapbeállítások • Szűrőket lehet megadni, hogy mely csomagok és osztályok jelenjenek meg a stack trace-ben
TestCase - teszteset • Több tesztet is futtathat • A TestCase osztályból származik • Definiálja, hogy mely tagváltozók tartalmazzák a teszt állapotát az osztályon belül • Inicializálás a setUp metódussal • Takarítás a tearDown metódussal
TestCase készítése • Csináljunk egy új osztályt a project-ben • Adjuk hozzá a junit.jar-t a függőségekhez
TestCase létrehozása • Kiválasztjuk a csomagot, ahova a tesztet rakni szeretnénk • A new menüből válasszuk a JUnit Test Case-t. • Elnevezzük, stb. • Egy megfelelő osztály létrejön
Példa: TestCase package com.espirity.course.testing; import junit.framework.TestCase; public class FirstTestCase extends TestCase { public FirstTestCase(String arg0) { super(arg0); } public static void main(String[] args) { } protected void setUp() throws Exception { super.setUp(); } protected void tearDown() throws Exception { super.tearDown(); } }
TestCase létrehozása • Minden „test”-tel kezdődő metódus tesztként lesz kezelve az osztályban • Sok teszt metódusunk lehet • Minden teszt metódus többféle „assert” metódust használhat, hogy a tesztelés alatt álló osztályok állapotát vizsgálja • Az assert metódusok öröklöttek
TestCase létrehozása • Assert • assertEqual(x,y) • assertFalse(boolean) • assertTrue(boolean) • assertNull(Object) • assertNotNull(Object) • asserSame(Object,Object) • assertNotSame(Object,Object)
Példa: TestCase package testing; import junit.framework.TestCase; public class FirstTestCase extends TestCase { public FirstTestCase(String arg0) { super(arg0); } public static void main(String[] args) {} protected void setUp() throws Exception { super.setUp(); } protected void tearDown() throws Exception { super.tearDown(); } public void testCompareSucceed() { assertEquals(0, 0); //this assertion will succeed } public void testCompareFail() { assertEquals(0, 1); //this assertion will fail }}
TestCase futtatása • Válasszuk ki az osztályt • Run -> Run as -> JUnit Test • Lefutnak a tesztek • Az eredmény a JUnit view-ban jelenik meg.
JUnit view • Információk • Piros/zöld a teszt eredménye hiba/ok • Látható a meghiúsult tesztek neve • Látható a hiba trace • Látható a lefutott tesztek száma • Látható a hibák száma
TestSuite • Több TestCase vagy Suite futtatása • A TestSuite osztályból örököltetjük • Létrehozás varázslóval… • File->New->Other…->Java->JUnit • A varázslóban válasszuk a JUnit Test Suite opciót • Megadhatjuk a résztevő Case-eket
Példa: TestSuite packagecom.espirity.course.testing; importjunit.framework.Test; public classAllInclusiveTestSuite { public staticTest suite() { TestSuite suite = newTestSuite("Test for com.espirity.course.testing"); //$JUnit-BEGIN$ suite.addTestSuite(FirstTestCase.class)); suite.addTestSuite(SecondTestCase.class)); //$JUnit-END$ returnsuite; } }
TestSuite futtatás • Hasonló a TestCase-éhez • Minden megadott TestCase lefut • A JUnit ablak tartalmazza az eredményeket • Fontos: TestSuite is adható TestSuite-hoz!
PDE JUnit • JUnit támogatás plug-in fejlesztéshez • A sima JUnit nem használható • Nem Workbench-ben fut • Az Eclipse plug-inok nem leérhetőek • PDE JUnit • Külön futtatási mód
Plugin futtatás Alap Eclipse, ezen dolgozunk
Plugin futtatás Projectek a workbench-ben
Plugin futtatás Ha plugint futtatunk egyúj Eclipse példány indul
Plugin futtatás Betöltődik a plugin-unk
Plugin futtatás Külön workspace látszik
Plugin teszt futtatás Teszt projekt a workspace-ben
Plugin teszt futtatás A teszt is betöltődik, valamint a teszt futtató
PDE JUnit működés • Írunk egy tesztet (ugyanúgy, mint alapesetben) • Futtatjuk JUnit Plug-in Test-ként • Egy Eclipse ablak nyílik, majd a tesztek lefutása után bezáródik • A teszteredményt a szokásos ablakban találhatjuk meg
PDE JUnit működés • Hol legyenek a tesztek? • Lehet a tesztelendő plug-inban is • De! • A JUnit függőségeket be kell építeni • Keveredik a kód és a teszt • Tegyük külön plug-inba, ami könnyen leválasztható • Ez függ az eredeti plug-in-től
Mit teszteljünk? • Nyilván csak a meghajtható részek (API) tesztelhető • Nincs lehetőség közvetlen GUI tesztre • Rational Robot • Amit tesztelni szeretnénk, látható kell legyen • Erősen függ a konkrét plug-intól
View • Általános információ-megjelenítő elem • Extension point: • org.eclipse.ui.views • If: IViewPart • Sokféle lehetőség van információ megjelenítésére • Tartalmazhat SWT és JFace elemeket is