Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
Unit-Tests für JBF-Services
Gert Lormes, AEW6TA | JBFOne 2009
2
Ziel dieses Vortrags Sensibilisierung für Unit-Tests von Serverkomponenten Vorstellung der Framework-Unterstützung für Transaction Services (TSe) Hinweise für Data Services (DSe) Hinweise für Application Services (ASe) Wartbarkeit von Tests und Codeabdeckung
3
Agenda Motivation Transaction Services HDS und HcRuntime Data Services
Application Services Qualität von Unit-Tests
4
Agenda Motivation Transaction Services HDS und HcRuntime Data Services
Application Services Qualität von Unit-Tests
5
Warum überhaupt den Server testen?
Serverkomponenten haben einen höheren Qualitätsanspruch Server ist kritischer als Client werden oft von mehreren Clientkomponenten genutzt Bediener kann keine Fehler umgehen Serverkomponenten leben typischerweise länger als Clientkomponenten haben damit auch längere Wartungsintervalle Investitionen in Wartbarkeit lohnen sich (noch) mehr
6
Warum den Server nicht einfach über den BAP testen?
Client Code ist eventuell noch nicht fertig Aufwand zur Durchführung zu hoch: Tomcat starten, Anmeldung, … zu viele Abhängigkeiten es ist sehr schwer, die Testumgebung passend zum Test aufzusetzen nicht alle Testfälle sind über Service-Schnittstelle ausführbar Asserts sind über Service-Schnittstelle nicht ausreichend möglich Regressionstests praktisch nicht möglich Tests müssen Standalone als Unit-Tests laufen!
7
Was testen wir am Server
Datenbankzugriffe Data Services Hostzugriffe Transaction Services Business-Logik Application Services DSe, TSe und ASe sind eigene Einheiten (= Units) und deshalb natürliche Kandidaten für Unit-Tests
8
Forderungen: Tests sollen …
automatisiert und schnell laufen (Regressionstests) wenn möglich, isoliert laufen bei DB-Zugriffen ist das möglich IMS-Transaktionen??? eine hohe Aussagekraft haben mit vernünftigem Aufwand erstellbar sein gut wartbar sein „iMove-kompatibel“ sein
9
Ablaufumgebung Test mit BAP Entwicklertest BAP Eclipse Test- treiber
Tomcat AS TS DS DS TS
10
Zu beachten Frameworkunterstützung erforderlich! ClientContext
Preferences Configuration Controlapi … Leider können sich die Details mit jedem JBF-Release ändern Frameworkunterstützung erforderlich!
11
Agenda Motivation Transaction Services HDS und HcRuntime Data Services
Application Services Qualität von Unit-Tests
12
Basics: ein TS … public class MyRequest implements Serializable {...}
public class MyResponse implements Serializable {...} public class MyTs extends AbstractTS { public AttributeList invoke(AttributeList attRequest) { // auspacken DefaultServiceRequest dsRequest = (DefaultServiceRequest) AbstractApplicationService.getRequestFromAttributeList(attRequest)); MyRequest request = (MyRequest) dsRequest.getData(); // erstelle InputMessages, rufe Host-Tx, erstelle Response aus OutputMessages MyResponse response = ...; // einpacken DefaultServiceResponse dsResponse = new DefaultServiceResponse(response); AttributeList attResponse = AbstractApplicationService. getResponseAsAttributeList(dsResponse); return attResponse; } }
13
… und ein rufender AS public class MyAs extends AbstractService implements ServiceCommand { … MyRequest request = ...; ServiceRequest dsRequest = new DefaultServiceRequest("TsName", request); ServiceResponse dsResponse = super.executeTransactionService(dsRequest); MyResponse response = (MyResponse) dsResponse.getData(); ... } AbstractService.executeTransactionService() verpackt den DefaultServiceRequest in eine AttributeList ermittelt aus dem Namen (hier: "TsName") und der Datei <xxxHostObject.ini> die TS-Klasse instanziiert den TS und ruft ihn auf packt aus der AttributeList den DefaultServiceResponse aus Das ist im Test nachzubilden!
14
Idee eines Testtreibers
public class MyTest extends TestCase { public void testCase1() { MyRequest request = new MyRequest(); // request initialisieren … MyTs ts = new MyTs(); String tsName = "TsName"; MyResponse response = (MyResponse) execute(request, ts, tsName); // und hier kommen die asserts ... } public void testCase2() {…} private Serializable execute(Serializable request, AbstractTS ts, String tsName) { DefaultServiceRequest dsRequest = new DefaultServiceRequest(tsName, request); AttributeList attRequest = AbstractApplicationService.getRequestAsAttributeList(dsRequest); AttributeList attResponse = ts.invoke(attRequest); DefaultServiceResponse dsResponse = (DefaultServiceResponse) AbstractApplicationService.getResponseFromAttributeList(attResponse); return dsResponse.getData();
15
Aber … So einfach geht das leider nicht, denn …
dieser Test wird scheitern wegen Anmeldung Konfiguration Datenbankverbindungen Technische User …
16
… deshalb Unterstützung aus dem Framework
AbstractImsconTestCase extends TestCase { … } mit JBF 7.15 (BAP 4.0) verfügbar enthält die bereits gezeigte execute-Methode stellt in setUp() die benötigte Umgebung her räumt in tearDown() wieder auf
17
Funktionierender Testtreiber
public class MyTest extends AbstractImsconTestCase { // setUp() und tearDown() sind optional; wenn vorhanden, // müssen sie als Erstes bzw. Letztes ihre super-Methoden rufen! protected void setUp() throws Exception { super.setUp(); … } protected void tearDown() throws Exception { super.tearDown(); public void testCase() { MyResponse response = (MyResponse) super.execute(request, ts, tsName); ...
18
AbstractImsconTestCase – 1
baut in jedem setUp() den ClientContext auf ruft dazu getRzbkForTest(), getUseridForTest() und getBedienernrForTest() diese haben Defaults, können aber überschrieben werden außerdem im Angebot: overwriteClientContext(String userid, String bedienernr) überschreibt die GENO Userid und die Bedienernummer RZBK bleibt z. B. für Testfälle im Zusammenhang mit dem 4-Augen-Prinzip stellt in jedem tearDown() den alten ClientContext wieder her Integration in Baselibs geplant Kontextdaten in local.setup.properties
19
AbstractImsconTestCase – 2
allgemeine JBF-Einstellungen: diese sind für alle Arten von Standalone Unit-Tests erforderlich: System Properties für diverse Factories einige weitere Einstellungen Einstellungen für ImsConnect: diese sind speziell zum Test für TSe erforderlich Sicherstellen, dass die Implementierung „JBFImsConnect“ benutzt wird Setzen eines Default-Loggers Setzen einer Default-Konfiguration für IMSU (normalerweise wird die Konfiguration mittels Steuer-API aus Oracle gelesen)
20
Agenda Motivation Transaction Services HDS und HcRuntime Data Services
Application Services Qualität von Unit-Tests
21
HcRuntime oder HDS? Standalone Tests waren bisher nur mit HcRuntime möglich dazu wurde ein Test-Jar aus CBx benutzt (template-service-test) die Test Cases mussten sich von HcStandaloneTestCase ableiten dahinter lief bereits ein einfacher ImsConnect Client in Java ab Jetzt können (fast) alle IMS-Transaktionen unabhängig von der Implementierung des TS standalone getestet werden Ausnahmen: 3-stellige Transaktionscodes in BAP 4.0: einige weitere Sonderfälle, z.B. NIB-Transaktionen
22
Testtreiber für HcRuntime
Zusatzanforderung bei HcRuntime: Request und Response sind Interfaces erben von HcRequest oder HcResponse deshalb: Erzeugen einer Request-Instanz über BeanImplProvider public interface MyRequest extends HcRequest {…} public interface MyResponse extends HcResponse {…} public class HcRuntimeTestSample extends AbstractImsconTestCase { public void testCase() { MyRequest request = (MyRequest) BeanImplProvider. createImplementationFor(MyRequest.class); // request initialisieren … MyTs ts = new MyTs(); MyResponse response = (MyResponse) super.execute(request, ts, "TsName"); // asserts … } }
23
Anwendungsfall: Migration von HDS nach HcRuntime
HcRuntime ist das offizielle Framework der FIDUCIA zur Implementierungen von TSen performant Anwendungen sind einfach zu entwickeln und zu warten Unterstützung von Redefines, Occurs usw. Viele TSe sind aber noch in HDS (oder anderen Techniken) implementiert Umstellung auf HcRuntime war bisher sehr riskant, da kaum testbar (never change a running system) dieses K.o.-Kriterium entfällt jetzt
24
Testen bei der Migration von HDS nach HcRuntime
Erstelle neue Request- und Response-Interfaces, die strukturell den Request- und Response-Klassen der alten Implementierung gleichen (Eclipse: „Refactor / Extract Interface…“) von HcRequest oder HcResponse erben bringe ausreichend viele Testfälle für die alte Implementierung zum Laufen Positiv- und Negativ-Fälle berücksichtigen hohe Codeabdeckung erzielen Erstelle neue Implementierung mit HcRuntime Die Testfälle sind für beide Implementierungen verwendbar
25
Migration von HDS nach HcRuntime: Muster
interface NewRequest extends HcRequest {…} interface NewResponse extends HcResponse {…} class OldRequest implements Serializable, NewRequest {…} class OldResponse implements Serializable, NewResponse {…} Alte Implementierung: arbeitet unverändert mit OldRequest, OldResponse Neue Implementierung: arbeitet mit NewRequest, NewResponse Test Cases: arbeiten mit NewRequest, NewResponse Ausnahme: Instanziierung mit „new OldRequest()“ statt mit BeanImplProvider TS-Klasse über Factory erzeugen einfaches Umschalten alt / neu
26
Agenda Motivation Transaction Services HDS und HcRuntime Data Services
Application Services Qualität von Unit-Tests
27
Test von Data Services JBFOne 2007
Unit-Tests entwickeln und Testabdeckung messen in HORIZON-Projekten Data Services sollen in einer isolierten Umgebung getestet werden eigenes Schema benutzen für jeden Testfall exakt die benötigten Daten einstellen Helperklassen liegen (noch) in horizonbaseutils setUp- und tearDown-Code sowie Asserts gehören nicht in die Transaktionsklammer des Data Services
28
Test von Data Services Implementierung von setUp-Code
alles muss lesbar im Java Code stehen pro Testcase exakt die benötigten Daten einstellen keine Excel-Files verwenden „zu Fuß“ über JDBC Fachlicher Code Delegation an Helperklassen mit sprechenden Klassen- und Methodennamen kein „Verstecken“ im setUp() der eigenen Klasse oder gar von Oberklassen Fingerspitzengefühl erforderlich beim Abwägen zwischen Auscodieren im Testcase Nachteil: Code-Duplizierung Test wird evtl. zu lang und unübersichtlich Delegation an Helpermethoden Nachteil: Transparenz kann verloren gehen aussagekräftige Namen verwenden, z.B. erstelleKontoOhneIndividualKonditionen()
29
Agenda Motivation Transaction Services HDS und HcRuntime Data Services
Application Services Qualität von Unit-Tests
30
Application Services Wichtig Tests für ASe testen den AS-Code
die TSe und DSe sind (hoffentlich) schon getestet!!! Korrektheit von serviceRegistry und ServiceDeskriptoren testen? dafür sind keine eigenen Unit-Tests erforderlich Tool vorhanden (Sotograph) Viele Application Services sind trivial sie rufen nur einen TS oder DS auf sie geben den Client Request 1:1 an diesen weiter für diese Application Services reicht jeweils ein Unit Test
31
Application Services Komplexer werden Tests für ASe, wenn
mehrere TSe und DSe aufgerufen werden zusätzlich ASe aus anderen Modulen aufgerufen werden (z.B. CBx, Kunde, …) Business-Logik enthalten ist Was soll getestet werden? die eigene Business-Logik Die Ergebnisse der Aufrufe an TSe, DSe, andere ASe müssen dazu reproduzierbar sein Test-Dubletten verwenden!? Leider: für den Test von ASen gibt es noch keine Best Practices
32
Agenda Motivation Transaction Services HDS und HcRuntime Data Services
Application Services Qualität von Unit-Tests
33
Qualität von Unit Tests
Es genügt nicht, dass die Unit-Tests im Eclipse grün sind! Qualitätskriterien sind hohe Codeabdeckung ausreichend viele assert-Statements korrekte assert-Statements Wartbarkeit der Tests Ob ausreichend viele und korrekte assert-Statements codiert sind, lässt sich kaum messen Produktspezialisten einbeziehen Aber: zur Messung der Codeabdeckung gibt es Werkzeuge In mehreren Projekten eingesetzt: Cobertura
34
Was ist Cobertura? Cobertura ist ein freies Java-Tool das die Codeabdeckung von Java-Programmen durch Tests misst Features instrumentiert den Java Bytecode berechnet die prozentuale Abdeckung von Codezeilen und von Branches berechnet die McCabe-Metrik (= zyklomatische Komplexität) erzeugt HTML Reports, über die bis auf Quellcode-Ebene navigiert werden kann per Konfiguration können Packages oder Klassen von der Messung ausgenommen werden (z. B. generierte Klassen, Testklassen) Nutzen Cobertura hilft bei der Identifikation von Programmteilen, die nicht durch Tests abgedeckt werden Toter Code? fehlende Tests?
35
Cobertura Report – Projekt- und Package-Ebene
36
Cobertura Report – Klassenebene
37
Wartbarkeit von Unit-Tests
Unit-Tests machen eine erhebliche Menge des Gesamtcodes aus (50% !?) ihre Erstellung kostet erheblichen Aufwand gute Wartbarkeit ist ein Muss Maßnahmen Zusammenfassung zu Suites rekursiv eine Top-Level Suite pro Produkt oder Komponente diese (und nur diese) als Launcher mit sprechendem Namen in SVN einchecken Tests müssen schnell laufen (im Sekundenbereich) vor jedem nichttrivialen SVN-Commit laufen lassen keine harten Abhängigkeiten zu Userids, DB-Instanzen, … keep it simple – Lesbarkeit ist höchstes Gebot keine eigenen Frameworks und Klassenhierarchien bauen keine 80%-Bedürfnisse in setUp() und tearDown() legen – lieber delegieren keine Excel-Tabellen für setUp() – alles in den Code
38
Zusammenfassung Serverkomponenten haben einen hohen Qualitätsanspruch
Dieser kann nur mit Standalone Unit-Tests erreicht werden Für Transaction Services ab JBF 7.15 / BAP 4.0 möglich Für Data Services schon länger Test von Application Services muss noch besser unterstützt werden Codeabdeckung kann mit Cobertura gemessen werden Übergabekriterium zwischen AEW3 und AEW4/AEW5?
39
Fragen? – Diskussion? Gert Lormes
Anwendungsentwicklung Technische Architektur 0721/
40
Ihr IT-Partner Vielen Dank
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.