Kihagyás

Unit és integrációs tesztelés

JUnit

A JUnit 5 egységteszt keretrendszerrel fogunk megismerkedni. Ehhez először nézzünk egy problémát.

A probléma

Hajókra tervezünk ütközéselkerülő rendszert. A rendszer alapja, hogy a saját hajó navigációs radarja érzékeli a másik hajó relatív helyzetét és relatív haladási irányát. A helyzet egy x,y koordinátapár, ahol az y tengely a hajó haladási irányával párhuzamos (a haladási irány felé pozitív), az x tengely pedig arra merőleges (haladási iránytól jobbra pozitív), és a koordináta rendszer origójában van a saját hajó. A másik hajó relatív haladási irányát fokban kapjuk meg (ez egy 0-359 közötti szám: 0 ha párhuzamosan azonos irányba; 90 ha merőlegesen jobbról balra; 180 ha párhuzamosan de ellentétes irányba; 270, ha merőlegesen balról jobbra halad). Ebből a rendszer kiszámolja a két hajó útvonalának mettszéspontját.

Ezután a rendszer a saját hajó haladási sebességből és hosszából kiszámolja, hogy mikor (milyen időintervallumban) fog ezen a ponton áthaladni előtte-utána 3-3 hajóhossz ráhagyással. Ez azt jelenti, hogy a saját hajó eleje mikor közelíti meg 3 hajóhossznyira a metszéspontot, és a tatja mikor hagyja el legalább 3 hajóhosszal (viszonyítási pontnak a saját hajó geometriai közepét tekintve).

Közben érzékeli a másik hajó folyamatosan sugárzott sebesség és hossz adatait, és azokkal is elvégzi a számolást. Ha a két hajó eltérő időintervallumban tartozkodik az adott helyen, akkor nincs baj.

Ha viszont a két időpont metszi egymást, akkor több lehetőség van. Ha a hajók haladási iránya legfeljebb 90 fokban tér el (azaz legfeljebb merőlegesen haladnak, de kicsit sem "egymással szemben"), akkor "a jobbról érkezőnek elsőbbsége van" alapon sebességcsökkentést javasol, vagy csak fokozott óvatosságra figyelmeztet. Ha viszont a két hajó kicsit is szemben halad egymással, akkor "a könnyebb hajó könnyebben menőverez" alapon javasol elkerülő manővert vagy fokozott óvatosságot. (A tömeg adatokat szintén folyamatosan sugározzák a hajók.)

A probléma, hogy az adatsugárzó rendszerek nem teljesen standardizáltak, ezért a sebesség, hossz és tömeg adatokat különféle hajók különféle mértékegységekben sugározhatják.

  • Hosszmérték
    • cm, m (100cm), km (1000m), in (2.54cm), ft (12in), yd (3ft), mile (1760yd), nm (1852m)
  • Tömeg
    • g, kg (1000g), t (1000kg), oz (28.34952g), lb (16oz)
  • Idő
    • s, m (60s), h (60m)
  • Sebesség
    • m/s, km/h, mi/h, knot (1 nm/h)

Egységtesztek

  1. Töltsd le az Eclipse projektet és csomagold ki
  2. Töltsd be Eclipse-be
    • File -> Open Projects from file system
    • File -> Import ... -> General -> Existing project into workspace
  3. Ship projektre jobb gombbal kattintás -> New -> Source folder -> Folder name: test
  4. test folderre jobb katt -> New -> Package -> Name: scws
  5. Package-re jobb katt -> New -> JUnit test case -> New JUpiter test bepipálva
    • Name -> UnitTests.java
    • Which method subs would you like to create? - Mind a négyet ki kell pipálni.
  6. Írjuk be az alábbiakat:
Helyes Unit teszt (a Time osztály as függvényét teszteli.)
1
2
3
4
5
6
@Test
    void testAsRelations() throws InvalidUnitException {
    assertEquals(1.0, new Time(   1.0, "s").as("s"));
    assertEquals(1.0, new Time(  60.0, "s").as("m"));
    assertEquals(1.0, new Time(3600.0, "s").as("h"));
}
Helytelen (bukó) unit teszt (a Time osztály as függvényét teszteli.)
1
2
3
4
5
6
@Test
void testAsRelationsBadExample() throws InvalidUnitException {
    assertEquals(1.0, new Time(   1.0, "s").as("s"));
    assertEquals(1.0, new Time(  59.9, "s").as("m"));
    assertEquals(1.0, new Time(3600.0, "s").as("h"));
}
  1. Ship projektre jobb katt -> Run As -> JUnit Test
  2. Láthatjuk, hogy egy passed és egy failed tesztünk van.
Feladat: egységtesztek

Készíts egységteszteket JUnit segítségével.

Mi a teszt futtatásának eredménye?

Sikerült-e a tesztek segítségével valamilyen hibát felfedezni?

Egységteszt hiba
  • Az AbstractUnit osztály int compareTo(T) metódusa hibás

Integrációs tesztek

  1. Package-re jobb katt -> New -> JUnit test case -> New JUpiter test bepipálva
    • Name -> IntegrationTests.java
    • Which method subs would you like to create? - Mind a négyet ki kell pipálni.
  2. Írjuk be az alábbiakat, majd futtassuk le az előbb leírt módon
Helyes Integration test (hossz, idő és sebesség integrációja)
1
2
3
4
5
6
7
@Test
void testLengthPerTime() throws InvalidUnitException {
    assertEquals(new Speed(1.00, "m/s"), new Length(1.0, "m").div(new Time(1.0, "s")));
    assertEquals(new Speed(1.00, "km/h"), new Length(1.0, "km").div(new Time(1.0, "h")));
    assertEquals(new Speed(1.00, "mi/h"), new Length(1.0, "mi").div(new Time(1.0, "h")));
    assertEquals(new Speed(1.00, "knot"), new Length(1.0, "nm").div(new Time(1.0, "h")));
}
Feladat: integrációs tesztek

Készíts integrációs teszteket JUnit segítségével.

Mi a teszt futtatásának eredménye?

Sikerült-e a tesztek segítségével valamilyen hibát felfedezni?

Integrációs teszt hiba
  • A Length osztály távolságból és sebességből időt számoló metódusa rosszul működik.
  • A ShipCollisionWarningSystem osztály rosszul számolja meg ez "előtt" és "mögött" fogalmát.

Rendszertesztek

Bár a JUnit (és a hasonló keretrendszerek) alapvetően egységtesztek megírására lettek tervezve, ez nem jelenti azt, hogy nem lehet magasabb szintű teszteket automatizálni a segítségükkel.

Az algoritmus
  • Saját hajó (sebesség (V), hossz (L), tömeg (M), relatív irány 0 fok, relatív pozíció (0,0))
  • Másik hajó (sebesség (v), hossz (l), tömeg (m), irány (rd), relatív pozíció (dx,dy))

  • Másik hajó irány és pozíció adataiból számoljuk ki, hogy, hogy keresztezi-e a saját hajó útvonalát?

    • Ha a jobb oldalon (dx > 0) jobbra tart (0° ≤ rd ≤ 180°), vagy a bal oldalon (dx < 0) balra megy (180° ≤ rd ≤ 360°(=0°)) -- megengedve a párhuzamos haladást, most tekintsünk el a gömbfelszíntől --, akkor nem, tehát nincs figyelmeztetés.
  • Számoljuk ki az útvonalak metszéspontját:
    • A másik hajó v sebességét vx (nekünk merőleges) és vy (velünk párhuzamos) komponensekre kell felbontani:
      • vx = v * cos(90° - rd)
      • vy = v * sin(90° - rd)
    • vx-ből és dx-ből kiszámolható, hogy a másik hajó t = - (dx / vx) idő múlva keresztezi a saját hajó útvonalát
    • vy-ból, dy-ból és t-ből kiszámolható, hogy a másik hajó az Y = dy + vy * t helyen keresztezi a saját hajó útvonalát (X=0, mivel mi definíció szerint az y tengelyen haladunk)
  • Mikor ér a két hajó az útvonalak kereszteződéséhez?
    • A másik hajó az előbb kiszámolt t idő múlva
    • Mi T = Y / V idő múlva (V a sebességünk)
  • Ütközünk?
    • A másik hajó dt = 3.5 * l / v idővel a keresztezés előtt lép be, és ennyivel ez után lép ki a biztonságos zónából, vagyis [t-dt, t+dt] időintervallumban tartózkodik ott.
    • Hasonlóan, a saját hajó esetén ez dT = 3.5 * L / V, és [T-dT, T+dT] a keresett időintervallum.
    • Ha a két időintervallum nem metszi egymást, akkor nincs figyelmeztetés.
  • Ki tér ki?
    • Ha 270° ≤ rd ≤ 360° vagy 0° ≤ rd ≤ 90°, akkor
      • Ha dx > 0, a másik hajó mehet, a saját hajó lassít.
      • Ha dx < 0, a sajét hajó mehet (óvatosan), a másik hajó lassít.
    • Ha 90° < rd < 270°, akkor
      • Ha m > M, akkor a másik hajó mehet (óvatosan), és a saját hajónak kell manővereznie.
      • Ha M > m, akkor a saját hajó mehet (óvatosan), és a másik hajónak kell manővereznie.
Feladat: JUnit használata magasabb szintű tesztekhez

Készíts rendszerteszteket JUnit segítségével.

Mi a teszt futtatásának eredménye?

Sikerült-e a tesztek segítségével valamilyen hibát felfedezni?

Rendszerteszt hiba
  • Ha pont szemből jön a másik hajó, akkor lehet, hogy biztonságos oldaltávolság ellenére is figyelmeztetést kapunk.

Utolsó frissítés: 2021-10-26 09:36:16