login  Naam:   Wachtwoord: 
Registreer je!
 Forum

PHPUNIT

Offline finduilas - 01/12/2014 21:05
Avatar van finduilasPHP gevorderde De laatste tijd probeer ik het Zend Framework wat uit. Ik heb ervaring met andere frameworks als codeIgniter.. Voorlopig vind ik Zend wat omslachtig. Maar dat is waarschijnlijk het begin ;)..

Bij Zend wordt er heel veel gebruik gemaakt van unittesting. Ik heb er wat over gelezen. Maar ik heb het nog niet helemaal door hoe ik het moet gebruiken. Ook hier lijkt het weer wat omslachtig.

Nu wil ik wel eens weten wie van jullie aan unittesting doet, en of er iemand een eenvoudig voorbeeld in mensentaal kan formuleren ;). Het lijkt nu voorlopig gewoon wat extra werk...

7 antwoorden

Gesponsorde links
Offline Wijnand - 02/12/2014 08:50
Avatar van Wijnand Moderator Wij gebruiken het hier niet, maar ik heb mij wel eens ingelezen in wat het doet, maar het komt er op neer dat je de method's die je gebruikt met de queries en dergelijke kunt testen. Als je dus een code-fout maakt, en je hebt het niet goed getest, dan kan die testunit dit aangeven.

Ik zelf heb het nooit goed in werking gezien, dus eigenlijk kan ik er weinig over delen.
Offline Sitebase - 02/12/2014 10:21
Avatar van Sitebase PHP expert Bij unit testen ga jij eigenlijk kijken dat de uitkomst van een bepaalde functie is wat je verwacht. Om een heel simpel voorbeeld te geven:

Als je een functie "sum" hebt ga je kijken als je 4 en 5 meegeeft als argumenten, de functie 9 terug geeft.

In het begin lijkt het schrijven van unit tests inderdaad omslachtig en puur tijdverlies, maar geloof mij, dat is het niet.

Om een overzichtje te geven van voordelen:

Fouten worden sneller gevonden
Doordat je fouten in je code sneller gaat vinden gaan ze ook minder tijd innemen om op te lossen. Je unit tests zullen je ongeveer al gaan aangeven in welke bepaalde functie er een probleem zit.

Op deze manier los je heel veel bugs al op voor het in productie komt te staan. Klanten zullen dus minder last van bugs in je software hebben.

Refactoren zonder mogelijke problemen
Je kan je code naar hartelust refactoren want je unit tests checken toch automatisch of alles nog werkt als daarvoor.
Als je geen unit tests hebt is refactoren een hel.

Bugs van andere teamleden
Onze projecten zijn zo opgezet dat als iemand zijn code naar Github pushed dat deze dan automatisch worden geunittest. Als er dan problemen in die code zitten krijg degene die deze code gepushed heeft meteen een mailtje dat hij zijn code moet fixen.
Op deze manier kom ik niet in de problemen door buggy code van een collega te gebruiken.

Betere code
Dit is nog een zeer belangrijk voordeel aan unit testen van je code. Je gaat betere code schrijven!
In het begin als je start met unit testen dan ga je vaak hebben dat je denkt dat je code niet te unit testen is. Dit is meestal een teken dat je slechte code hebt geschreven. Eén van de grootste oorzaken hiervan is veel te veel code in één method willen proppen.


Hopelijk zijn de voordelen van unit testen een beetje duidelijker nu.
Bedankt door: finduilas
Offline finduilas - 02/12/2014 11:07
Avatar van finduilas PHP gevorderde Alvast bedankt voor je reactie..

Wat ik er uit begrijp is dat je eigenlijk dus je methods test.. Moet je dan steeds alle mogelijkheden opgeven bij voorbeeld een method sum? Of doet dit het automatisch? Ik denk maar aan "foutieve data" van de gebruiker.. Een string bijvoorbeeld?

Is er iemand die een voorbeeld kan geven?
Offline Sitebase - 02/12/2014 12:19 (laatste wijziging 02/12/2014 12:19)
Avatar van Sitebase PHP expert Ik heb even een voorbeeldje op github gezet:

https://gist.gi...8bed139285
Bedankt door: finduilas
Offline Thomas - 02/12/2014 15:42
Avatar van Thomas Moderator En wat nu als je unittest niet klopt of op een andere manier "de lading niet dekt", Who Watches the Watchers
Naar aanleiding van het gegeven voorbeeld: daar wordt is_int() gebruikt. Die controle is misschien al te streng in een taal als PHP, deze functie kijkt namelijk naar het type van je variabele. Als bijvoorbeeld je input uit een formulier komt dan hang je al, tenzij je deze evalueert met filter_ functies, die typen lijken te converteren als de validatie slaagt (oorspronkelijk is alle data uit $_POST, $_GET etc. van het type string, dus dan levert is_int() false op). Tenzij je applicatie dus niet een dergelijke "type awareness" heeft is deze test niet geschikt. En misschien zoek je je dan een ongeluk naar waar de fout zit.

Het probleem is een beetje dat de meerwaarde van unittesting waarschijnlijk lastig te illustreren valt met een triviaal voorbeeld.

Ik heb zelf ook nooit gebruik gemaakt van unittesting eerlijk gezegd.

Een interessante vraag (naast "Wat is unittesting") is wellicht "Wanneer zet ik unittesting in?" (wanneer heeft dit meerwaarde). Dit lijkt mij namelijk geen doel an sich, maar een middel om een doel te bereiken. Als je een groter (en complex?) project hebt waar meerdere mensen aan werken dan kan dit meerwaarde hebben.

Vergelijk het met een stuk gereedschap. Je gebruikt (als je verstandig bent) geen hamer om een schroef de muur in te krijgen. Je hebt een bepaalde klus en om die te klaren gebruik je bepaalde stukken gereedschap. Unittesting is zo'n stuk gereedschap, maar is niet per definitie het beste (of enige) gereedschap voor de klus.

Citaat:
Eén van de grootste oorzaken hiervan is veel te veel code in één method willen proppen.
En unittesting kan een middel zijn die je dwingt om hier van weg te sturen. Maar het achterliggende principe hiervan is toch gewoon het single responsibility principe? Ik denk dat je ook al een heel eind komt als je de achterliggende principes kent en toepast.

Het lijkt mij niet dat je unittesting zou moeten gebruiken als een soort van keurslijf? Of misschien wel? Wordt je code dan echt altijd "beter" (ook uit oogpunt van OOP)? Of "beter afgestemd op unittests"? Wordt code daarmee dan altijd beter? That would be cool.

Voorwaar, slechte code met een bijbehorende unittest bestaat niet, toch? 
Offline Sitebase - 02/12/2014 16:27 (laatste wijziging 02/12/2014 16:28)
Avatar van Sitebase PHP expert Als het "de lading niet dekt" dan is dat meestal een eigen keuze. Je kan een coverage test runnen samen met je unit tests en die gaat je perfect kunnen zeggen welke lijnen code niet getest werden door jouw unit tests.

Die is_int is helemaal niet te streng, parse gewoon je variable naar een int voor je ze doorgeeft aan de functie en er is geen probleem. Bijvoorbeeld:

  1. echo sum((int)"6", (int)"9");


Dit is nu net de grote oorzaak dat veel programmeurs het niet zo voor PHP hebben, gebrek aan consistentie. Je zou inderdaad de sum functie string argumenten kunnen laten accepteren, maar hiermee maak je alleen je documentatie en implementatie van de sum functie moeilijker en minder consistent.
Het enige wat je moet doen is duidelijke documentatie geven en in dit geval is dat heel simpel. Je kan 2 argumenten meegeven en ze moeten beide een integer zijn.

Maar dat terzijde, want we zijn een beetje off-topic aan het gaan.

Single responsibility principe is inderdaad één van de dingen die ik bedoel, maar het is niet omdat je de theorie kent dat je deze ook toepast. Wij werken hier vaak met heel getalenteerde programmeurs en master studenten die hun theorie kennen, maar deze in de praktijk totaal niet toepassen.

Ik ben er van overtuigd dat je code er beter van wordt gebaseerd op zowel eigen ervaring en op de vooruitgang die stage studenten bij ons maken.

Uiteraard ga je niet bij elk type project unit tests schrijven. Ik denk maar aan een landingspagina of een gewone website waar dit in veel gevallen overkill is.
Maar als je bijvoorbeeld een CMS, backend systeem, library of zo aan het schrijven bent is het een must.

Wij gebruiken persoonlijk hier op het bedrijf nooit libraries in onze code waarbij geen unit tests geschreven zijn. Het gevaar op bugs en problemen is daarbij veel te groot.
Offline Thomas - 02/12/2014 17:39
Avatar van Thomas Moderator
Citaat:
parse gewoon je variable naar een int voor je ze doorgeeft aan de functie en er is geen probleem
Typecasting lijkt mij (mogelijk) een (nog) slecht(er) idee. Daarmee wordt een poging gedaan om een variabele om te zetten naar een type, terwijl het niets weg hoeft te hebben van dat type.

Voorbeeld:
(int)"aap"

lolwut

Dat lijkt mij niet het idee van (en ga je helemaal voorbij aan) input filtering (nog zo'n principe).

Gebruik dan een regexp of dwing inderdaad af dat je invoer echt een integer is.

/offtopic
Gesponsorde links
Je moet ingelogd zijn om een reactie te kunnen posten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.185s