Archief voor de ‘Open Source’ Categorie

De Browser-Back Button

18 18 2008

De Browser-Back knop op internetschermen is een zege voor de eindgebruiker en een nachtmerrie voor de webapplicatie-bouwer. De eindgebruiker is er blij mee, omdat hij altijd naar een vorige situatie terug kan. De bouwer is er niet blij mee, want met deze knop verliest hij de controle op de volgorde van te bezoeken webpagina’s.

Bovendien heeft de Browser-Back button een zusje: de Browser-Forward button. En richten verschillende browsers het gedrag van de Browser-Back knop verschillend in.

Hieronder beschrijven we welke concepten we hebben gebruikt om de Browser-Back button op te vangen in een webapplicatie met een flexibele workflow. Onze oplossing is gebouwd in Java, maar de concepten zullen ook in andere programmeeromgevingen bruikbaar zijn. Wij hebben onze oplossing toegepast in een adresboek ontwikkeld voor een Onderzoeksbureau van de Rijksoverheid. Voor het toevoegen van een nieuwe medewerker moeten de volgende stappen doorlopen worden.

  1. Voer naw gegevens van de medewerker in
  2. Voeg de medewerker toe aan 1 of meer categorien
  3. Controleer de gegevens van de nieuwe medewerker
  4. Voeg de gegevens toe aan de database
  5. Meld dat de actie is uitgevoerd

De invoer van de gegevens gebeurt met jsp’s. Een jsp wordt voorafgegaan door een Access-servlet, waarin autorisaties worden geverifieerd en helpers worden gevuld. Deze helpers worden gebruikt om de informatie in de jsps te tonen, en te zorgen dat de jsps niet te complex worden. De oplossing om de Browser-Back button op te vangen maakt gebruik van:

  1. Cookies om de ingang van de jsp via de Access files te garanderen
  2. een server-worker pattern voor hergebruik van de code
  3. Een stack met variabelen voor het bewaren van scherminvoer

Cookies
Wanneer de eindgebruiker op de Browser-Back toets klikt, dan gaat de browser terug naar de vorige pagina. Deze vorige pagina kan de jsp zijn, of de Access voorafgaand aan de jsp. Dit is afhankelijk van de instellingen van de browser, i.e. dit wordt buiten de applicatie-code geregeld. Om te garanderen dat jsps altijd via de bijbehorende Access file benaderd worden, zetten we de cookie “entrypage” in de Access file. De eerste actie bij binnenkomst van de jsp is het verwijderen van de cookie. Als de jsp vervolgens benaderd wordt zonder de Access uit te voeren, dan wordt eerste de Access-page uitgevoerd, en daarna de jsp.

Deze techniek is ontwikkeld op basis van diverse engels-talige bijdragen en voorbeelden die over dit onderwerp op internet te vinden zijn.

Cookies moeten op de goede plek in de hierarchie ingezet worden. Met de Webdeveloper plugin van de firefox browser kun je eenvoudig controleren of de cookies juist in de hierarchie worden geplaatst.

Service-to-Worker pattern
Het Service-to-Worker pattern is een elegante manier om workflows te bouwen en tegelijk het aantal servlets en access-classes te beperken. Bij het Service-to-Worker pattern worden de functionaliteit en de volgorde van de stappen van elkaar gescheiden. Je krijgt dus een bestand met stap-volgordes, in ons geval een xml bestand. Een regel in het xml-bestand bestaat uit een start-status, een doel-status en een actie. Wanneer de applicatie in start-status is, dan gaat hij naar doel-status na het succesvol uitvoeren van de actie. Wij hebben deze techniek gehaald uit:

J2EE Design Patterns, William Crawford and Jonathan Kaplan, O’Reilly, 2003

Doordat de functionele classes en jsps geen workflow informatie bevatten kun je ze op verschillende plekken in verschillende workflows hergebruiken. Hergebruik komt de kwaliteit en de onderhoudbaarheid van de software ten goede.

Maar omdat de functionaliteit en de workflow van elkaar gescheiden zijn, staat in de jsps niet meer aangegeven wat de volgende stap is. Dat is geen probleem wanneer de jsps in volgorde achter elkaar worden uitgevoerd, dan is immers het xml-bestand met de stap-volgordes leidend. Maar dat is wel een probleem wanneer een eindgebruiker op de Browser-Back of de Browser-Forward klikt. Dan wijzigt de eindgebruiker de volgorde van stappen buiten het xml-bestand om.

Onze oplossing is een link te bouwen tussen de jsps en het xml-bestand met stapvolgordes. Deze link is de naam van de jsp, die een jsp altijd zelf kan bepalen., en die overeenkomt met een start-status in het xml-bestand. Zo kan de web-applicatie altijd dynamisch bepalen wat de volgende stap is en welke stap dan uitgevoerd moet worden.

De search-stack
Door ervoor te zorgen dat een jsp altijd voorafgegaan wordt door een Access pagina, kan informatie die de eindgebruiker handmatig op een scherm invoert verloren gaan. Om de eindgebruiker beter van dienst te zijn bewaren we in een stack de laatste keuzes van de eindgebruiker.

Essentieel in de stack is het veld entrypage. In dit veld staat de naam van de Accessfile waarmee de jsp benaderd wordt. Bij binnenkomst zoekt de Accessfile het stackitem met de juiste naam en haalt de meest recente gegevens uit dit stackitem.

In de stack wordt en teruggezocht en vooruitgezocht. In die zin is het niet een echte stack. Bij het uitvoeren van een actie vanaf een pagina midden in de stack worden de items boven deze plek uit de stack gehaald.

Samenvatting
Omdat de Browser-Back knop zoveel waarde heeft voor de eindgebruiker moet deze button in een webapplicatie beschikbaar blijven. Wij gebruiken in onze applicaties een combinatie van:

  1. Cookies, om af te dingen dat jsps altijd benaderd worden vanuit de Access file
  2. Een Service-to-Worker pattern met als status de jsps om hergebruik van code te bevorderen
  3. Een stack om de laatste invoer van de eindgebruiker te bewaren

Let op: wellicht zijn cookies niet nodig, en kun je de binnenkomst van een jsp via de Access file afdwingen met zgn filters. Als jij daar ervaring mee hebt, of als je andere verbeteringen in deze aanpak ziet, dan stel ik een reactie op prijs.

Sophie Fischer
Sponiza !T
www.sponiza.nl
www.etikettenprinten.nl

Selenium: automatisch testen webtoepassingen

10 10 2007

Het testen van nieuwe of gewijzigde software is een belangrijke, maar ook een tijdrovende klus. In deze bijdrage laten we zien hoe de testsoftware Selenium het uitschrijven van testgevallen overbodig maakt, zodat ontwikkelaars en eindgebruikers hun energie kunnen besteden aan de kwaliteit van de testgevallen. Deze bijdrage is bedoeld voor ontwikkelaars en – wat betreft de minder technische secties – eindgebruikers van webtoepassingen.

Aanleiding
Een grote uitdaging bij het ontwikkelen van software is het effectief en efficient testen van die software. Eindgebruikers waarderen foutloze software enorm. Maar testen is ook kostbaar. Tijdens een test dien je voor alle mogelijke voorkomende situaties na te gaan of de software zich juist gedraagt.

Dat “alle mogelijke voorkomende situaties” is de bottleneck tijdens het testen. Want stel dat 2 personen een jaar lang 24 uur per dag, 7 dagen mogen testen, en stel dat een test 5 minuten duurt. Dan kunnen max 2 * 12 * 24 * 365 = 210.240 testgevallen uitgevoerd worden.

Dat lijkt veel. Voor software-producten, die met de hand getest worden, zal het uitvoeren van 210.240 testen in de praktijk onhaalbaar zijn. Maar dat is het niet. Om een eenvoudig webformulier met 10 velden, waarbij ieder veld 6 keuze-mogelijkheden heeft, volledig te testen, zijn 1.000.000 (10*10*10*10*10*10) testgevallen nodig. Bovendien moet na iedere wijziging in de software het hele pakket opnieuw getest worden.

Omdat volledig testen geen optie is, proberen wij met geautomatiseerd testen en het opbouwen van een vaste verzameling met testsituaties de kwaliteit van de test en daarmee van onze producten te verbeteren.

Automatiseren testen
Het automatiseren van testen is niet nieuw: er bestaan verschillende software-pakketten die het automatisch testen van software ondersteunen. Commerciele pakketten zoals Tmap en Testrunner. Maar ook OpenSource varianten. Wij hebben zelf een hele tijd gebruik gemaakt van HttpUnit, een extensie van het veel-gebruikte jUnit.

Hoe werkt dat, een automatische testtool? Voor onze webtoepassingen maken wij scripts waarmee wij de mogelijke acties van eindgebruikers simuleren. Een script om in te loggen bijvoorbeeld, dat bestaat uit de volgende stappen:

1. open de login pagina
2. vul de gebruikersnaam in in het veld voor de gebruikersnaam
3. vul het wachtwoord in in het veld voor het wachtwoord
4. druk op de knop met het woord login
5. controleer dat je op de pagina Afspraken Overzicht bent gekomen

of, als voor het testen van de reactie op een verkeerd wachtwoord:

1. open de login pagina
2. vul de gebruikersnaam in in het veld voor de gebruikersnaam
3. vul het wachtwoord in in het veld voor het wachtwoord
4. druk op de knop met het woord login
5. controleer dat er een foutmelding verschijnt met de mededeling dat er een verkeerd wachtwoord is ingevuld

Het maken van dit soort testen is tijdrovend, maar als ze er eenmaal zijn, dan leveren ze veel tijdbesparing op. De zgn ReturnOnInvestment is enorm.

Vaste verzameling representatieve testgevallen
Omdat het niet haalbaar is alle testgevallen uit te voeren, is het zinvol om te bepalen welke testgevallen in ieder geval wel uitgevoerd moeten worden. Bijvoorbeeld testgevallen die de beveiliging testen, testgevallen die de meest voorkomende handelingen van eindgebruikers testen en testgevallen voor situaties die na analyse van de programma-code tot problemen kunnen leiden.

In de loop van tijd kan de verzameling representatieve testgevallen uitgebreid worden. Bijvoorbeeld wanneer de eindgebruiker een fout meldt, dan kan na het oplossen van de fout een testgeval worden gemaakt die test die de gemelde fout niet meer voorkomt. Dit is erg belangrijk voor de klantbeleving.

Waarom een alternatief voor HttpUnit
Wij hadden goede successen met HttpUnit voor onze online agenda en het internet-adresboek, maar het lukte ons niet onze nieuwste roostertoepassing met automatisch volledig te testen. Hier zijn 2 redenen voor. Ten eerste is rooster-software veel complexer dan agenda en adresboek-software. Ten tweede maken wij gebruik van Javascript om de toepassing gebruikersvriendelijker te maken. Het lukte ons niet de JavaScript met HttpUnit te simuleren. Dus zijn wij op zoek gegaan naar een nieuwe, automatische testtool voor webtoepassingen, en wij hebben een oplossing gevonden in Selenium van www.thinkworks.com. Selenium downloaden kan van de website http://www.openqa.org/selenium.

Het product Selenium – de Core
Het product Selenium bestaat uit verschillende onderdelen, waarvan wij nu de onderdelen Selenium Core gebruiken en Selenium IDE. De kern van de Selenium testsoftware is de Selenium Core. Deze core bestaat uit een verzameling voorbeeld-testgevallen. deze voorbeeld-testgevallen zijn de basis voor de eigen testgevallen.

<tr>
<td>open</td>
<td>http://192.168.0.10:8080/login.jsp</td>
<td></td>
</tr>
Deze testcase opent een loginpagina. De derde parameter is leeg.

<tr>
<td>type</td>
<td>USERID</td>
<td>s.fischer@mijnbedrijf.nl</td>
</tr>
Met deze testcase wordt ingelogd.

In het algemeen geldt dat de eerste kolom de actie bevat, de tweede kolom de locatie en de derde kolom de waarde. Een actie kan een actie van een eindgebruiker zijn, zoals open pagina, tik een waarde in of klik op een link. Maar een actie kan ook een verifieer-actie zijn, zeer belangrijk als je wilt verifieren dat een bepaalde foutmelding wordt getoond. De tweede kolom kan bijvoorbeeld een URL zijn, zoals http://192.168.0.10:8080/login.jsp, een invoer-veld, zoals USERID of een DOM-referentie. De derde kolom mag leeg zijn. Dus een algemene testcase is

<tr>
<td>action</td>
<td>location</td>
<td>value</td>
</tr>

De tweede kolom mag overigens ook leeg zijn, zoals in het voorbeeld:
<tr>
<td>goBackAndWait</td>
<td></td>
<td></td>
</tr>
waarmee het klikken op de Vorige-toets in een browser-window wordt gesimuleerd.

Erg krachtig is het aanroepen van test-bestanden in een soort super-test-bestand. Daarmee is het mogelijk uitgebreidere testen te splitsen en op te slaan in handzame delen. Bovendien is het mogelijk een conditie toe te voegen aan het <tr> element van de testcase zodat testen afhankelijk van het browser-type worden uitgevoerd. Bijvoorbeeld: <tr unless=”browserVersion.isKonquerer”> voert een test uit tenzij er met de Konquerer browser gewerkt wordt.

Het valideren van het testresultaat
Een testgeval behoort naast de acties ook een beschrijving te hebben van het verwachte resultaat. Selenium kan het controleren van de verwachte resultaten automatisch uitvoeren. Hiervoor bestaan bijvoorbeeld de commando’s verifyTextPresent en verifyText. De verifyTextPresent controleert of een tekst, bijvoorbeeld een foutmelding of een toegevoegd item, op het scherm voorkomt. De verifyText controleert of een bepaald element (link, button) op het scherm voorkomt. De controle-stappen voor het valideren van de testresultaten moeten handmatig in de test worden geplaatst.

Het product Selenium – IDE
Selenium – IDE is een plugin en om deze te gebruiken is Firefox 1.5.8 of hoger nodig. Na installatie van deze versie kan de Selenium – IDE automatisch geinstalleerd worden vanaf de website. De plugin is vervolgens beschikbaar onder Tools.

Voordeel: Met Selenium – IDE hoef je geen testgevallen meer in de omgeving van de applicatie-server te plaatsen.

De Selenium – IDE biedt een opname mogelijkheid voor het uitvoeren van testen op dezelfde manier waarop je vroeger muziek op een casette opnam, en je nu macro’s in Excel kunt opnemen.

Hiermee wordt het mogelijk om gebruikers-gedrag te simuleren. Want gebruikers voeren niet de velden op een scherm in de juiste volgorde en met de goede waarden in. Ze openen een scherm, komen er achter dat ze niet over de juiste informatie beschikken, gaan terug naar eerdere pagina’s met de browser-vorige-knop en vergeten vervolgens een veld. Dit gedrag kan nu opgenomen worden en later weer worden afgespeeld.

Wij zijn bij het opnemen van de testen de volgende zaken tegengekomen:
- Wanneer wij een link op een ander frame aanklikken, dan wordt er een actie click in het testbestand gezet. Dit zou naar onze mening clickAndWait moeten zijn, net zoals dat gebeurt bij links op hetzelfde frame. Wij adviseren het testbestand door te lopen en click te vervangen door clickAndWait.
- De browser-backtoets wordt niet gesimuleerd. Deze teststap goBackAndWait zal apart moeten worden toegevoegd.

Troubleshooting en documentatie
Een nadeel van testen met Selenium is dat het niet snel duidelijk is welk object, zij het een window, formulier, frame, enz, centraal staat. Zo zijn wij nogal wat tijd kwijt geraakt omdat we 2 frames dezelfde naam hadden gegeven. Het eerste frame met de naam bevatte geen links, het tweede frame bevatte wel links. Tot vervelends toe meldde de test dat een link niet bestond, en wij hadden geen mogelijkheid om te zien waar de tool aan het zoeken was.

Een tweede reden waardoor een link niet gevonden kan worden is bij het zoeken niet gewacht wordt totdat de pagina volledig geladen is. Zelf maken de Selenium testcases veelvuldig gebruik van het commando clickAndWait en selectAndWait. Dat betekent dat het script op een link klikt en wacht totdat de resulterende pagina geladen is. Bij de commando’s click en select gaat het script meteen door, en zal links niet kunnen vinden als die nog niet opgehaald zijn.

De documentatie is niet goed, niet duidelijk en onvolledig. Maar er zijn zoveel testvoorbeelden met aansprekende titels, en er is een goed forum met een goede zoekfunctie. Een avondje puzzelen en je kunt ermee aan de gang.

Tot slot
Welke methoden gebruikt u om te controleren of software aan uw wensen voldoet? Maakt u gebruik van handmatige of automatische testen? Kende u Selenium al? Zo ja, wat is uw ervaring met Selenium RC? Zo nee, denkt u dan dat u Selenium gaat gebruiken in de nabije toekomst?

Sophie Fischer
www.sponiza.nl
www.etikettenprinten.nl

Is gratis software iets voor jou?

13 13 2006

Het mag dan gratis zijn, Linux, en veilig, en stabiel, overstappen op Linux betekent zelf hardware kopen, zelf installeren en zelf vragen stellen aan Linux goeroes op het internet. Voor de niet-technisch geinteresseerde computer-gebruiker lijkt Microsoft dan zoveel aantrekkelijker. Iedereen gebruikt het, het ziet er gelikt uit, je koopt een computer met Microsoft al voor 500 euro bij Dell. Die ook nog thuis wordt bezorgd.

Maar wat zie je op veel van deze computers:

1. Virusscanners, omdat de computers bedolven worden onder allerlei virussen, trojaanse paarden en internet-wormen. Er zijn testen die aantonen dat een nieuwe computer aangesloten op het internet binnen 20 minuten zijn eerste virussen te pakken heeft. Een Linux computer is minder bevattelijk, beter te beschermen en er zijn diverse gratis virusscanners op de markt.

2. Een mengeling aan legale en illegale software. Microsoft Word is misschien legaal. Maar Excel? Of Powerpoint? Of Photoshop? Terwijl illegale software op je computer strafbaar is. Bij Linux betaal je niet voor de software of het gebruik van de software, en kent geen betaalde licenties.

3. Tijdverlies bij het opnieuw installeren van je computer of een programma. Waar was die installatie-cd met certificatie-key ook maar weer? Voor een Linux computer kun je software zonder kosten of certificatie-keys van het internet halen en gebruiken.

4. Wat als je meer wilt met je computer? Een stamboom van je familie maken? Foto’s en films bewerken? Websites ontwerpen? Offertes en contracten omzetten in PDF-formaat? Met een Linux computer heb je toegang tot een scala aan gratis software voor allerlei hobbies en werkzaamheden. Eventueel huur je iemand in die op afstand de software op jouw computer plaatst en beheert. Daar betaal je voor, maar voor de commerciële software varianten betaal je ook, die je dan zelf moet onderhouden.

Vergelijk het met koken en uit eten gaan. Je eigen eten koken heeft veel voordelen. Het is goedkoop. Het is gezond en veilig. Op het internet kun je een heleboel recepten vinden. Voor lastige sauzen en curries koop je een basismix in de winkel. Maar zelf koken kost wel tijd en je hebt er vaardigheden en creativiteit voor nodig. Het alternatief is uiteten gaan. Een traktatie, maar je zit wel vast aan de openingstijden, het menu en de hygiëne van het restaurant.

Misschien is het toch de moeite waard eens uit te zoeken of een Linux computer beter aansluit op jouw wensen en werkzaamheden.