Over Atos Origin
Contact
Diensten
Nieuws
Home
Feedback  |  Atos Origin.com  |  Syndicatie
Syndicatie
 
Links
Archief
Meer over de bloggers
Onderwerpen
Alle onderwerpen
Agile
Algemeen
Architectuur
Besturingssystemen
Bpm
Business intelligence
Business proces design
Cloud computing
Eai
Governance
Ibm
Integratie
It consultancy
Java
Microsoft
Nljug
Open source
Oracle
Process standaarden
Project management
Requirements engineering
Rich internet applications
Saas
Security
Sharepoint
Soa
Testing
Virtualisatie
Xml

Saneren: het nieuwe bouwen? Tools of the trade
Geplaatst op 11 February 2010, 15:44 door Arthur Amesz in java, open source, integratie, testing

Bij mijn huidige klant krijgt op dit moment het saneren van software prioriteit van de business. Hulde!

Hieronder beschrijf ik de context van dit saneren, geef ik vervolgens aan hoe jMeter en DbUnit worden gebruikt en geef daarna aan hoe unit tests voor batch jobs die een System.exit() uitvoeren kunnen worden opgezet.

Context

Jarenlang is gebruik gemaakt van een door de klant zelf ontwikkeld framework om een reeks van web applicaties te ontwikkelen. De kennis van het framework, van de gebruikte architectuur en van de specifieke applicaties ligt vooral vast in de hoofden van mensen. Mensen die inmiddels in het gunstigste geval nog wel bij de klant betrokken zijn (hoewel vaak in andere functies). Maar die vaak ook niet meer bij dezelfde organisatie werkzaam zijn.

Omdat de architectuur, het framework en de applicaties niet of nauwelijks zijn gedocumenteerd ontstaat een steeds grotere uitdaging. Die alleen aan de oppervlakte komt als er problemen zijn met de applicaties of als ze aangepast moeten worden, bijvoorbeeld om wijzigingen in wettelijke bepalingen door te voeren.

Daarom is besloten om het gebruikte framework sterk te vereenvoudigen en de applicaties overeenkomstig aan te passen. Hierdoor is voortaan minder kennis van het framework nodig, lijken de applicaties meer op andere applicaties van de klant en kunnen zij op de 'standaard' manier worden gedeployed op 'standaard' servers (het deployen was een zeer specifieke aangelegenheid en leidde tot serverprocessen die op specifieke servers draaiden). Tenslotte is voor elke applicatie tenminste beschreven hoe deze lokaal gedeployed en getest kan worden. Al met al leidt dit ertoe dat veel minder specifieke (schaarse) kennis nodig is.

Alleen de interne werking van de applicaties is aangepast: de functionaliteit moet 100% hetzelfde blijven. Daarom was het belangrijk om regressietests uit te voeren, die kunnen aantonen dat op alle (OTAP-) omgevingen de applicatie hetzelfde gedrag vertoont. Door een noodzakelijke aanpassing in het framework kon het verder voorkomen dat applicaties hun resources niet meer correct beheerden, wat alleen bij intensief gebruik tot problemen zou leiden. Om intensief gebruik te simuleren, is gebruik gemaakt van loadtests.

jMeter

Voor het uitvoeren van de regressie- en loadtests is gebruik gemaakt van jMeter. Hiermee kan worden gesimuleerd dat meerdere gebruikers tegelijkertijd dezelfde requests afvuren, waardoor een goed beeld ontstaat van het gedrag van de applicatie onder een zware load. Hoewel de handleiding van het opnemen van tests (http://jakarta.apache.org/jmeter/usermanual/jmeter_proxy_step_by_step.pdf) aangeeft dat het opnemen van (secure) https requests niet direct wordt ondersteund, blijkt dit toch gewoon te werken met de standaard jMeter installatie. Een geruststellende constatering toen bleek dat de applicaties op de meeste omgevingen alleen secure te benaderen waren!

Naast deze web applicaties, moest ook een batch applicatie worden aangepast. Voor de batch applicatie waren geen unit tests geschreven en de applicatie maakte gebruik van een sterk verouderde database. Om toch te kunnen testen of wijzigingen in de applicatie de functionaliteit niet aantastten, is besloten om eerste een aantal unit tests te schrijven.

DbUnit

Omdat de functionaliteit van de batch applicatie vooral bestaat uit het ophalen en wijzigen van gegevens in een database, is besloten om gebruik te maken van DbUnit (http://www.dbunit.org/). Hiermee kan worden bereikt dat voor unit tests de database steeds dezelfde, zelf gedefinieerde inhoud heeft. Hiermee ben je dus niet meer afhankelijk van een database met testgegevens die een, mogelijk ook nog eens per omgeving wisselende, variabele inhoud kunnen hebben. In plaats daarvan zorg je voor een kleine, speciaal voor jouw unit tests geschikte set van gegevens. De database waar gebruik van wordt gemaakt is HSQLDB (http://hsqldb.org/), een in memory database.

Als je voor een unit test de org.dbunit.DatabaseTestcase class wilt extenden (zoals je bij een reguliere unit test de junit.framework.Testcase zou extenden), dien je twee methodes te implementeren.

De eerste geeft een database connectie terug. Hierin kun je bijvoorbeeld een connectie opvragen bij de in memory HSQLDB database en kun je create scripts uitvoeren, die ervoor zorgen dat de tabellen die je later wilt vullen beschikbaar zijn.
 


De tweede geeft een dataset terug: deze bevat de initiële vulling van de database. Bijvoorbeeld in de vorm van een XML file. De documentatie (http://www.dbunit.org/components.html) vermeldt "To specify null values, omit corresponding attribute.". Dit blijkt echter niet altijd te werken. Als je bijvoorbeeld een DATETIME kolom null will laten zijn, leidt dat tot een exceptie bij het uitvoeren van de unit test. In plaats daarvan dien je dan ook expliciet de waarde "<null/>" te gebruiken.

Een tabel 'mijnTabel' met twee kolommen 'mijnOmschrijving' en 'mijnDatum', heeft bijvoorbeeld de volgende xml dataset om de inhoud van de tabel te beschrijven:



in plaats van:



Unit tests en System.exit()

De te testen batch applicatie kent verschillende batch stappen. Elke stap eindigt (of de stap nou succesvol was of niet) met het aanroepen van System.exit(exitCode), waarbij een exitCode wordt meegegeven, die aan de aanroepende partij teruggeeft of de batch stap al dan niet succesvol was.

Het aanroepen van System.exit() heeft normaal gesproken echter tot gevolg dat de JVM wordt gestopt. Zonder speciale voorzorgsmaatregelen kan een unit test die zo'n batch stap aanroept dus nooit slagen. Daarom wordt een class aangemaakt die de standaard lava.lang.SecurityManager extend.

Deze class kan er bijvoorbeeld als volgt uitzien (met excuses voor de met opzet erg sobere javadoc):



Deze gebruikt op zijn beurt een eigen ExitException, die de standaard java.lang.SecurityException extend:



 
Een unit test krijgt vervolgens de volgende member, die de oorspronkelijke SecurityManager vasthoudt voor de duur van de unit test:



Deze wordt in de setUp() gezet:



 
En in de tearDown() wordt de oorspronkelijke security manager weer teruggezet:




Een batch step kan in een unit test bijvoorbeeld op de volgende manier worden aangeroepen:




Op deze manier is ervoor gezorgd dat de unit test gewoon doorloopt op het moment dat de aangeroepen batch step System.exit() aanroept en kunnen asserts worden uitgevoerd op de waarde die bij de aanroep van System.exit() wordt meegegeven.




Share this | 347 keer bekeken | 0 reacties
Reacties Syndicatie en RSS
Reageer
 
 
Top artikelen
  • J-Spring 2009:Hop on board the Java Troubleshooting Platform
  • Softwaredocumentatie met Sandcastle
  • Agile Springboard
  • Blik op kwaliteit door middel van Six Sigma
  • Developers zijn kikkers
Recente reacties
  • IDC voorspelt dat SaaS mainstream wordt binnen paar ...
  • PrimeFaces is nauwelijks nog bekend terwijl het veel ...
  • Dank!
  • Het bijwerken is met behulp van if(contains()) remove() ...
  • Alleen keuren de bovengenoemde alternatieven duplicate entries af ...
  • Terms of use
  • Legal