feige sein! testen im java-ee-umfeld
DESCRIPTION
GEDOPLAN-Vortrag zum Thema Unit Tests, Multi Unit Tests und Integration Tests insbesondere für Anwendungen auf Basis der Java EE. (www.gedoplan.de)TRANSCRIPT
![Page 1: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/1.jpg)
Feige sein!
Testen im EE-Umfeld
Dirk Weil, GEDOPLAN GmbH
![Page 2: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/2.jpg)
Dirk Weil
GEDOPLAN GmbH, Bielefeld
Java EE seit 1998
Konzeption und
Realisierung
Vorträge
Seminare
Veröffentlichungen
2 Feige sein!
![Page 3: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/3.jpg)
Testen
3 Feige sein!
Bei mir läuft's!
Dafür haben wir
kein Budget.
Gestern ging‘s
noch (und ich hab‘
nix gemacht).
Wir haben
keinen
Testserver
EE-Tests sind zu
aufwändig.
![Page 4: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/4.jpg)
Testen
4 Feige sein!
Testen ist feige!
… dann lassen Sie uns feige sein!
![Page 5: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/5.jpg)
EE-Tests
Komplexe Komponenten-Landschaft
CDI / EJB
@Inject, @Produces, @Alternative …
Plattform
@PersistenceContext, @Transactional, …
Web
@Named, @XyzScoped, @Path
5 Feige sein!
![Page 6: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/6.jpg)
real
embedded
SE-Test
Was und wie schnell?
6 Feige sein!
Ausf
ühru
ngsz
eit
Testtiefe
Unit
Test
Multi Unit
Test
Integration
Test
Einzelklasse Komponente
Subsystem
Anwendung
Service
(inkl. Umgebung)
In-Container-Test
![Page 7: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/7.jpg)
Beispielprojekt
7 Feige sein!
WaehrungRepository
WaehrungService
WaehrungModel
+ Views
WaehrungRestService
BestellungRepository
ArtikelRepository
ShopModel
+ Views
Artikel
Bestellung
Waehrung
Bestell-
Position
EntityManager / PU TX Manager
![Page 8: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/8.jpg)
Unit Test
Test: Umrechnung in WaehrungService
Mock für WaehrungRepository
Toolset: JUnit, Mockito
8 Feige sein!
WaehrungRepository
WaehrungService Waehrung
![Page 9: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/9.jpg)
Unit Test
9 Feige sein!
@Stateless @LocalBean
public class WaehrungService implements WaehrungServiceRemote
{
@Inject
WaehrungRepository waehrungRepository;
public BigDecimal getTauschkurs(String waehrungId)
{
Waehrung waehrung = waehrungRepository.findById(waehrungId);
public class WaehrungServiceUnitTest
{
@BeforeClass
public static void beforeClass()
{
repository = Mockito.mock(WaehrungRepository.class);
Mockito.when(repository.findById("USD")).thenReturn(USD);
service = new WaehrungService();
service.waehrungRepository = repository;
}
Mock-Objekt vorbereiten
„Injektion“
![Page 10: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/10.jpg)
Multi Unit Test
Test: Umrechnung in WaehrungService
Test-DB statt Prod-DB
Toolset: JUnit, CDI-Container
alternativer Producer für EntityManager
TX-Interceptor
10 Feige sein!
WaehrungRepository
WaehrungService Waehrung
EntityManager / PU TX Manager
![Page 11: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/11.jpg)
Multi Unit Test
Apache
DeltaSpike
Container-
Start
Kontext-
Start
Injektion
in unmanaged
Objects
public class WaehrungServiceMultiTest { private static CdiContainer cdiContainer; @BeforeClass public static void beforeClass() { cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); cdiContainer.getContextControl().startContexts(); } @Before public void before() { BeanProvider.injectFields(this); } @Inject WaehrungService waehrungService;
![Page 12: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/12.jpg)
Multi Unit Test
Mocking – the CDI way
(1: Alternative)
12 Feige sein!
public class EntityManagerProducer
{
@PersistenceContext(unitName = "seminar")
@Produces
private EntityManager entityManager;
} @Alternative @Priority(1)
public class TestEntityManagerProducer
{
EntityManagerFactory emf;
@PostConstruct
private void postConstruct()
{
emf= Persistence.createEntityManagerFactory("test");
}
@Produces
EntityManager createEntityManager()
{
return emf.createEntityManager();
Mock-Objekt
nur im
Test-Classpath
![Page 13: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/13.jpg)
Multi Unit Test
Mocking – the CDI way
(2: Interceptor)
13 Feige sein!
@Transactional
public class WaehrungRepository
{
public void persist(Waehrung entity)
{
this.entityManager.persist(entity);
@Interceptor @Priority(Interceptor.Priority.APPLICATION + 1)
@Transactional
public class TestTransactionInterceptor
{
@Inject
EntityManager entityManager;
@AroundInvoke
Object manageTX(InvocationContext invocationContext) throws Exception
{
this.entityManager.getTransaction().begin();
Mock-Objekt
nur im
Test-Classpath
![Page 14: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/14.jpg)
Testdaten-Bereitstellung
Bulk Load
Skript, DBUnit, …
Manuell
Prod Extract, …
Anwendungs-API
EntityManager, XyzRepository
14 Feige sein!
<waehrung
id="USD">
…
>import 2013-11-07.dump
![Page 15: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/15.jpg)
Testdaten-Bereitstellung
Daten vor dem Test löschen …
höhere Komponenten zuerst
… und neu laden
niedere Komponenten zuerst
Daten nach Test stehen lassen!
Lässt sich gut mit CDI implementieren
(Testdaten-Lader wiederum nur im Test-Classpath)
15 Feige sein!
![Page 16: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/16.jpg)
Integration Tests
Test in Java EE Server
Test von Komponenten
inkl. der davon genutzten Schichten
Zugriff auf alle Java-EE-Ressourcen
„echte“ Persistence Unit (mit Test-DB)
„echter“ Transaction Manager
Toolset: JUnit, Arquillian, EE Server
16 Feige sein!
![Page 17: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/17.jpg)
Arquillian
Server Lifecycle (Start/Stop)
Erstellung von Deployment Archives
Deployment (+Undeployment)
Integration mit JUnit und TestNG
Testausführung
Server: White Box Test
Client: Black Box Test
Diverse Erweiterungen
17 Feige sein!
![Page 18: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/18.jpg)
18 Feige sein!
Arquillian
Server starten Archiv erstellen und deployen
Tests durchführen
Archiv undeployen
Server stoppen weitere
Testklasse?
Remote Mode Managed Mode
![Page 19: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/19.jpg)
Arquillian
Container-Wahl durch Classpath
verfügbare Container:
https://docs.jboss.org/author/display/ARQ/Container+adapters
19 Feige sein!
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<profiles>
<profile>
<id>astest_wildfly-8.0-managed</id>
<dependencies>
<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
![Page 20: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/20.jpg)
Arquillian
JUnit Testrunner
Deployment mit ShrinkWrap erstellen
neuen Archivnamen nutzen (z. B. UUID)
richtige Endung!
20 Feige sein!
@RunWith(Arquillian.class)
public class WaehrungServiceIntegrationTest
{
@Deployment
public static WebArchive createDeployment()
{
WebArchive archive = ShrinkWrap.create(WebArchive.class, deploymentUnitName + ".war");
archive.addClasses(…);
archive.addAsWebInfResource(…);
archive.addAsResource(…);
archive.addAsLibraries(…);
![Page 21: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/21.jpg)
Arquillian
White Box Test
@Deployment(testable=true) (Default)
Testklasse wird mit deployt
@Inject etc. nutzbar
21 Feige sein!
@RunWith(Arquillian.class)
public class WaehrungServiceIntegrationTest
{
…
@Inject WaehrungService waehrungService;
@Test
public void testUmrechnenUSD()
{
…
BigDecimal actual = this.waehrungService.umrechnen(fremdBetrag, fremdWaehrungId);
Assert.assertEquals("Euro-Betrag", expected, actual);
![Page 22: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/22.jpg)
Arquillian
White Box Test
Passend erstelltes Deployment
angepasste PU-Definition
22 Feige sein!
WaehrungRepository
WaehrungService Waehrung
EntityManager / PU TX Manager
![Page 23: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/23.jpg)
Arquillian
White Box Test
23 Feige sein!
Archiv erstellen
- Benötigte Anwendungsdateien
- ggf. spezielle Testartefakte
(z.B. persistence.xml)
- Testklasse inkl. Dependencies
(automatisch per testable=true)
Testergebnisse einsammeln
Testlauf abschließen
Archiv deployen
Tests ausführen
Archiv undeployen
Client Server
![Page 24: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/24.jpg)
Arquillian
Black Box Test
@Deployment(testable=false)
Test läuft im Client
(IDE, Jenkins, etc.)
Zugriff nur Remote
z. B. EJB per Remoting
z. B. RESTful Service via JAX-RS Client
24 Feige sein!
@RunWith(Arquillian.class)
public class WaehrungServiceRemoteIntegrationTest
{
@Deployment(testable = false)
public static WebArchive createDeployment()
{
@RunWith(Arquillian.class)
public class WaehrungRestServiceIntegrationTest
{
@Deployment(testable = false)
public static WebArchive createDeployment()
{
![Page 25: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/25.jpg)
Arquillian
Black Box Test
25 Feige sein!
Archiv erstellen
- Benötigte Anwendungsdateien
- ggf. spezielle Testartefakte
(z.B. persistence.xml)
Tests ausführen
Testlauf abschließen
Archiv deployen
Archiv undeployen
Client Server
remote
![Page 26: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/26.jpg)
Drone
Arquillian-Erweiterung für Selenium
Browser-Fernsteuerung
Drone übernimmt Lifecycle-Steuerung des ggf. nötigen Browsers
@Drone injiziert WebDriver (=Fernsteuerung)
Browser wählbar via arquillian.xml
Firefox, Crome, IE, HtmlUnit, PhantomJS, …
häufig per Maven-Profil
26 Feige sein!
![Page 27: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/27.jpg)
Drone
27 Feige sein!
WaehrungRepository
WaehrungService
WaehrungModel
+ Views
EntityManager / PU TX Manager
Waehrung
![Page 28: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/28.jpg)
28 Feige sein!
Drone
@RunWith(Arquillian.class)
public class WaehrungGuiIntegrationTest
{
…
@Drone WebDriver webDriver;
@Test
public void testUmrechnenUSD()
{
…
this.webDriver.get(serverUrlWebContext + "/demo/waehrungsrechner.xhtml");
WebElement fremdBetragField = this.webDriver.findElement(By.id("form:fremdBetrag"));
fremdBetragField.clear();
fremdBetragField.sendKeys(fremdBetrag.toString());
…
WebElement umrechnenButton = this.webDriver.findElement(By.id("form:umrechnen"));
umrechnenButton.click();
WebElement euroBetragField = this.webDriver.findElement(By.id("form:euroBetrag"));
String actual = euroBetragField.getText();
Assert.assertEquals("Eurowert", expected, actual);
![Page 29: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/29.jpg)
Drone
Grey Box Test
Web GUI Fernbedienung wie zuvor
Abfrage des serverseitigen Zustands
z. B. mittels Remote EJB
29 Feige sein!
@RunWith(Arquillian.class)
public class ShopGuiIntegrationTest
{
@Test
public void testCreateBestellung()
{
…
this.webDriver.get(serverUrlWebContext + "/demo/waehrungsrechner.xhtml");
…
ShopGuiIntegrationTestInspectorRemote inspector
= ServiceLocator.getEjb(ShopGuiIntegrationTestInspectorRemote.class, …);
Assert.assertTrue("Bestellung nicht gespeichert",
inspector.checkBestellungExists(expected));
![Page 30: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/30.jpg)
Arquillian Extensions
30 Feige sein!
Persistence Initialisierung, Validierung und Cleanup
der Datenbank
JaCoCo Code Coverage Monitoring
Performance Prüfung der Ausführungszeit
Warp Grey Box Testing mit Drone
Graphene Selenium-Erweiterung u. a. mit AJAX-
Unterstützung und JQuery-Selektion
…
![Page 31: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/31.jpg)
Arquillian Experience
Mächtiges Werkzeug
Dokumentation je nach Extension sehr gut bis nicht vorhanden
Aufwändige Konfiguration
JAR-Hölle
Ausführungsgeschwindigkeit
31 Feige sein!
![Page 32: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/32.jpg)
Links
Beispielprojekt
https://github.com/dirkweil/feige-sein
Arquillian
http://arquillian.org/
Arquillian Testing Guide
http://www.packtpub.com/arquillian-testing-guide/book
32 Feige sein!
![Page 33: Feige sein! Testen im Java-EE-Umfeld](https://reader033.vdocuments.mx/reader033/viewer/2022052900/555e5870d8b42ad74a8b5279/html5/thumbnails/33.jpg)
More
Seminare zum Thema, z. B.
Java Software Testing
http://www.gedoplan-it-training.de
http://www.gedoplan-it-consulting.de
http://javaeeblog.wordpress.com/
http://expertenkreisjava.blogspot.de/
@dirkweil
34 Feige sein! [email protected]