[alg] Hoe zwaar testen jullie?

Pagina: 1 2 Laatste
Acties:
  • 704 views sinds 30-01-2008
  • Reageer

  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
EfBe schreef op 30 mei 2004 @ 15:50:
Debuggen != testen
Testen is semantics testen. Debuggen is het vinden van fouten, dus wanneer je al hebt geconstateerd dat je programma een fout bevat.
Leuk die definities, maar precies waarom is het gebruik van een debugger om variablen te bekijken evil? Als cout << "userKey: " << userKey << " serverSlot: " serverSlot << endl; enz enz... wel mag, waarom mag ik dan niet via mijn debugger kijken wat die variablen als waarden hebben? Je zou kunnen zeggen dat de debugger voor mij, in dit geval, de universele cout is mbt het weergeven van variabelen.

Testen is een zeer breed begrip. Als ik snel wil testen of na een loop variable X de gewenste waarde heeft, waarom zou ik dan niet na de loop een breakpoint zetten om te controleren of dat klopt? -Mag- dat van jou alleen dmv een cout?

Als ik wil testen of mijn datastructuur correct is opgebouwt in het geheugen, waarom zou ik deze dan niet in de debugger inspecteren?

Ik denk, beste Efbe, dat jij je te zeer vastpint op de naam die het beestje heeft: Debugger roept bij jou (mischien) een verkeerde associatie op. Voor mij is een debugger niet alleen een middel om te debuggen, maar ook een tool om de state van mijn code op een bepaald soort manier te visualiseren, om mezelf in inside-look te geven. Een semantische test kan daar mee samen vallen, of kan dat niet. Dat hangt van de code in kwestie af.

Testen gaat in verschillende fasen, van de schets op papier van een algortime, via een compile (maakte ik geen syntax fouten), via een -snelle- test-run, via een -snelle- inspectie van de state, via unit testen, via code reviews, via acceptence & QA tests, tot en met de praktijk test.

Mischien ben jij, Efbe, zoiemand die van die dingen op zijn CV schrijft als "nauwkeurigheid: ik maak minder dan 0.01 fouten per 1000 regels" oid, maar in de praktijk gebruikt elke programmeur die ik ken een vorm van "cout" testen. Heck, in veel opensource code die ik lees staan de cout's of printf's nog gecomment. Ipv cout bekijk ik de waardes via een debugger. Ik jou ogen ben ik nu een slechte ontwikkelaar?
Laat me raden, jij bent zeker ook een voorstander van Edit & Continue?
Nee, nooit gebruikt en ben er ook geen voorstander van. Net zomin als ik er een voorstander van ben om tijdens debuggen waarden van variablen te veranderen.
Jij wel?

Maar laat mij ook eens raden, jij bent zeker een voorstander van formele correctheids bewijzen voor je gehele code? De pre-inspectie voer je uit over iedere regel code die je schrijft?

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
flowerp schreef op 30 mei 2004 @ 16:27:
[...]
Testen is een zeer breed begrip. Als ik snel wil testen of na een loop variable X de gewenste waarde heeft, waarom zou ik dan niet na de loop een breakpoint zetten om te controleren of dat klopt? -Mag- dat van jou alleen dmv een cout?

Als ik wil testen of mijn datastructuur correct is opgebouwt in het geheugen, waarom zou ik deze dan niet in de debugger inspecteren?

Ik denk, beste Efbe, dat jij je te zeer vastpint op de naam die het beestje heeft: Debugger roept bij jou (mischien) een verkeerde associatie op. Voor mij is een debugger niet alleen een middel om te debuggen, maar ook een tool om de state van mijn code op een bepaald soort manier te visualiseren, om mezelf in inside-look te geven. Een semantische test kan daar mee samen vallen, of kan dat niet. Dat hangt van de code in kwestie af.
Testen is niet hetzelfde als debuggen.
Met testen bepaal je of je code / module / method een fout bevat, en met debuggen kan je die fout in je code gaan opsporen.

Om te unit testen schrijf je 'testcode'. Code die je schrijft waarin je je methods aanroept, en daar dmv Asserts oid al aangeeft of de output correct is of niet. Met een testprogramma als NUnit kan je dan zien welke tests er goed en fout verlopen zijn.
Ipv cout bekijk ik de waardes via een debugger. Ik jou ogen ben ik nu een slechte ontwikkelaar?
Dat heeft helemaal niks met een goeie of slechte ontwikkelaar te maken. Iedereen bekijkt die variabelen zoals hij het zelf wil. Soms kan je het doen via watches, soms via console - outputs.
Ik vind het wel slordig om die statements in je code te laten staan.

[ Voor 9% gewijzigd door whoami op 30-05-2004 16:50 ]

https://fgheysels.github.io/


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
whoami schreef op 30 mei 2004 @ 16:48:
[...]

Testen is niet hetzelfde als debuggen.
Dat klopt :) Maar je kunt een debugger wel gebruiken voor een snelle test. Net zoals je cout voor een snelle test gebruikt. Klopen de waardes/gedrag niet? Dan ga je echt debuggen.
Dat heeft helemaal niks met een goeie of slechte ontwikkelaar te maken. Iedereen bekijkt die variabelen zoals hij het zelf wil. Soms kan je het doen via watches, soms via console - outputs.
Ik vind het wel slordig om die statements in je code te laten staan.
Nou, terwijl ik aan het ontwikkelen ben laat ik wel eens wat statements staan, maar volgens mij doet iedereen dat wel. Ik zag dat bij mede-studenten, ik zie het bij collega's en ik zie het in opensource projecten. Bij code cleanups gaan al zulksoort dingen eruit. Alarmnummer merkte terrecht op dat je dan je test-code kwijt ben, en daar ben ik het zeer mee eens.

Het enige wat ik wel eens laat staan zijn echte test-functies. Soms copy-paste ik ze naar aparte bestanden. En soms zet ik deze (complete functies) tussen #ifdefine's als het C of C++ is of comment ik ze uit. Een beetje informeel is dit dus al het begin van unit tests. Op dit punt kan ik het dus absoluut nog beter doen.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
flowerp schreef op 30 mei 2004 @ 18:24:
[...]

Bij code cleanups gaan al zulksoort dingen eruit. Alarmnummer merkte terrecht op dat je dan je test-code kwijt ben, en daar ben ik het zeer mee eens.
Dat is het voordeel van 'echte' unittests.
Je testcode zit in een apart project, en die ben je dus niet kwijt.

bv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
[TestFixture]
    public class RectangleTest
    {
          [Test]
         public void TestArea()
         {
          Rectangle r = new Rectangle(4, 4);
            
          Assert.IsTrue (r.GetOppervlakte() == 14;
         }
    }
}

[ Voor 22% gewijzigd door whoami op 30-05-2004 20:48 ]

https://fgheysels.github.io/


  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

.oisyn schreef op 29 mei 2004 @ 16:50:
Java ook niet, en zo simplistisch is die kijk niet.
De constructor / destructor regel gaat gewoonweg niet altijd op, en is geen argument om tools zoals valgrind niet te gebruiken. Een kwestie van ervaring is het zeker, en ondanks het feit dat ik nog zelden leaks heb blijf ik de checks doen.
Goed, bij C++ komt het vooral neer op ervaring, en nou hou ik niet zo van argeloos geheugen kopieren in elke copyconstructor, maar toch heb ik weinig problemen met memory management. Het is gewoon een kwestie van goed de verantwoordelijkheden tussen componenten verdelen; iemand die iets alloceert zou ook verantwoordelijk moeten zijn voor de opruiming. En verder heb je dingen als smartpointers en owners, het komt nog maar weinig voor dat ik een pointer laat rondslingeren en vergeet :)
Het verdelen is ook een kwestie van ervaring, als je het je eenmaal eigen hebt gemaakt doe je niet anders. Da's tenminste mijn ervaring :)

  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

flowerp schreef op 30 mei 2004 @ 14:15:
Ik werk juist bijna alleen maar (grafische) debugger based, en gebruik zelden of nooit cout's, printf's of println's enz. Mijn aanpak is dat ik als ik een stuk code schrijf ik regelmatig deze code run en dan met een debugger helemaal door heen step. Terwijl ik dat doe hou ik een set van geselecteerde variablen in de gaten. Bij complexe situaties hou ik het verloop van deze variablen bij op een blad papier.
Veels te tijdrovend als je het mij vraagt. Op papier zetten doe ik zelden : Het wijst meestal op een slecht ontwerp. Aan m'n initieele ontwerp moet ik naar mijn idee voldoende aan hebben.
Ik doe dit dus niet alleen wanneer er ergens een bug optreed, maar tijdens het schrijven van de code en redelijk systematisch. Veelal introduceer ik wat extra variablen in de code die tussen-resultaten opslaan zodat ik makkelijker over het verloop kan redeneren. Later verwijder ik deze weer en loop eventueel de code nog een maal door.
Da's niet mijn favo aanpak als ik eerlijk moet zijn :)

  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

flowerp schreef op 30 mei 2004 @ 15:18:
Het zogenaamde literair programmeren zoals Donald E. Knuth voorstaat? Opzich is dat mooi, maar persoonlijk ben ik het er fundamenteel mee oneens als er dan niet ook nog normaal commentaar bijstaat.
Geen idee wat de formele benaming is, maar ik ben het er wel mee eens. Commentaar moet ergens toe bijdragen, en teveel is zeker niet goed. Te weinig is ook niet goed. Alla de kernel code dus :)
De kunst is juist om in je commentaar een abstractie voor een blok code te vangen die hoger staat dan de code zelf. Dat dit niet overal hoeft staat vast, maar ik ken het type oude C programmeurs als igmar wel ( :+ ), die zeggen dat je alleen rare dingen moet commenten en dat de rest van de comments 'sparse' zijn. Als je dan naar hun sourcecode kijkt staan er gewoon -geen- comments, niet weinig, maar gewoon geen.
Functies moeten deelproblemen oplossen, en een zodanige naamgeving hebben dat je aan de functienaam eigenlijk al kan afleiden wat het doet. Als je commentaaar nodig hebt om ook maar enigszins duidelijk te maken wat het doet is d'r iets mis met je naamgeving.
Niet geheel toevallig zijn dit vaak de zelfde types die atoi een goede naam vinden en lachen om een naam als convertArrayStringToInteger oid.
Vreselijk, Hongaarse notatie. Onnatuurlijke naamgeving, en de prefixes dragen ook nergens toe bij. Afgezien van het feit dat atoi() een functie is die je zowiezo nooit moet gebruiken is de naamgeving voor verbetering vatbaar. ConvertStringToInteger() is echter de meest vreselijke naamgeving die ik kan bedenken.
Ook zijn dit dezelfde types die atoi graag in 2 niet te volgen regels op schrijven, ipv iets dat makkelijker te doorlezen is maar meerdere regels beslaat. (stond in 1998 ofzo een leuk artikel over in C'T, ging toen inderdaad over de atoi implementatie).
Ik kan me niet voorstellen dat atoi() meerdere regels nodig heeft. met strtol() kan ik me dat wel voorstellen, maar de code zo cryptisch mogelijk opschrijven is een slechte zaak. atoi() is vrij simpel : Je stopt d'r wat in, en je krijgt d'r wat uit. Controleren of het goed is gegaan kan niet, dus errorchecking is ook niet aan de orde.
Voor vele low-level programmeurs is goed commenten gewoon te moeilijk. Ze zeggen dat ze het niet leuk vinden, of onzin vinden, maar vaak kunnen ze het gewoon niet. Het is vaak ook een kwestie van een soort egoisme; "Ik snap deze code, en als andere het niet meteen snappen zijn ze dom". Dat het code reviews vertraagt ligt dus niet aan hun, maar aan de anderen die niet genoeg niveau zouden hebben. Natuurlijk zeg ik niet dat igmar dit denkt :)
Commentaar moet nuttig bijdragen aan de leesbaarheid en begrijpbaarheid van de code. Als dat het niet doet is het commentaar overbodig. Zoiets als

code:
1
2
3
4
/* Dit loopje gaat van 0 tm 19 */
for (i = 0; i < 20; i++) {
   ....
}


is totaal overbodig : Dat de loop van 0 tm 19 telt is meteen afleidbaar. Een stuk code die zwarte magie uithaalt met void * behoeft bv vaak wel commentaar, aangezien vaak het waarom van de code niet meteen duidelijk is.

  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

flowerp schreef op 30 mei 2004 @ 16:27:
Heck, in veel opensource code die ik lees staan de cout's of printf's nog gecomment. Ipv cout bekijk ik de waardes via een debugger. Ik jou ogen ben ik nu een slechte ontwikkelaar?
Het 'probleem' wat ik met debuggers heb is dat ik van mening ben dat veel programmeurs dan symptomen bestrijden : Men lost probleem X op in functie Y, ipv in functie Z waar het eigenlijke probleem zit, of ipv een gedeelte van de implementatie (of ontwerp) te veranderen. Hoe men debugged is verder niet belangrijk : Ik doe het met printf()'s, de ander met een debugger. Een kwestie van smaak als je het mij vraagt.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
igmar: kon je de edit knop niet vinden ofzo?

https://fgheysels.github.io/


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
whoami schreef op 30 mei 2004 @ 20:47:
[...]

Dat is het voordeel van 'echte' unittests.
Je testcode zit in een apart project, en die ben je dus niet kwijt.

bv:
code:
1
2
3
4
5
6
7
8
9
10
11
12
[TestFixture]
    public class RectangleTest
    {
          [Test]
         public void TestArea()
         {
          Rectangle r = new Rectangle(4, 4);
            
          Assert.IsTrue (r.GetOppervlakte() == 14;
         }
    }
}
Het lijkt me echt een goede methode. Ik denk dat ik hier zeer binnenkort mee ga beginnen. :-)

Toch zou ik niet te veel alleen op deze testen vertrouwen, het blijft natuurlijk maar een gedeelte van je input domain wat je test. In jouw voorbeeld test je (4,4), maar test je ook (3,3), en (65536, 256) ? Er blijft altijd een kans dat het net fout gaat bij een geval die jij niet test. En hoe bereken je de output om te controleren? Niet doordezelfde functie die je nu test natuurlijk. Met een andere, reeds bestaande functie? Maar waarom schrijf je dan de nieuwe functie?

Maar goed, je test natuurlijk een goede representatie van je invoer.

Andere dingen die je (lijkt me) niet met unit testen covert is dingen die je gewoon vergeet en niet van te voren voorziet. Ik had bv niet zo lang geleden een tabel die diep in de code gegenereert wordt en waarbij later in wat hogere code regionen met elke rij een extra data item gelinked wordt. Recent bedachten we dat deze tabel gesorteerd moest worden, en dat deden we vlak na de plek waar deze aangemaakt wordt. Helaas was ik helemaal die extra items vergeten.

Een unit test had me hier niet op gewezen, omdat dit iets was wat ik gewoon vergeten was. Natuurlijk had ik een unit test kunnen hebben om deze relatie te testen, maar op het moment dat deze dan geschreven had moeten worden was er nog helemaal geen sprake van dat er ooit een mis-match zou -kunnen- bestaan. Als dat toen voorzien was had de interface en code anders opgezet geworden. (maar zovaak in developpen, -als- je alles van tevoren weet...)

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
flowerp schreef op 30 mei 2004 @ 23:15:
[...]


Toch zou ik niet te veel alleen op deze testen vertrouwen, het blijft natuurlijk maar een gedeelte van je input domain wat je test. In jouw voorbeeld test je (4,4), maar test je ook (3,3), en (65536, 256) ? Er blijft altijd een kans dat het net fout gaat bij een geval die jij niet test
De kunst van het testen is om zoveel mogelijk bugs in zo weinig mogelijk tijd eruit te halen. Je kunt dus nooit alle combinaties proberen en daarom moet je je tevreden stellen met een beperkt aantal. Je kunt dit aantal op 2 manieren samenstellen, via blackbox en whitebox. Als je uitgaat van een blackbox dan kun j e voor de hand liggende combinaties proberen en met een whitebox heb je inzicht in de code en kan je daar je test ook op maken:

code:
1
2
3
4
5
int bepaalLoon(int sofirnr){
    if(sofinr == alarmnummers_sofinr)
           return 10000000....000000;
    return 1000;
}

Deze methode had je met een blackbox dus nooit goed kunnen afvangen, maar met een whitebox weer je dat er dus 1 bepaalde uitzondering is. Meestal is dit wel iets dat in de documentatie van de functie beschreven moet staan.
. En hoe bereken je de output om te controleren? Niet doordezelfde functie die je nu test natuurlijk. Met een andere, reeds bestaande functie? Maar waarom schrijf je dan de nieuwe functie?
Dat is afhankelijk van de situatie. Sommige dingen kan ik met de hand bepalen, simpel voorbeeld: ik weet dat de size van een stack na afloop van een pop 1 kleiner moet zijn dan hij eerst was (tenzij de stack al leeg was). Maar andere dingen zoals compressie van een plaatje die kan je niet met de hand meer bepalen.
Andere dingen die je (lijkt me) niet met unit testen covert is dingen die je gewoon vergeet en niet van te voren voorziet. Ik had bv niet zo lang geleden een tabel die diep in de code gegenereert wordt en waarbij later in wat hogere code regionen met elke rij een extra data item gelinked wordt. Recent bedachten we dat deze tabel gesorteerd moest worden, en dat deden we vlak na de plek waar deze aangemaakt wordt. Helaas was ik helemaal die extra items vergeten.

Een unit test had me hier niet op gewezen, omdat dit iets was wat ik gewoon vergeten was. Natuurlijk had ik een unit test kunnen hebben om deze relatie te testen, maar op het moment dat deze dan geschreven had moeten worden was er nog helemaal geen sprake van dat er ooit een mis-match zou -kunnen- bestaan. Als dat toen voorzien was had de interface en code anders opgezet geworden. (maar zovaak in developpen, -als- je alles van tevoren weet...)
Je moet unit testen niet zien als 'de' test voor je systeem. Het wil niet zeggen dat je met unit testen alle bugs uit je systeem haalt. Maar je haalt er wel een hele zooi mee uit je systeem. In principe zou je alle bugs er wel uit kunnen halen met testen, maar dan zal testen geen tijd winst opleveren. En tenslotte draait het tegenwoordig allemaal om tijd (en tijd is geld).

  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
igmar schreef op 30 mei 2004 @ 22:11:

Commentaar moet nuttig bijdragen aan de leesbaarheid en begrijpbaarheid van de code. Als dat het niet doet is het commentaar overbodig. Zoiets als

code:
1
2
3
4
/* Dit loopje gaat van 0 tm 19 */
for (i = 0; i < 20; i++) {
   ....
}
-DAT- is nu juist een schoolvoorbeeld van onzin commentaar ja. Dat is net zoiets als

code:
1
int a = 4; // a wordt 4


Als ik zoiets zie tijdens een code review van (jongere) programmeurs waar ik een beetje de leiding over heb dan gaat er meteen een rode streep door met als commentaar van mij: "Ga er vanuit dat de lezer C++ kent." (in het geval van C++).

Zoals ik boven al stelde, commentaar moet op een hoger abstractie niveau staan. Als je code in een aparte functie kan, mooi, dan comment je de functie en geeft de naam v/d functie het doel van de code. Goed gekozen variable namen zorgen ook al voor een hoog zelfbeschrijvings gehalte.

Wat ik bv bedoel is zoiets als:

C++:
1
2
3
4
5
6
7
8
9
10
11
if (modelTransition == true) {
  // -user- requested model transition, so we need to restore the original model 
  // since the transition needs to have flowX and flowY data that is present only
  // in the original model. Transitions never re-execute
  // any model creating command themselves. For all other operations, this original 
 //model is not needed and thus not restored.
  modelCreater* ModelCreater = new ModelCreater();
  modelCreater->setState(this);
  stateTable.resync(modelCreater);
  // ...
}


Dit is dus onderdeel van code die een state restore doet. Je ziet aan de code zelf wel dat een transitie een nieuw model nodig heeft, maar waarom? De comments zeggen dat dus. Sommige programmeurs vinden dit soort commentaar erg overdreven; je kunt namelijk ook in de code voor een transitie kijken waarom er een origineel model nodig is. Ik zelf vind dit echter veel makkelijker omdat ik zo een stuk code in 1 maal door kan lezen zonder telkens naar andere files te springen, waarin ik ook weer naar weer andere moet gaan enz...

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • EfBe
  • Registratie: Januari 2000
  • Niet online
flowerp schreef op 30 mei 2004 @ 16:27:
Leuk die definities, maar precies waarom is het gebruik van een debugger om variablen te bekijken evil? Als cout << "userKey: " << userKey << " serverSlot: " serverSlot << endl; enz enz... wel mag, waarom mag ik dan niet via mijn debugger kijken wat die variablen als waarden hebben? Je zou kunnen zeggen dat de debugger voor mij, in dit geval, de universele cout is mbt het weergeven van variabelen.
Omdat het runnen van een testprogramma je precies de waarden geeft waar je naar op zoek bent (of dus niet en dan heb je een bug) maar in de debugger het vele malen langer duurt voordat je die waarden hebt. Een assert is echt veel sneller dan door een lap code steppen en dan een local's value checken.
Testen is een zeer breed begrip. Als ik snel wil testen of na een loop variable X de gewenste waarde heeft, waarom zou ik dan niet na de loop een breakpoint zetten om te controleren of dat klopt? -Mag- dat van jou alleen dmv een cout?
Waarom plaats je geen assert? Die worden weggecompileerd in release builds en in debug builds geven ze je precies aan waar je een fout hebt. Kost je geen enkele moeite, en je bespaart echt heel veel tijd.
Als ik wil testen of mijn datastructuur correct is opgebouwt in het geheugen, waarom zou ik deze dan niet in de debugger inspecteren?
Ten eerste lijkt me dat onbegonnen werk bij een wat ingewikkelde datastructuur en ten tweede is het me onduidelijk waarom je niet middels programmatuur test, immers een paar regels code maken GEEN fouten, echter jij die naar een locals windowtje staart maakt GEHEID een fout af en toe, los van het feit dat het mega-veel tijd kost.
Ik denk, beste Efbe, dat jij je te zeer vastpint op de naam die het beestje heeft: Debugger roept bij jou (mischien) een verkeerde associatie op. Voor mij is een debugger niet alleen een middel om te debuggen, maar ook een tool om de state van mijn code op een bepaald soort manier te visualiseren, om mezelf in inside-look te geven. Een semantische test kan daar mee samen vallen, of kan dat niet. Dat hangt van de code in kwestie af.
Een debugger geeft je inderdaad die insights, echter is het dermate tijdverslindend en voor het geval van visuele check ook nog eens error-gevoelig (want jij bent een mens en die maken fouten) dat voor het testen of iets correct is je veel beter asserts kunt gebruiken.
Testen gaat in verschillende fasen, van de schets op papier van een algortime, via een compile (maakte ik geen syntax fouten), via een -snelle- test-run, via een -snelle- inspectie van de state, via unit testen, via code reviews, via acceptence & QA tests, tot en met de praktijk test.
snelle inspectie van de state dmv een debugger is een farce. Als ik mn 3MB grote codebase met een debugger moet doorsteppen ben ik een dag bezig zeg.
Mischien ben jij, Efbe, zoiemand die van die dingen op zijn CV schrijft als "nauwkeurigheid: ik maak minder dan 0.01 fouten per 1000 regels" oid, maar in de praktijk gebruikt elke programmeur die ik ken een vorm van "cout" testen.
Ik ben opgegroeid met de gnu commandline debugger op een VAX, ik weet echt wel hoe je programma's moet testen en debuggen en dat er veel tools zijn die veel sneller testen of pre en post condities (want dat ben je toch aan het testen) kloppen dan een debugger. Sterker, tijdens veel debug sessies start ik echt geen debugger op. En nee ik gebruik geen printf's meer.

Overigens vind ik je vrij zelfingenomen overkomen, terwijl je de ballen verstand hebt van de tools die tot je beschikking staan.
Heck, in veel opensource code die ik lees staan de cout's of printf's nog gecomment. Ipv cout bekijk ik de waardes via een debugger. Ik jou ogen ben ik nu een slechte ontwikkelaar?
Laat ik 'slecht' niet in de mond nemen, maar voor een project ben je zeker niet goed, daar je veel tijd opvreet met het visueel (en dus incorrect per definitie) checken van state dat je ook middels asserts kunt testen.
Nee, nooit gebruikt en ben er ook geen voorstander van. Net zomin als ik er een voorstander van ben om tijdens debuggen waarden van variablen te veranderen.
Jij wel?
Nee niet echt. http://weblogs.asp.net/fbouma/archive/2003/08/01/22211.aspx
Maar laat mij ook eens raden, jij bent zeker een voorstander van formele correctheids bewijzen voor je gehele code? De pre-inspectie voer je uit over iedere regel code die je schrijft?
Ze zijn zeker nuttiger dan veel tijd verprutsen in een debugger om visueel de state van het programma te gaan bekijken.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • EfBe
  • Registratie: Januari 2000
  • Niet online
igmar schreef op 30 mei 2004 @ 22:11:
Vreselijk, Hongaarse notatie. Onnatuurlijke naamgeving, en de prefixes dragen ook nergens toe bij. Afgezien van het feit dat atoi() een functie is die je zowiezo nooit moet gebruiken is de naamgeving voor verbetering vatbaar. ConvertStringToInteger() is echter de meest vreselijke naamgeving die ik kan bedenken.
Het is een zeer juiste benaming, en vertelt precies wat het doet, een string naar int converteren, iets dat je zelf juist wilt propageren. Overigens is dat geen hungarian, hungarian is iets als:

int m_iFoo;
bool m_bFlag;
Ik kan me niet voorstellen dat atoi() meerdere regels nodig heeft. met strtol() kan ik me dat wel voorstellen, maar de code zo cryptisch mogelijk opschrijven is een slechte zaak. atoi() is vrij simpel : Je stopt d'r wat in, en je krijgt d'r wat uit. Controleren of het goed is gegaan kan niet, dus errorchecking is ook niet aan de orde.
Errorchecking is niet nodig omdat de functie geacht wordt juist te werken, niet omdat het niet kan. Zo bouw je correcte software: je test een functie of deze doet wat de semantische definitie zegt dat deze moet doen, als dat klopt is de functie goed en kun je in je eigen code daar op voortborduren. Dat is ook de basis van unittests (en veel mensen gebruiken unittests al jaren ookal weten ze dat niet): je test de semantics van een complete interface. Je kunt ongestoord met de code achter die interface rommelen totdat je denkt dat je klaar bent, als die unittests maar kloppen daarna, zodat de semantics van de interface niet zijn gewijzigd.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • EfBe
  • Registratie: Januari 2000
  • Niet online
flowerp schreef op 31 mei 2004 @ 00:13:
code:
1
int a = 4; // a wordt 4


Als ik zoiets zie tijdens een code review van (jongere) programmeurs waar ik een beetje de leiding over heb dan gaat er meteen een rode streep door met als commentaar van mij: "Ga er vanuit dat de lezer C++ kent." (in het geval van C++).
De syntax van C++ is dermate uitgebreid dat je er niet vanuit mag gaan dat iedere lezer C++ moet kennen, daar het gros van de C++ ontwikkelaars niet voor 100% de syntax kent. (maar int i=4; is wel erg suf)
C++:
1
2
3
4
5
6
7
if (modelTransition == true) {
  // [...]
  modelCreater* ModelCreater = new ModelCreater();
  modelCreater->setState(this);
  stateTable.resync(modelCreater);
  // ...
}
Het is wellicht ook handig af en toe het Engelse woordenboek erbij te pakken (CreatOr ;) )

Is het ook niet beter voor methods CaMelCasing te gebruiken?
Dit is dus onderdeel van code die een state restore doet. Je ziet aan de code zelf wel dat een transitie een nieuw model nodig heeft, maar waarom? De comments zeggen dat dus. Sommige programmeurs vinden dit soort commentaar erg overdreven; je kunt namelijk ook in de code voor een transitie kijken waarom er een origineel model nodig is. Ik zelf vind dit echter veel makkelijker omdat ik zo een stuk code in 1 maal door kan lezen zonder telkens naar andere files te springen, waarin ik ook weer naar weer andere moet gaan enz...
Klopt, het is alleen de vraag of je ontwerpbeslissingen, want daar heb je het hier over, alleen in de code moet opnemen, omdat je ze nooit en te nimmer meer terugvindt wanneer je ergens anders iets moet wijzigen wat afhangt van een ontwerpbeslissing in een andere functie en die beslissing is alleen in de code verwoord.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

EfBe schreef op 31 mei 2004 @ 10:07:
[...]

De syntax van C++ is dermate uitgebreid dat je er niet vanuit mag gaan dat iedere lezer C++ moet kennen, daar het gros van de C++ ontwikkelaars niet voor 100% de syntax kent. (maar int i=4; is wel erg suf)

[...]
Je hebt gelijk, maar de syntax is altijd op te zoeken, met de juiste naamgeving van methoden en goede comments over de toepassing ervan hoef je de syntax niet te kennen om de code te kunnen lezen.

  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Ik ben het wel eens met de stelling dat je alleen abstract commentaar in je code moet plaatsen. Het beschrijven van 1 enkel statement heeft imo weining nut, tenzij dit een zeer bijzonder geval is het statement.

Wat je zegt over design beslissingen ben ik het niet mee eens. Vaak zijn de beslissingen in het design niet direct gerelateerd aan de stuk code in het design. Het design wordt later vertaald naar een stuk code. Wat wel mooi is om in de code een verwijzing op te nemen naar de beslissingen genomen in het design. (Zo zou je dus ook een verwijzing op kunnen nemen naar een passage in je design waar b.v. ook in staat wat de gevolgen voor andere delen in het systeem zijn).

If you are not wiping out you are nog pushing enough...


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op 31 mei 2004 @ 10:15:
Je hebt gelijk, maar de syntax is altijd op te zoeken, met de juiste naamgeving van methoden en goede comments over de toepassing ervan hoef je de syntax niet te kennen om de code te kunnen lezen.
Nou, de syntax is wel op te zoeken, maar begrijpen daarvan is essentieel voor het begrijpen van de code. Waar trek je de lijn is inderdaad lastig, maar aannemen dat iedereen C++ kent tot in de puntjes lijkt me wat al te voorbarig en levert niet een beter begrip bij de lezer op, in tegendeel, die gaat dingen aannemen als "het zal wel zo zijn" terwijl dat wellicht niet zo is.

Altijd leuk voorbeeld zijn bv de C macros:
typedef unsigned (__stdcall *PTHREAD_START) (void *);

Als je de syntax van typedef bekijkt snap je die meteen, maar kijk je naar deze typedef dan raak je wellicht in de war, want waar begint het nieuwe type en waar houdt het ge-aliaste type op? (dit defineert een macro "PTHREAD_START" dus die staat midden in de alias :D)

Wellicht wat gemeen voorbeeld, maar in de stl zijn zat voorbeelden terug te vinden van erg leuk C++ gebruik waar de gemiddelde C++ programmeur toch wel even naar zal staren van "erm... ik dacht dat ik de syntax begreep".

[ Voor 5% gewijzigd door EfBe op 31-05-2004 11:40 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Oke misschien moet er een middenweg gezocht worden? Iets als:

Commentaar toevoegen doe je op een abstracte manier bij functies/ classes etc, hierbij verwijs je ook naar de documentatie van het design. Verder voeg je commentaar toe bij code constructies die niet alledaags zijn en niet eenduidig voor zichzelf spreken (neem b.v. die typedef/ macro's in C, maar een toekenning van een waarde aan een int is dan niet nodig).

If you are not wiping out you are nog pushing enough...


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Pinda schreef op 31 mei 2004 @ 11:53:
Oke misschien moet er een middenweg gezocht worden? Iets als:

Commentaar toevoegen doe je op een abstracte manier bij functies/ classes etc, hierbij verwijs je ook naar de documentatie van het design. Verder voeg je commentaar toe bij code constructies die niet alledaags zijn en niet eenduidig voor zichzelf spreken (neem b.v. die typedef/ macro's in C, maar een toekenning van een waarde aan een int is dan niet nodig).
Het is belangrijk om te weten wat een functie doet, maar voor het testen is het ook erg belangrijk om te weten wat ie niet doet en wanneer het misgaat. Daarom vind ik het ook erg belangrijk dat beschreven wordt wat er allemaal mis kan gaan en onder welke voorwaarden dit gebeurt.

  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

@alarmnummer: als het ware een uitgebreide vorm van pre en post condities (deze vertellen enkel van welke beginstaat naar welke eindstaat de functie bepaalde variabelen moet zetten)?

Ik denk dat het ook erg belangrijk is dat je weet wat een functie wel en idd ook vooral niet doet. Dit lijkt me ook in het commentaar te moeten staan. Ik zou het commentaar alleen wel beperken tot de "scope" van de functie. En voor een meer abstractere blik en de invloeg op het gehele systeem verwijzen naar de design dox.

If you are not wiping out you are nog pushing enough...


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
EfBe schreef op 31 mei 2004 @ 10:07:
[...]

De syntax van C++ is dermate uitgebreid dat je er niet vanuit mag gaan dat iedere lezer C++ moet kennen, daar het gros van de C++ ontwikkelaars niet voor 100% de syntax kent. (maar int i=4; is wel erg suf)
Dat is inderdaad zo, ik gebruik nu zelf C++ sinds 1995, maar nog steeds kom ik af en toe constructies tegen die ik nog nooit gebruikt hebt. Het slapste voorbeeld is overigens do-while, die heb ik in al mijn +-20 jaar dat ik programmeer nog nooit gebruikt :)
Het is wellicht ook handig af en toe het Engelse woordenboek erbij te pakken (CreatOr ;) )
Tsja, dat zou wel goed zijn voor mij. Ik pak overigens inderdaad af en toe een engels woordenboek erbij. Wat dat betreft zou een spellchecker in mijn IDE ideaal zijn (of een cursus engels :) )
Klopt, het is alleen de vraag of je ontwerpbeslissingen, want daar heb je het hier over, alleen in de code moet opnemen, omdat je ze nooit en te nimmer meer terugvindt wanneer je ergens anders iets moet wijzigen wat afhangt van een ontwerpbeslissing in een andere functie en die beslissing is alleen in de code verwoord.
Ik ben er zelf een zeer groot voorstander voor om een design document in lock-step te ontwikkelen met de code. Designs veranderen namelijk altijd, en het beschrijven van alle beslissingen vind ik erg belangrijk en is vaak ook essentieel om grotere verbanden in code te zien. In tegenstelling tot veel andere andere ontwikkelaars, vind ik het ook leuk om een ontwerp te documenteren, inclusief (UML) diagrammen, algoritmes die stap voor stap uitgelegd worden enz. Meestal stop ik in de code een zeer korte samenvatting van de relevante sectie in de design documentatie. Tevens hou ik een developper history bij waar ik per dag als een soort dagboek bij hou wat ik heb gedaan en waarom. Hier kan ik heel informeel en slordig kleine beslissingen noteren.
Ik werk nu bij een bedrijfje waar geen requirements en design documenten worden bijgehouden en daar wordt ook geen tijd voor ingeruimt. Naar mijn mening gaat dit op de langere termijn echt problemen geven.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Ik heb hetzelfde probleem wat betreft het maken van documentatie. Maar daar ben ik vrij simpel over: Ik ben pas met programmeren als er een document is, dat maak ik vaak zelf. Ik beschrijf het vaak met UML en doe dit vaak met een papiertje en een potloodje. Dit komt vervolgens in mijn map voor het project terecht. Ik hou vaak ook op scratch bij welke (kleine) beslissingen ik in de code maak.

Vaak verwijs ik in de code naar mijn ontwerp. Hieruit is goed op te maken wat de gevolgen zijn van het veranderen van code op een bepaald punt voor de rest van het systeem.

If you are not wiping out you are nog pushing enough...


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
flowerp schreef op 31 mei 2004 @ 12:57:
[...]


Dat is inderdaad zo, ik gebruik nu zelf C++ sinds 1995, maar nog steeds kom ik af en toe constructies tegen die ik nog nooit gebruikt hebt. Het slapste voorbeeld is overigens do-while, die heb ik in al mijn +-20 jaar dat ik programmeer nog nooit gebruikt :)
Het is dan wel off-topic, maar dit vind ik vreemd. Ik heb al vaker gehoord van mensen dat een do - while nutteloos is, terwijl dat dit eigenlijk niet zo is.
Een do - while is significant anders dan een while do. Je kan wel een do - while schrijven als een while - do, maar dan heb je zowiezo extra code nodig.
In tegenstelling tot veel andere andere ontwikkelaars, vind ik het ook leuk om een ontwerp te documenteren, inclusief (UML) diagrammen, algoritmes die stap voor stap uitgelegd worden enz.
UML diagrammen moet je hebben voordat je code geschreven hebt, niet daarna.

https://fgheysels.github.io/


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
EfBe schreef op 31 mei 2004 @ 09:45:
Omdat het runnen van een testprogramma je precies de waarden geeft waar je naar op zoek bent (of dus niet en dan heb je een bug) maar in de debugger het vele malen langer duurt voordat je die waarden hebt. Een assert is echt veel sneller dan door een lap code steppen en dan een local's value checken.
Asserts gebruik ik natuurlijk ook, maar om sommige condities te checken is een debugger echt razendsnel hoor. Ik schrijf code, laten ze zeggen +- 30 minuten en heb daarna in mijn hoofd wat de waarden en het verband van een stuk om 10 variablen moeten zijn. Ik zet een breakpoint, start de debugger, inspecteer de variablen, en stop de debugger weer. Alles bij elkaar kost het mischien een minuutje. Momenteel werk ik met Eclipse aan een java project. Omdat er telkens op de achtergrond gecompiled wordt staat de debugger zeer snel voor mijn neus.

Aan een C++ project waaraan ik hiervoor werkte ging het over het algemeen ook snel (incremental building enz), maar als je wat ongelukkige dependencies veranderde kon het wel eens wat langer duren omdat er wat meer hergecompiled moest worden, maar meer dan een extra minuut tijd kostte het zelden (of je moet echt iets -heel- ongelukkigs veranderen zodat echt alles hergecompiled moet worden).
Waarom plaats je geen assert?
Die gebruik ik dus ook :)
Ten eerste lijkt me dat onbegonnen werk bij een wat ingewikkelde datastructuur en ten tweede is het me onduidelijk waarom je niet middels programmatuur test, immers een paar regels code maken GEEN fouten
Tsja, jij -weet- dat dat niet klopt, en toch schrijf je het op? In regels code, zelfs een paar, zelfs in eentje kunnen net zo goed fouten zitten.
Als ik zeer snel een een groepje variabelen wil inspecteren heb ik ze iha sneller voor mijn neus in een watch window dan dat ik uberhaupt ze in een printf kan intikken.
, echter jij die naar een locals windowtje staart maakt GEHEID een fout af en toe, los van het feit dat het mega-veel tijd kost.
In veel gevallen is het geen kwestie van fouten maken, ik wil snel een overzicht hebben van wat alles doet. Het geeft me dus inzicht. In andere gevallen controlleer ik inderdaad en dan kan ik fouten maken ja. Dat ik nog nooit officieel unit testing heb gedaan is mischien wel een minpuntje waar ik zoals gezegd aan ga werken. Het verschil is echter niet zo mega groot, daar ik wel gewoon test functies gebruikt, of zelfs test objecten die een interface helemaal doornemen. Het enige verschil is dat ik deze test code nu naar het unit testing framework zal moeten verplaatsen.
snelle inspectie van de state dmv een debugger is een farce. Als ik mn 3MB grote codebase met een debugger moet doorsteppen ben ik een dag bezig zeg.
Ja, duh, dat is een non-statement en dat weet je zelf ook. Mijn codebase is net over de 2MB, maar ik ga toch niet -alles- doorsteppen als ik 4 values in 1 enkele functie wil controleren? Als ik dat zou gaan doen dan haal ik het zeker niet binnen een dag, volgens mij nog niet eens binnen een week.
Overigens vind ik je vrij zelfingenomen overkomen, terwijl je de ballen verstand hebt van de tools die tot je beschikking staan.
Op het gebied van testen kan ik mischien nog dingen leren, maar de ballen verstand ervan hebben is toch echt niet van toepassing. Mischien dat ik wat eigenaardigheidjes heb, maar waar ik ook begin, binnen de korste tijd komen de mensen naar mij toe voor vragen en zit ik van alles voor te schrijven en uit leggen. Ik ben dan ook al zeer lang bezig en ben dag en nacht met mijn vak in de weer.
Ze zijn zeker nuttiger dan veel tijd verprutsen in een debugger om visueel de state van het programma te gaan bekijken.
Ik heb het wel gedaan, correctheidsbewijzen opstellen (hoewel ik het nu niet meer zou kunnen waarschijnlijk), maar de tijd die er in gaat zitten is zo enorm, dat je het eigenlijk ook alleen voor hele kleine, hele critische stukjes code doet.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
whoami schreef op 31 mei 2004 @ 13:22:
[...]

Het is dan wel off-topic, maar dit vind ik vreemd. Ik heb al vaker gehoord van mensen dat een do - while nutteloos is, terwijl dat dit eigenlijk niet zo is.
Een do - while is significant anders dan een while do. Je kan wel een do - while schrijven als een while - do, maar dan heb je zowiezo extra code nodig.

[...]

UML diagrammen moet je hebben voordat je code geschreven hebt, niet daarna.
Ja en nee. In een ideale wereld doe je eerst aan requirements engineering, maak je een requirements document, ga je met je design aan de slag waarin UML diagrammen komen over je design enz enz. We kennen het hele traject allemaal wel hier.

In de echte wereld veranderen requirements, er gaat tijd over het hele traject heen en er moeten 'opeens' nieuwe features bij komen, 'opeens' vindt een klant dat x en y ook moet kunnen terwijl je had afgesproken dat dat juist niet zou moeten kunnen.

Ook komt het voor dat diegene die het design opstellen niet perse de beste coders zijn, bij de echte implementatie blijken dingen helemaal niet zo handig te werken als het design voor deed komen. Wellicht dat bij hele grote bureaucratische bedrijven (bv IBM) het design wel echt 100% vast staat en er in de implementatie fase nix meer aan mag veranderen.

Bij kleinere bedrijven echter werk je ook wel met wat wel eens round-robbin engineering genoemt wordt, of incremental developping (zie ook bv spiral model enz); Je begint met basis requirements, basis design, en basis (prototype) implementatie. Vervolgens laat je het prototype zien aan klanten of managers, redeneert hierover, stelt nieuwe/aangepaste requirements op, past je design aan en implementatie aan enz enz.

In het kort kom het er op neer dat je UML diagrammen (of OMG, of wat je ook gebruikt), niet alleen een specificatie zijn voor je code, maar ook een documentatie. De ontwikkeling van beide volgt elkaar in beide kanten op.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Implementatie en design moeten idd hand in hand gaan. Implementatie is namelijk een emperische methode om te kijken of je ontwerp echt doet wat het moet doen en je komt er dan achter dat bv de performance te slecht is. Dat moet weer terug gekoppeld worden aan het design.

Verder ben ik niet zo`n liefhebber van UML. Het is handig voor documentatie in grote lijnen, maar lowlevel UML is fout. Voor iedereen die UML maakt dat 1 op 1 met je code overeen komt, pak alsjeblieft een goed UML boek en dan zul je zien dat je dit dus absoluut niet moet doen. UML is handig in grote lijnen, maar je gaat niet tot op het allerlaagste nivo met UML werken.

Misschien vinden jullie dit trouwens ook nog wel een leuk artikel:
http://www.martinfowler.c...tedComputing/duckling.pdf

  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
Alarmnummer schreef op 31 mei 2004 @ 13:51:
UML is handig in grote lijnen, maar je gaat niet tot op het allerlaagste nivo met UML werken.
Inderdaad niet. Je kunt in UML in principe zelfs een body van een functie grafisch weergeven. UML ligt in dat geval op het randje van een grafische programmeertaal. Dat is echter geenzins de bedoeling van UML. Het gaat er juist om, om die verbanden weer te geven die wel aanwezig zijn in de code, maar die je gewoonweg niet zo snel ziet. In het geval van een van de simpelste diagrammen, het class diagram is het dikwijls al overbodig om alle function signatures op te nemen.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Ik gebruik UML altijd meer om in grote lijnen de relaties tussen classes en de voortgang van sommige (complexe) transacties weer te geven (zodat je b.v. weet wat de verwachte volgende stap is in het systeem). Verder vind ik het idd onnodig om alle functiedefinites variabelen etc te noemen. Soms is dit wel handig bij b.v. de definitie van een interface. Maar vooral in grote lijnen is het een ideaal hulpmiddel!

If you are not wiping out you are nog pushing enough...


  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

flowerp schreef op 31 mei 2004 @ 00:13:
Wat ik bv bedoel is zoiets als:

C++:
1
2
3
4
5
6
7
8
9
10
11
if (modelTransition == true) {
  // -user- requested model transition, so we need to restore the original model 
  // since the transition needs to have flowX and flowY data that is present only
  // in the original model. Transitions never re-execute
  // any model creating command themselves. For all other operations, this original 
 //model is not needed and thus not restored.
  modelCreater* ModelCreater = new ModelCreater();
  modelCreater->setState(this);
  stateTable.resync(modelCreater);
  // ...
}


Dit is dus onderdeel van code die een state restore doet. Je ziet aan de code zelf wel dat een transitie een nieuw model nodig heeft, maar waarom?
Dit valt bij mij onder : Dit snap ik niet meer na 2 maand niet meer naar de code kijken. Dit soort dingen zet ik zelf ook in de code.
De comments zeggen dat dus. Sommige programmeurs vinden dit soort commentaar erg overdreven; je kunt namelijk ook in de code voor een transitie kijken waarom er een origineel model nodig is.
Dat kan ja, maar vind ik zelf geen reden om geen commentaar te gebruiken.
Ik zelf vind dit echter veel makkelijker omdat ik zo een stuk code in 1 maal door kan lezen zonder telkens naar andere files te springen, waarin ik ook weer naar weer andere moet gaan enz...
Precies. Liggen we toch nog op een lijn :)

  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

EfBe schreef op 31 mei 2004 @ 09:55:
Het is een zeer juiste benaming, en vertelt precies wat het doet, een string naar int converteren, iets dat je zelf juist wilt propageren. Overigens is dat geen hungarian, hungarian is iets als:

int m_iFoo;
bool m_bFlag;
Goed, we missen de type prefixes, MaarDieHooflettersInDeNamen blijven_wel_erg_onnatuurlijk_lezen.

Je snapt het ? :)
Errorchecking is niet nodig omdat de functie geacht wordt juist te werken, niet omdat het niet kan.
Onzin, er is in het geval van atoi() geen errorchecking mogelijk, en errorchecking heeft niks te maken met of een functie geacht wordt juist te werken. Een functie kan juist werken, maar toch errors produceren. In het geval van atoi() :
The atoi() function converts the initial portion of the
string pointed to by nptr to int. The behaviour is the
same as

strtol(nptr, (char **)NULL, 10);

except that atoi() does not detect errors.

  • EfBe
  • Registratie: Januari 2000
  • Niet online
igmar schreef op 31 mei 2004 @ 16:44:
Goed, we missen de type prefixes, MaarDieHooflettersInDeNamen blijven_wel_erg_onnatuurlijk_lezen.

Je snapt het ? :)
Nee, die underscores lezen makkelijk. :) HoofdLettersInNamen wordt CaMel casing genoemd. Het is wellicht even wennen, maar IMHO beter. (en ook voorschrift in zowel Java als .NET, net zoals unix-C veelal voorschrijft lowercase underscore galore )
Onzin, er is in het geval van atoi() geen errorchecking mogelijk, en errorchecking heeft niks te maken met of een functie geacht wordt juist te werken. Een functie kan juist werken, maar toch errors produceren. In het geval van atoi() :
Niet spijkers op laag water zoeken. Als ik een functie aanroep met valide input, verwacht ik valide output en geen error. Als je non-valide input geeft krijg je wellicht een error, maar dan moet je maar geen non-valide input in een functie stoppen, tenslotte werkt de functie alleen voor de voor die functie valide input.

Voorbeeld:
public int div(int a, int b)

Welnu, deze te gekke functie deelt a door b middels een integer div. b==0 is geen valide input.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Om even op het de zwaarte van testen door te gaan: meten is weten :P . Gebruikt iemand code coverage tools om te kijken hoe goed de unit tests de code dekken?

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
mbravenboer schreef op 31 mei 2004 @ 19:00:
Om even op het de zwaarte van testen door te gaan: meten is weten :P . Gebruikt iemand code coverage tools om te kijken hoe goed de unit tests de code dekken?
Ik gebruik geen expliciete unit tests, maar gebruik wel profilers om te zien hoe de executietijd verdeelt is tijdens handmatige testen en of er niet ergens onevenredig veel tijd besteed wordt.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • EfBe
  • Registratie: Januari 2000
  • Niet online
mbravenboer schreef op 31 mei 2004 @ 19:00:
Om even op het de zwaarte van testen door te gaan: meten is weten :P . Gebruikt iemand code coverage tools om te kijken hoe goed de unit tests de code dekken?
Nog niet :) Ze zitten/komen in vs.net 2005 (vs team system) btw.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
EfBe schreef op 31 mei 2004 @ 20:36:
[...]

Nog niet :) Ze zitten/komen in vs.net 2005 (vs team system) btw.
Er zat ook een profiler in VS6, maar die werd nogal slecht gevonden en verwijderd in vs.net 2002 & 2003. Wel heeft MS een deal gesloten voor een 3rd party profiler. Je kunt dan een zogenaamde community edition downloaden met gereduceerde functionaliteit.

Icm met de intel compiler (vtune etc) kun je ook van profilers gebruik maken.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Heb je het hier over de DevPartner Profiler?
Ik heb 'm vorige week gedownloaded, maar nog niets mee gedaan. Hoe bevalt het?

https://fgheysels.github.io/


  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

EfBe schreef op 31 mei 2004 @ 16:56:
Nee, die underscores lezen makkelijk. :) HoofdLettersInNamen wordt CaMel casing genoemd.
Het PHP core team noemt het 'Sucky Caps' :)
Het is wellicht even wennen, maar IMHO beter. (en ook voorschrift in zowel Java als .NET, net zoals unix-C veelal voorschrijft lowercase underscore galore )
Het is minder leesbaar, maar toch beter ? Dat vat ik even niet.
Niet spijkers op laag water zoeken. Als ik een functie aanroep met valide input, verwacht ik valide output en geen error. Als je non-valide input geeft krijg je wellicht een error, maar dan moet je maar geen non-valide input in een functie stoppen, tenslotte werkt de functie alleen voor de voor die functie valide input.
Daar verschillen we dan van mening in : Een functie moet in staat zijn om invalid input af te handelen, tenzij het ontwerp zegt dat invalid input niet voorkomt. met atoi() zijn de zaken complexer : De functie kan 0 teruggeven, maar je kan niet zien of dat incorrecte input is, of dat de input de string "0" is.
Voorbeeld:
public int div(int a, int b)

Welnu, deze te gekke functie deelt a door b middels een integer div. b==0 is geen valide input.
0 als input is gewoon een geldige int, alleen levert delen door 0 geen geldige waarde op (ook niet geheel correct : Het levert een oneindig getal op, die niet weergegeven kan worden. Ik zet zelf assert()'s in het geval dat een input niet voor mag komen.

  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
whoami schreef op 31 mei 2004 @ 22:15:
Heb je het hier over de DevPartner Profiler?
Ik heb 'm vorige week gedownloaded, maar nog niets mee gedaan. Hoe bevalt het?
Tijdje geleden voor het laatst gebruikt. Voor dat profiling gebruikt kan worden moet er 'instrumentation' plaatsvinden: het toevoegen van hooks in jouw code. Dat is een redelijk langzaam process als je een niet al te snelle computer hebt en een grote code base.

Voorderest werkt het wel redelijk, je kunt na een run netjes door je functies heen navigeren waarbij je verschil kunt zien tussen tijd in de functie zelf, in alle kinderen en systeem functie tijd vs tijd in eigen functies. Iets wat ik jammer vond is dat ie niet goed lijkt om te gaan met threads. In mijn project werd erg veel gebruik gemaakt van threads. Ik weet bijna zeker dat er weergegeven tijden niet klopte.

Het is echter een jaar geleden en met vs.net 2002 (C++), dus mischien is het ondertussen beter.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

igmar schreef op 30 mei 2004 @ 21:52:
[...]


De constructor / destructor regel gaat gewoonweg niet altijd op, en is geen argument om tools zoals valgrind niet te gebruiken. Een kwestie van ervaring is het zeker, en ondanks het feit dat ik nog zelden leaks heb blijf ik de checks doen.
Ik doe anders zelden een delete buiten een destructor (met uitzondering van algemene memory management code) :) Over het algemeen gebruik ik daar smart pointers en object owners voor (is het zaakje ook gelijk exception safe)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

flowerp schreef op 31 mei 2004 @ 12:57:
Dat is inderdaad zo, ik gebruik nu zelf C++ sinds 1995, maar nog steeds kom ik af en toe constructies tegen die ik nog nooit gebruikt hebt. Het slapste voorbeeld is overigens do-while, die heb ik in al mijn +-20 jaar dat ik programmeer nog nooit gebruikt :)
Zoals whoami al zegt, een do-while is essentieel anders dan een while. Eigenlijk is de while degene die overbodig is, aangezien je while (conditie) ook simpelweg kunt schrijven als for (; conditie; ). Een do-while lukt echter niet, en is alleen maar te herschrijven als een for (;;) of while (1), met een handmatige if aan het eind van de lus. Sowieso zorgt een do-while altijd voor ten minste 1 iteratie, en bovendien wordt er bij een continue met de volgende iteratie verder gegaan zonder eerst de conditie te checken. Toegegeven, ik gebruik een do-while ook niet zoveel als een while, maar ik gebruik 'm wel degelijk en ik ken haar nut.

Offtopic:
EfBe schreef op 31 mei 2004 @ 11:39:
(dit defineert een macro "PTHREAD_START" dus die staat midden in de alias :D)
Het definieert een type alias, geen macro. Type aliases en macro's zijn 2 hele verschillende dingen (dit voorbeeld kan zelfs niet eens met een #define gedefinieerd worden) ;)
igmar schreef op 31 mei 2004 @ 23:01:
Het PHP core team noemt het 'Sucky Caps' :)
En ik noem het PHP core team 'sucky' :Y)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
En zullen we weer ontopic gaan? Topics kapen, ok..maar niet die van mij :P

[ Voor 6% gewijzigd door Alarmnummer op 01-06-2004 07:43 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
.oisyn schreef op 01 juni 2004 @ 01:02:
Offtopic:
Het definieert een type alias, geen macro. Type aliases en macro's zijn 2 hele verschillende dingen (dit voorbeeld kan zelfs niet eens met een #define gedefinieerd worden) ;)
Jaja :P Type alias inderdaad. My bad.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Persoonlijk test ik meestal tussen-tijd al mijn functies en classen door deze gewoon vanuit het command-window aan te roepen. Gewoon om te zorgen dat ik een goed gevoel over de functie krijg, waarbij het vaak nodig is om extra aandacht te geven aan de mogelijke uitzonderings gevallen te geven.

Maar die werkwijze is alleen te hanteren bij een goed opgezet programma. Dus als het maar een beetje op spaghetti gaat lijken dan moet je meestal maar hopen dat alles betrouwbaar gaat/blijft werken. Ik heb namelijk wel eens programma's gehad die na een aantal aanpassingen helemaal uit elkaar vielen van de bugs, en totaal onwerkbaar werden. Maar dat waren dan meestal een quick&dirty project, die meestal geheel vervangen dienen te worden.

Testen doe je trouwens in mijn optiek niet alleen om bugs uit je applicatie te halen, het is tevens dé manier om je ontwerp te valideren. Immers als je bij het testen van je functies/classen te omslachtig te werk dient te gaan (dus simpelweg erg veel code voor je test-case nodig hebt) dan moeten er zeker nog wat dingen versimpeld worden.

Testen is dus voor mij een onderdeel van het ontwikkel-proces en niet een stap welke alleen tijd kost en niks oplevert. En door tussen-tijds de testen is het minder erg als je opeens tegen een boom aan rijd.


Deze manier van testen leid automatisch tot:
- Extreem kleine functies en classen (gemiddeld 10 regels code per functie/methode, anders zijn er teveel mogelijke inputs mogelijk).
- Elke functie/methode als een zwarte doos, als er x in gaat móet er y uitkomen (anders weet je niet of een test het goede resultaat heeft gegeven 8)7 ).
- Meer herbruikbare code (dan hoef je immers niet telkens ongeveer hetzelfde te testen)
- Alleen verwijzingen naar minder specifieke code (voorkomt ontestbare spaghetti code)
- Zelf documenterende code.

seweso's blog


  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

.oisyn schreef op 01 juni 2004 @ 00:41:
Ik doe anders zelden een delete buiten een destructor (met uitzondering van algemene memory management code) :) Over het algemeen gebruik ik daar smart pointers en object owners voor (is het zaakje ook gelijk exception safe)
Da's inderdaad nog beter, al blijf ik erbij dat een extra check door iets als valgrind geen kwaad kan :)

  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

.oisyn schreef op 01 juni 2004 @ 01:02:
En ik noem het PHP core team 'sucky' :Y)
Ik moet desondanks de eeste nog tegencomen die valide argumenten kan geven voor het gebruik Hongaarse notatie, en in mindere mate CaMel casing aka Studdly Caps aka Sucky Caps. Ik ben fanatiek aanhanger van een (grote) groep die het wijgert te gebruikern (al wel in mindere met Camel casing).

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

igmar schreef op 01 juni 2004 @ 11:49:

Ik moet desondanks de eeste nog tegencomen die valide argumenten kan geven voor het gebruik Hongaarse notatie, en in mindere mate CaMel casing aka Studdly Caps aka Sucky Caps. Ik ben fanatiek aanhanger van een (grote) groep die het wijgert te gebruikern (al wel in mindere met Camel casing).
Wat je het liefst hebt is natuurlijk volledig je eigen keuze, ik reageerde alleen maar op je argument dat het PHP Core team iets vindt. Als er wel iets is wat ik niet serieus neem dan is dat het "PHP Core team" wel ;). Consistentie en elegantie komt iig niet in hun vocabulaire voor, laat staan logische semantiek

Overigens ben ik zelf wel fan van camelcasing, java-style (dus functies en variabelen beginnen met een kleine letter), maar ik mix ook wel C++ STL style naamgeving erdoorheen. Echte solide klassen CamelCase ik, maar dingen als PODs en enums schrijf ik over het algemeen in lowercase met een _t erachter, en containers zijn meestal alleen lowercase (Beetje raar dat als je een std::vector en een std::list hebt, dat je dan wel ineens een Oisyn::BinaryTree zou hebbeb. Een oisyn::binarytree past dan beter :)). Namespaces doe ik overigens ook altijd lowercase, en niet van die lange namen (omdat ik ze vaak gewoon volledig typ, en zelden gebruik maak van using directives en declarations)

[ Voor 5% gewijzigd door .oisyn op 01-06-2004 13:56 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

EfBe schreef op 31 mei 2004 @ 09:45:

Ik ben opgegroeid met de gnu commandline debugger op een VAX, ik weet echt wel hoe je programma's moet testen en debuggen en dat er veel tools zijn die veel sneller testen of pre en post condities (want dat ben je toch aan het testen) kloppen dan een debugger. Sterker, tijdens veel debug sessies start ik echt geen debugger op. En nee ik gebruik geen printf's meer.
Ik ben zelf drs. informatica met 4 jaar werkervaring, en ben toch niet op het laagste niveau bezig. Natuurlijk doe ik aan unit testing, af en toe zeer uitgebreid zelfs. Toch maak ik ook gebruik van een debugger voor een snelle test. Sterker nog, ik begin niet eens aan het schrijven van test code als ik niet eerst de code die ik wil testen:

1 Tenminste 1 maal gecompiled heb
2 Snel met een debugger de belangrijkste variabelen gechecked heb

Voor mij is een debugger een zeer handige tool om mijn code snel te controleren en eventueel de stomste dingen er meteen uit te halen.

Pas als de code een beetje stable is, ga ik er uitgebreid unit testen voor schrijven. De debugger komt gewoon een fase daarvoor.
Overigens vind ik je vrij zelfingenomen overkomen, terwijl je de ballen verstand hebt van de tools die tot je beschikking staan.
Volgens mij heb jij ook de ballen verstand van dingen. Iedereen met praktijk ervaring weet dat een dergelijke manier van controleren handig is als de code nog heel jong is. Unit testen hebben in een heel vroeg stadium IMHO nogal weinig zin.

Als jij een debugger stom vindt dan zou je het gewoonweg kijken naar je code ook stom moeten vinden. In zekere zin komt een early run daarop neer; Bij het bekijken van een stukje code vul je ook in gedachten wat waarden in, loopt een stukje door in gedachten, en denkt na over de uitkomst. Een run met de debugger maakt dit concreet. Met unit tests pak je ook niet zomaar even een stukje code midden in een functie.

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

igmar schreef op 31 mei 2004 @ 23:01:
[...]

0 als input is gewoon een geldige int, alleen levert delen door 0 geen geldige waarde op (ook niet geheel correct : Het levert een oneindig getal op, die niet weergegeven kan worden. Ik zet zelf assert()'s in het geval dat een input niet voor mag komen.
Je originele stelling klopt, je 'correctie' niet. De enige manier om een deling door 0 te simuleren is door hem te benaderen, en afhankelijk van de richting van benaderen kom je oftewel op plus of min oneindig uit. Ergo het is niet eens benaderbaar.

Verder is je stelling dat camelCase of PascalCase (camelCase heeft een leading non-caps, ooit een kameel met een bult op z'n kont gezien? ;) ) niet populair zou zijn volstrekt onzin: ieder stuk bedrijfssoftware dat ik ooit heb gezien hanteert het. Leuk dat het PHP core team het niet blijkbaar als enige in deze wereld niet mooi vind, maar daar hecht ik niet echt veel waarde aan totdat ze een fatsoenlijke taal leren opzetten.

Professionele website nodig?


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Pas als de code een beetje stable is, ga ik er uitgebreid unit testen voor schrijven. De debugger komt gewoon een fase daarvoor.
Ik pak de meest stomme fouten er uit met unit testen. Naarmate ik langer achter mijn pc zit, en hoe meer werk ik heb verzet, hoe meer stomme fouten er in komen. Unit testen is voor mij de manier om deze kleine etterbakjes er uit te peuteren. Ik heb zelf een hele fijne debugger bij mijn IDE, maar ik met eerlijk toegeven dat ik hem nooit gebruik.
Volgens mij heb jij ook de ballen verstand van dingen. Iedereen met praktijk ervaring weet dat een dergelijke manier van controleren handig is als de code nog heel jong is. Unit testen hebben in een heel vroeg stadium IMHO nogal weinig zin.
Juist niet. Hoe jonger de code is, hoe beter unittesting is voor de 'controleren' Met een unittest is het juist zo handig dat je niet een compleet systeem hoeft te hebben om het in te testen, maar dat je een enkel object of zelfs een enkele methode kunt doorfluiten. Vandaar ook 'unit' test: de kleinste eenheid in je systeem: een methode. In principe als je al op meerdere objecten tegelijk bezig bent, zit je al aan de integration tests.
Als jij een debugger stom vindt dan zou je het gewoonweg kijken naar je code ook stom moeten vinden.
Het is dat het zo raar staat maar anders zou ik er behang van laten maken zodat ik er de hele dag naar kan kijken :P
In zekere zin komt een early run daarop neer; Bij het bekijken van een stukje code vul je ook in gedachten wat waarden in, loopt een stukje door in gedachten, en denkt na over de uitkomst. Een run met de debugger maakt dit concreet. Met unit tests pak je ook niet zomaar even een stukje code midden in een functie.
Ik ben het met je eens dat je minder makkelijk in een functie kunt kijken. Maar over het algemeen zijn mijn functies dermate klein dat ik daar niet zo vaak de behoefte aan heb. Ik test het van buitenaf op een aantal testscenario`s en dan is het kijken of het resultaat/verandering-aan-de-omgeving klopt.

[ Voor 5% gewijzigd door Alarmnummer op 02-06-2004 07:17 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
En handige techniek om je testen uit te voeren is om niet zozeer positief te testen, maar om te testen om je je code ook om zeep kan helpen. Dan ga je veel agressiever bezig om gaten in je code te vinden en eventueel af te schermen (met exceptions bv).

Verwijderd

Alarmnummer schreef op 02 juni 2004 @ 07:15:
[...]

Ik pak de meest stomme fouten er uit met unit testen. Naarmate ik langer achter mijn pc zit, en hoe meer werk ik heb verzet, hoe meer stomme fouten er in komen.
Je bedoelt dat als je moe wordt dat je dan rare fouten gaat maken? Dan heb ik ook wel eens, zeker aan het eind van een werk dag als het ook nog eens druk is geweest en ik vaak onderbroken wordt voor problemen in hele andere stukken code dan waar ik nu aan werk.

Af en toe programmeer ik dan 'op de automatische' piloot, heel raar, maar dan heb ik gewoon hele stukken code ingetikt zonder er echt bij na te denken. Een beetje zoals je een vaste route naar huis rijdt zonder na te denken. Als dat gebeurt weet ik dat het tijd is om naar huis te gaan :-) (en de code te wisssen)
Unit testen is voor mij de manier om deze kleine etterbakjes er uit te peuteren. Ik heb zelf een hele fijne debugger bij mijn IDE, maar ik met eerlijk toegeven dat ik hem nooit gebruik.
For the record, welke IDE gebruik je dan?
Het is dat het zo raar staat maar anders zou ik er behang van laten maken zodat ik er de hele dag naar kan kijken :P
Nou, op de universiteit waar ik zat (UL) hangen er best wel een aantal algorithmes aan de muren hoor en een stukje code hangt er ook wel af en toe :-)
Ik ben het met je eens dat je minder makkelijk in een functie kunt kijken. Maar over het algemeen zijn mijn functies dermate klein dat ik daar niet zo vaak de behoefte aan heb.
Natuurlijk, maar je wilt ook weer niet voor elk stukje code een aparte functie schrijven. Als ik nog een beetje aan het 'code-schetsen' ben wil ik wel eens kijken of alles tot een bepaald stukje een beetje aan de verwachtingen voldoet. Asserts helpen natuurlijk ook in zo'n geval.

Waar ik de debugger ook nog wel eens voor wil gebruiken is om een beeld van code te krijgen die ik niet zelf geschreven heb. In dat geval step ik deze een beetje snel door om een beetje een idee van de samenhang te krijgen.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
Verwijderd schreef op 02 juni 2004 @ 22:20:
For the record, welke IDE gebruik je dan?
Intellij IDEA en Codeguide (met een hele krachtige debugger schijnt het:)

Codeguide debugger
Nou, op de universiteit waar ik zat (UL) hangen er best wel een aantal algorithmes aan de muren hoor en een stukje code hangt er ook wel af en toe :-)
*voelt zich eindelijk begrepen*.. :P
Natuurlijk, maar je wilt ook weer niet voor elk stukje code een aparte functie schrijven. Als ik nog een beetje aan het 'code-schetsen' ben wil ik wel eens kijken of alles tot een bepaald stukje een beetje aan de verwachtingen voldoet. Asserts helpen natuurlijk ook in zo'n geval.
Gecompliceerde functies staan bij mij vol met asserts.
Waar ik de debugger ook nog wel eens voor wil gebruiken is om een beeld van code te krijgen die ik niet zelf geschreven heb. In dat geval step ik deze een beetje snel door om een beetje een idee van de samenhang te krijgen.
Ik heb tot zover het geluk gehad dat ik altijd goeie code van anderen heb kunnen gebruiken of het kunnen wijgeren/weggooien.

  • igmar
  • Registratie: April 2000
  • Laatst online: 12-05 15:46

igmar

ISO20022

curry684 schreef op 02 juni 2004 @ 02:10:
Je originele stelling klopt, je 'correctie' niet. De enige manier om een deling door 0 te simuleren is door hem te benaderen, en afhankelijk van de richting van benaderen kom je oftewel op plus of min oneindig uit. Ergo het is niet eens benaderbaar.
Dat zal d'r vanaf hangen of een deling door 0 wiskundig is definieert, en dat kun je beter niet aan mij vragen :P
Verder is je stelling dat camelCase of PascalCase (camelCase heeft een leading non-caps, ooit een kameel met een bult op z'n kont gezien? ;) ) niet populair zou zijn volstrekt onzin: ieder stuk bedrijfssoftware dat ik ooit heb gezien hanteert het.
Omdat de meeste bedrijfssoftware voor Windows is geschreven ? Ik zie het bijna nooit in OSS C code, wel bv in OSS C++. Verder is het een kwestie van smaak : Ik zelf gebruik het niet en ga het ook niet gebruiken, het is mij iig niet zo aangeleerd. Indien een project het wel gebruikt zal ik me daar gewoon bij aansluiten, net zoals ik alle codingstyles in acht neem.
Leuk dat het PHP core team het niet blijkbaar als enige in deze wereld niet mooi vind, maar daar hecht ik niet echt veel waarde aan totdat ze een fatsoenlijke taal leren opzetten.
Sja.. Ik noem de kernel, libc, openssl, zowat alle GNU tools toch geen 'kleine' projecten, en die gebruiken het niet. Ik zelf val er niet zo erg over, het enige waar ik wel een probleem mee heb zijn type prefixes, aka Hongarian Notation. Geef mij overigens maar Python of Java :)

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op 02 juni 2004 @ 00:05:
Ik ben zelf drs. informatica met 4 jaar werkervaring, en ben toch niet op het laagste niveau bezig.
Ik ben ing. informatica en 10 jaar werkervaring en ik ben ook niet op het laagste niveau bezig, maar wat heeft dit voor band met wat bediscussieerd werd? :)
Natuurlijk doe ik aan unit testing, af en toe zeer uitgebreid zelfs. Toch maak ik ook gebruik van een debugger voor een snelle test. Sterker nog, ik begin niet eens aan het schrijven van test code als ik niet eerst de code die ik wil testen:

1 Tenminste 1 maal gecompiled heb
2 Snel met een debugger de belangrijkste variabelen gechecked heb
Dat is een methode inderdaad. Het gaat er mij om dat men door heeft dat:
1) het algorithme dat geimplementeerd is, uberhaupt klopt
2) het algorithme dat geimplementeerd is, goed is geimplementeerd (dus code terugvertalen naar algorithme, checken of dat inderdaad het algorithme is dat geimplementeerd moest worden)
Hoe je 2) doet is aan de programmeur natuurlijk. Ik heb echter na 10 jaar echt geen debugger meer nodig om te kijken hoe code zich gedraagd. Waar ik wel een debugger voor nodig heb is de invloed van de flow van programmatuur door de applicatie, maw: method A doet iets, roept B aan en wat A deed is van invloed op B's uitkomst bijvoorbeeld. Dan kun je B controlleren, maar nooit echt goed zonder tezamen met A te checken. Dit kan dermate complex worden dat je dingen over het hoofd gaat zien.

Ik heb echter wel mn vraagtekens bij het visueel checken van state. Dit komt omdat een mens fouten maakt EN het tijdrovend is. Een setje asserts test ook state en doet dat stukken sneller EN correct in 100% van de gevallen.
Volgens mij heb jij ook de ballen verstand van dingen. Iedereen met praktijk ervaring weet dat een dergelijke manier van controleren handig is als de code nog heel jong is. Unit testen hebben in een heel vroeg stadium IMHO nogal weinig zin.
Nou, volgens mij moet jij beter lezen. Ten eerste durf ik de stelling wel aan dat ik meer van mn vak weet dan jij en ten tweede heb jij het mis in deze: een debugger is NIET bedoeld voor het checken van state, puur en alleen omdat het VISUEEL checken van state at time T:
1) traag is
2) error prone.
Nu weet ik het niet, maar volgens mij is een foutgevoelige testmanier geen juiste manier van het testen van state zoals jij dat wilt /doet
Als jij een debugger stom vindt dan zou je het gewoonweg kijken naar je code ook stom moeten vinden.
Wie zegt dat ik een debugger stom vindt? Ten eerste is het 'dom', en niet 'stom', en ten tweede is een debugger soms heel nuttig, alleen niet voor het checken van state zoals jij doet. Met een aantal asserts test je nl. ook state zonder een trage debug run te starten en in locals / watch windows values te checken.
In zekere zin komt een early run daarop neer; Bij het bekijken van een stukje code vul je ook in gedachten wat waarden in, loopt een stukje door in gedachten, en denkt na over de uitkomst. Een run met de debugger maakt dit concreet. Met unit tests pak je ook niet zomaar even een stukje code midden in een functie.
Ik doe heel veel testruns van code dat ik net heb geschreven, zodat ik weet dat het werkt. Ik heb daar echter geen debugger voor nodig en ook geen printf's. Wat denk je zelf, dat ik 3MB aan sourcecode in de debugger ga zitten verifyen? Dat is veel te tijdrovend en omdat het tijdrovend is, is de mens in algemene zin (jij wellicht niet volgens je eigen zelfbeeld) bij tijdrovende zaken minder tijd te nemen dan eigenlijk zou moeten. Een assert doet dat nooit, die doet gewoon wat hem opgedragen wordt.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • pkouwer
  • Registratie: November 2001
  • Laatst online: 07-10-2025
even een reactie tussendoor:

Ik heb dit topic globaal doorgelezen en wat mij opvalt is dat deze testmethoden gehanteerd worden door prof. programmeurs die er hun fulltime job aan hebben. Daarnaast zijn er imho legio tweakers die niet zo ver gevorderd zijn dat ze full-time programmeren en eventueel een stapje lager. Zelf ben ik wel 3/4 vd. tijd aan het programmeren, maar wel op een lager niveau dan dit topic doet vermoeden.

Deze categorie programmeurs zijn dus eigenlijk niet gebaat bij het smijten van moeilijke termen en technologieen als het om testen gaat (=noflame). Is het niet mogelijk om ook deze mensen van informatie te voorzien hoe zij/wij de applicaties kunnen testen zonder al te ingewikkelde studies te moeten volgen.

Het is maar een idee, maar doe er je voordeel mee.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Als je bepaalde termen niet kent, kan je natuurlijk altijd gaan opzoeken wat die termen betekenen en wat ze inhouden.
Zo kan je er ook je voordeel meedoen.

https://fgheysels.github.io/


  • pkouwer
  • Registratie: November 2001
  • Laatst online: 07-10-2025
dat is niet de essentie van mijn verhaal. Het gaat om het testen in het algemeen, niet om taalkundige betekenissen.

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
pkouwer schreef op 03 juni 2004 @ 11:29:
dat is niet de essentie van mijn verhaal. Het gaat om het testen in het algemeen, niet om taalkundige betekenissen.
Als je de reply van whoami goed leest (zowel taalkundig als inhoudelijk), dan zie je het werkwoord inhouden gebruikt worden. Dit betekent dus dat je moet uitzoeken wat bijvoorbeeld Unit testen inhoudt.

Misschien kun je een eigen topic openen wat meer voldoet aan je specifieke wensen? Het is namelijk zo dat de TS in principe zijn onderwerp afbakent en dat de rest daarop reageert.

  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

mbravenboer schreef op 31 mei 2004 @ 19:00:
Om even op het de zwaarte van testen door te gaan: meten is weten :P . Gebruikt iemand code coverage tools om te kijken hoe goed de unit tests de code dekken?
Ik gebruik de coverage-profiler om te kijken waar de bottle-necks in mijn code zitten. Ik moet wel zeggen dat de coverage-profiler standaard in een modus staat waardoor je in één oog-opslag kan zien welke code níet is uitgevoerd, maar daar kijk ik eigenlijk nooit naar.

Laat is eens voor de lol even kijken... hmm ja is op zich wel handig om snel wat test-cases te verzinnen. En als ik ook zorg dat die test-cases volledig automatisch kunnen worden uitgevoerd en gecontroleerd.... ja dat zou mooi zijn. Maar de realiteit is anders. Daar heb je meestal simpelweg de tijd niet voor.

Als het gaat om hoe zwaar je test dan kun je op het niveau van NASA werken of ... helemaal niet. Waarbij één ding duidelijk is dat beide extremen geen echte optie is, en dus ligt de waarheid ergens in het midden.

Persoonlijk ben ik wel benieuwd naar de achterliggende redenen waarom sommige heel gedetailleerd moeten testen, en om wat voor een projecten dat dan gaat...

seweso's blog


  • EfBe
  • Registratie: Januari 2000
  • Niet online
pkouwer schreef op 03 juni 2004 @ 10:36:
Ik heb dit topic globaal doorgelezen en wat mij opvalt is dat deze testmethoden gehanteerd worden door prof. programmeurs die er hun fulltime job aan hebben. Daarnaast zijn er imho legio tweakers die niet zo ver gevorderd zijn dat ze full-time programmeren en eventueel een stapje lager. Zelf ben ik wel 3/4 vd. tijd aan het programmeren, maar wel op een lager niveau dan dit topic doet vermoeden.

Deze categorie programmeurs zijn dus eigenlijk niet gebaat bij het smijten van moeilijke termen en technologieen als het om testen gaat (=noflame). Is het niet mogelijk om ook deze mensen van informatie te voorzien hoe zij/wij de applicaties kunnen testen zonder al te ingewikkelde studies te moeten volgen.
Termen als unit testen lijken nieuw terwijl de achterliggende techniek al zo oud is als software development zelf. Ik denk dat als je de termen wat opzoekt op internet, de achterliggende technieken je bekend voor zullen komen en het verhaal dan duidelijk wordt. Voorbeeld: ik doe al jaren aan geprogrammeerde tests, maar gebruik geen unit tester (nog, ga ik wel doen) ook vanwege de complexiteit van sommige tests. Maar ik ben wel aan het unit testen, alleen niet via een unit testing framework. Zo moet je ook tegen deze technieken aankijken, het is veelal iets dat je al zelf gebruikt maar je kent de term niet.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
seweso schreef op 03 juni 2004 @ 11:52:
[...]

Persoonlijk ben ik wel benieuwd naar de achterliggende redenen waarom sommige heel gedetailleerd moeten testen, en om wat voor een projecten dat dan gaat...
Euh, om ervoor te zorgen dat je software zo weinig mogelijk fouten bevat, en dat je die test-resultaten ook als een soort bewijs kunt gebruiken dat je software correct werkt misschien ?

https://fgheysels.github.io/


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
seweso schreef op 03 juni 2004 @ 11:52:
[...]
Ik gebruik de coverage-profiler om te kijken waar de bottle-necks in mijn code Laat is eens voor de lol even kijken... hmm ja is op zich wel handig om snel wat test-cases te verzinnen. En als ik ook zorg dat die test-cases volledig automatisch kunnen worden uitgevoerd en gecontroleerd.... ja dat zou mooi zijn. Maar de realiteit is anders. Daar heb je meestal simpelweg de tijd niet voor.
Hoe vaak ben jij een uur kwijt om te zoeken naar een bug? En hoeveel sourcecode moet je daar gemiddeld voor door bladeren?
Als het gaat om hoe zwaar je test dan kun je op het niveau van NASA werken of ... helemaal niet. Waarbij één ding duidelijk is dat beide extremen geen echte optie is, en dus ligt de waarheid ergens in het midden.
De kunst van het unit testen is op zoek te gaan naar het punt dat unit testen uit kan. Ik ben door meer unit testen minder tijd nodig met ontwikkeling en zorg ervoor dat mijn api`s sluitend(er) zijn dan zonder testen. Maar je kunt uiteindelijk ook alles gaan testen, maar dan heb je geen tijdswinst meer. Unit testen levert mij dus tijdswinst op doordat ik een reeks testen maak waarbij ik met relatief weinig moeite de meeste bugs eruit kan pakken.
Persoonlijk ben ik wel benieuwd naar de achterliggende redenen waarom sommige heel gedetailleerd moeten testen, en om wat voor een projecten dat dan gaat...
In principe alles wat niet triviaal is. Een of andere setter of getter is imho volslagen zinloos om te testen. Maar zo gauw er een beetje meer complexiteit bij komt te kijken -> unit test.


Een voorbeeld van een unit test. De isGround functie bepaald of in een term geen variablen voorkomen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public static class IsGroundTestCase extends TestCase {

    public IsGroundTestCase(String fixture) {
        super(fixture);
    }

    public void testConstant() {
        Constant constant = new Constant(10);
        assertTrue(constant.isGround());
    }

    public void testVarTerm() {
        VarTerm varTerm = new VarTerm(new Variable("A"));
        assertFalse(varTerm.isGround());
    }

    public void testAtom() {
        Struct struct = new Struct("a");
        assertTrue(struct.isGround());
    }

    public void testNonVarStruct() {
        Struct struct = new Struct("a", Struct.TRUE, Struct.FAIL);
        assertTrue(struct.isGround());
    }

    public void testVarStruct() {
        Struct struct = new Struct("a", new VarTerm(new Variable("A")));
        assertFalse(struct.isGround());
    }
}

[ Voor 27% gewijzigd door Alarmnummer op 03-06-2004 12:21 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Alarmnummer: Mja, dit zegt een beetje weinig. Misschien moet je een simpeler voorbeeld kiezen en even uitleggen wat je nou precies aan het testen bent, ipv een copy-paste uit je prolog compiler ;)

[ Voor 5% gewijzigd door .oisyn op 03-06-2004 15:28 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
.oisyn schreef op 03 juni 2004 @ 15:28:
Alarmnummer: Mja, dit zegt een beetje weinig. Misschien moet je een simpeler voorbeeld kiezen en even uitleggen wat je nou precies aan het testen bent, ipv een copy-paste uit je prolog compiler ;)
Ik heb snel even een voorbeeldje in elkaar geplakt voor een stack een hierin worden een aantal methoden getest (niet allemaal want het is een voorbeeld :P)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class StackTestCase extends TestCase{

    private Stack _stack = new Stack();

    public StackTestCase(String fixture){
        super(fixture);
    }
    
    public void test_pop_fromEmptyStack(){
        try{
            _stack.pop();
            fail("EmptyStackException expected");
        }catch(EmptyStackException ex){
        }
    }
    
    public void test_pop_fromNonEmptyStack(){
        Object item = "bla";
        _stack.push(item);
        
        Object foundItem = _stack.pop();
        assertSame(item,foundItem);
        assertTrue(_stack.isEmpty());
    }
    
    public void test_isEmpty_onNonEmptyStack(){
        _stack.push("onzin);
        assertFalse(_stack.isEmpty());
    }
    
    public void test_isEmpty_onEmptyStack(){
        assertTrue(_stack.isEmpty());
    }
}



Ik zal ook meteen even het stuk van mijn ANT-script erbij zetten. Alle unittesten die worden automatisch uitgevoerd, zo lang de testsuites maar eindigen op TestSuite.java.

XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<target name="test.run"
            depends="clean,compile.core,compile.parser"
            description="Tests sourcefiles against answerfiles">
        
        <mkdir dir="${classes.junit}"/>
            
        <javac  srcdir="${src.run-test}"
                debug="on"
                destdir="${classes.junit}"
                source="1.5">
                
            <classpath>
                <pathelement path="${classes.core}"/>
                <pathelement path="${classes.parser}"/>
                <fileset dir="${lib}">
                    <include name="**/*.jar"/>
                </fileset>
                <fileset dir="${test-lib}">
                    <include name="**/*.jar"/>
                </fileset>  
            </classpath>
        </javac>

        <mkdir dir="${junit-reports}"/>

        <junit haltonerror="yes" fork="on" printsummary="on">
            <classpath>
                <pathelement path="${classes.core}"/>
                <pathelement path="${classes.parser}"/>
                <pathelement path="${classes.junit}"/>
                <fileset dir="${lib}">
                    <include name="**/*.jar"/>
                </fileset>
                <fileset dir="${test-lib}">
                    <include name="**/*.jar"/>
                </fileset>  
            </classpath>
            
            <formatter type="plain"/>
            <jvmarg value="-ea"/>
            <jvmarg value="-Xbootclasspath/p:${jsr14.home}/gjc-rt.jar"/>
                                
            <batchtest todir="${junit-reports}">
                <fileset dir="${src.run-test}">
                    <include name="**/*TestSuite.java"/>
                </fileset>
            </batchtest>            
        </junit>
    </target>

[ Voor 45% gewijzigd door Alarmnummer op 03-06-2004 15:58 ]


  • MaxxRide
  • Registratie: April 2000
  • Laatst online: 09-01 10:13

MaxxRide

Surf's up

Ik moet zeggen dat ik erg onder de indruk ben van Junit.org testframework. Ik heb me nooit echt (willen) verdiept in unit testing. Met deze discussie zijn mijn ogen behoorlijk geopend (het is niet dat ik het nut er niet van in zag maar meer dat ik het nog niet echt kende oid).

Dit is echt cool en in grote projecten en bij moeilijke functies etc zeer bruikbaar! Super dit!

If you are not wiping out you are nog pushing enough...


  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Alarmnummer schreef op 03 juni 2004 @ 12:15:
[...]

Hoe vaak ben jij een uur kwijt om te zoeken naar een bug? En hoeveel sourcecode moet je daar gemiddeld voor door bladeren?
Nooit eigenlijk. En alle keren dat ik een grote zoektocht was begonnen naar een bug bleek die eigenlijk helemaal niet te bestaan en had een gebruiker iets verkeerd ingesteld (zoals een tv die kapot is omdat de stekker er niet in zit).
[...]

De kunst van het unit testen is op zoek te gaan naar het punt dat unit testen uit kan. Ik ben door meer unit testen minder tijd nodig met ontwikkeling en zorg ervoor dat mijn api`s sluitend(er) zijn dan zonder testen. Maar je kunt uiteindelijk ook alles gaan testen, maar dan heb je geen tijdswinst meer. Unit testen levert mij dus tijdswinst op doordat ik een reeks testen maak waarbij ik met relatief weinig moeite de meeste bugs eruit kan pakken.
Volgens mij ben ik nou net met iets bezig waar unit-testen niet zo relevant zou zijn. Want eigenlijk is het systeem wat ik nu aan het maken ben één grote setter en getter. Je stop er X,Y en Z in en er moet X,Y en Z weer uitkomen. Als dat werkt dan heb ik de unit-test toch niet (meer) nodig?

Kun je iets meer achtergrond info waar jij deze zware manier van testen dan voor nodig hebt?

seweso's blog


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
seweso schreef op 03 juni 2004 @ 16:38:
[...]
Nooit eigenlijk. En alle keren dat ik een grote zoektocht was begonnen naar een bug bleek die eigenlijk helemaal niet te bestaan en had een gebruiker iets verkeerd ingesteld (zoals een tv die kapot is omdat de stekker er niet in zit).
Vertel jij nu dat alle software die je schrijft nooit een bug bevat? Damn, misschien moet je eens naar Bill bellen.
Volgens mij ben ik nou net met iets bezig waar unit-testen niet zo relevant zou zijn. Want eigenlijk is het systeem wat ik nu aan het maken ben één grote setter en getter. Je stop er X,Y en Z in en er moet X,Y en Z weer uitkomen. Als dat werkt dan heb ik de unit-test toch niet (meer) nodig?
En die 'setter' wordt door geen enkele andere applicatie / method / oid gebruikt, en gebruikt ook geen enkele andere method ?
Trouwens om na te gaan of die functie werkt, zal je ze toch op de een of andere manier moeten testen.
Verder ontgaat me de bedoeling ook van een systeem als hetgeen eruit komt precies hetzelfde is als hetgeen je erin gestoken hebt, maar dat is een andere discussie.

[ Voor 14% gewijzigd door whoami op 03-06-2004 16:44 ]

https://fgheysels.github.io/


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
seweso schreef op 03 juni 2004 @ 16:38:
Nooit eigenlijk. En alle keren dat ik een grote zoektocht was begonnen naar een bug bleek die eigenlijk helemaal niet te bestaan en had een gebruiker iets verkeerd ingesteld (zoals een tv die kapot is omdat de stekker er niet in zit).
a) je hebt nog niet veel ervaring
b) je bent goddelijk :P
c) je liegt ;)
Volgens mij ben ik nou net met iets bezig waar unit-testen niet zo relevant zou zijn. Want eigenlijk is het systeem wat ik nu aan het maken ben één grote setter en getter. Je stop er X,Y en Z in en er moet X,Y en Z weer uitkomen. Als dat werkt dan heb ik de unit-test toch niet (meer) nodig?
Kijk eens naar die unit test. Is die ingewikkeld? Het stel echt niet veel voor hoor? En als je je scripts een beetje goed instelt dan is zelfs het draaien een peuleschil.
Kun je iets meer achtergrond info waar jij deze zware manier van testen dan voor nodig hebt?
Eigelijk alles wat niet triviaal is zou je kunnen unit testen. Als jij kan garanderen dat je weinig fouten in je code hebt, dan is unit testen misschien niet voor jou. Maar ik en de andere developers zijn it-ers van vlees en bloed. En wij maken gewoon fouten. Sommige fouten zijn ongelovelijk stom, maar je hebt ook veel gecompliceerdere fouten. Op het moment dat je een groot systeem hebt met veel complexiteit, dan is het een drama om een bug op te sporen omdat die op veel punten kan zijn ontstaan. Met unit testen kan je voor subsystemen zeggen dat de kans redelijk klein is dat de fout daar is ontstaan omdat die getest zijn. Hierdoor kan je je op een kleiner gebied concentreren om de bug te achterhalen. In de praktijk is het trouwens niet altijd even eenvoudig hoor :) Zelfs subsystemen kunnen met goed unit testen nog fouten veroorzaken en dan is het nog steeds lastig om te achterhalen waar de bug zit. Maar als je toch moet debuggen, dan wil ik hier in de toekomst ook een meerwaarde van hebben, en dat heb je alleen met unittesten en niet met een debugger/printlines.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22:08

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik gebruik zelf overigens ook nooit unittests, maar dat is ook mede omdat dat een beetje lastig is met de code die ik schrijf. Hoe bepaal je bijvoorbeeld of een object wel goed is gerenderd in een 3D omgeving? Of dat het collision systeem wel goed werkt? Ik kan eigenlijk geen enkel geometrisch algoritme bedenken wat wel goed te testen is. Eigenlijk is dat gewoon een kwestie van veel runnen en met een menselijk oog kijken of het goed gaat :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • RSchellhorn
  • Registratie: Augustus 2001
  • Laatst online: 19-05 12:56
Een punt wat ik hier nog niet gelezen heb, is dat je een testsuite niet alleen voor jezelf schrijft. Als later iemand anders je code moet aanpassen, is het voor hem ook een hulpmiddel om te checken welke gevolgen een verandering heeft.
Voorwaarde hiervoor is wel dat de unittests ook daadwerkelijk voor elke unit ( klassen & methode ) geschreven wordt.

Ik ben van mening dat een testsuite en het checken van pre- en postcondities iets essentieels is voor projecten waar meer dan één persoon aan werkt. Als je met meer mensen werkt, moet je elke unit beschermen tegen foutief gebruik door anderen. Andere mensen moeten zich ergens op kunnen richten, anders is er niet met je units te werken.

"Ik heb zo veel soep gegeten, dat kan een mens niet aan. Ik heb zo veel soep gegeten, kan bijna niet meer staan. Ik zat daar maar te slurpen achter die grote kop en als ik bijna klaar was, dan schepten ze weer op!" (Hans Teeuwen)


  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Alarmnummer schreef op 03 juni 2004 @ 16:47:
[...]

a) je hebt nog niet veel ervaring
b) je bent goddelijk :P
c) je liegt ;)
a) ik ben pas 2jr ing informaticus
b) mijn psychiater noemt dat grootheidswaanzin
c) ik lieg niet, ik tel gewoon alle spaghetti programma's die ik heb opgeleverd niet mee
Kijk eens naar die unit test. Is die ingewikkeld? Het stel echt niet veel voor hoor? En als je je scripts een beetje goed instelt dan is zelfs het draaien een peuleschil.
Ja die is ingewikkeld. Maar dat zal wel met de ingewikkeldheid van je applicatie te maken hebben. Maar ik zie zeker voordelen in unit-testen, vooral als form van documentatie. Daarnaast denk ik dat het zorgvuldig en tijdig testen van delen van een systeem uiteindelijk zal leiden tot een beter systeem, en dan bedoel ik qua ontwerp en niet alleen omdat er minder bugs in zullen zitten.
Eigelijk alles wat niet triviaal is zou je kunnen unit testen. ....
Jij denkt dus dat ik alleen bezig ben met triviale dingen?

seweso's blog


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
seweso schreef op 03 juni 2004 @ 22:33:
[...]
Jij denkt dus dat ik alleen bezig ben met triviale dingen?
Dat heb ik niet gezegd :) Jij vroeg wat je allemaal moest testen. En ik zeg: alles wat niet triviaal is (dus geen getters en setters). Alles waar een klein beetje complexiteit in zit (in principe al dat stackvoorbeeld) 'moet' geunit test worden.

[ Voor 3% gewijzigd door Alarmnummer op 03-06-2004 22:46 ]


  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Hoe maak je hier unit-test voor dan? (ff wat concrete voorbeelden die ik uit m'n source-tree heb gehaald)
1. Een functie die excel-cellen die op het klembord staan automatisch omvormt naar een array.
2. Een wachtwoord generatie-functie
3. Een functie die de tijd terug-geeft van een centrale server.
4. Functies en objecten die gegevens uit een database halen (database abstractie-laag).
5. Xml lezen, schrijven en tranformeren.
6. Externe programma's en api's aanroepen zoals MS-Word, xml/xhtml invoegen in een samengevoegd ms-word-document.
7. Conversie functies (b.v. speciale karakters uit een string halen)
8. Functies en classen t.b.v. de grafische user-interface.
9. Functie om te bepalen of iets een werkdag is.
10. Classen/functies waarmee je de beschikking krijgt over een 'oneindig' aantal velden die je aan elke tabel/object kan koppelen.

Ik heb het misschien mis, maar volgens mij kost het maken van bovenstaande unit-tests meer tijd dan de functies/classen zelf...

Ik ben als het gaat om testen heel pragmatisch: als het werkt dan werkt het.

seweso's blog


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:44

Creepy

Tactical Espionage Splatterer

seweso schreef op 03 juni 2004 @ 23:26:
Ik heb het misschien mis, maar volgens mij kost het maken van bovenstaande unit-tests meer tijd dan de functies/classen zelf...

Ik ben als het gaat om testen heel pragmatisch: als het werkt dan werkt het.
Jij hebt dus geen bugs in je code? Jij pas nooit je functies aan?

Als je je unit tests al hebt, hoef je ze na het bugfixen van bugs niet aan te passen en kan je de tests gebruiken om je bugfix te testen. Zeker met complexere code levert het uiteindelijk tijdwinst op.

Overigens vraag je hoe een aantal gevalen te unit testen. Unit testen doe je op losse functies en methods. Die hebben allemaal pre en post condities. Daar test je dus op.
En als je bij jou voorbeeld 2 (wachtwoord generatie) niet een unit test kan schijven in minder tijd dan waarin je je wachtwoord functie hebt geschreven dan is er denk ik iets mis ;)
De rest van je voorbeelden (op 1 na) beschrijven allemaal meerdere gevallen i.p.v. 1 losse method.
Visuele dingen kan je niet unit testen nee, dus dat wordt wat moeilijk. Maar zodra je een functie of method hebt met een input die dan een bepaalde output waarde moet hebben dan is het unit testen in principe vrij makkelijk. Eenmaal je unit tests geschreven en je hebt er daarna alleen maar tijdwinst door als de functies / methods aangepast zijn. Je hoeft dan niet meer handmatig te testen.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • seweso
  • Registratie: Augustus 2003
  • Laatst online: 04-04-2018

seweso

de mouw is uit de aap

Creepy schreef op 03 juni 2004 @ 23:40:
[...]

Jij hebt dus geen bugs in je code? Jij pas nooit je functies aan?

Als je je unit tests al hebt, hoef je ze na het bugfixen van bugs niet aan te passen en kan je de tests gebruiken om je bugfix te testen. Zeker met complexere code levert het uiteindelijk tijdwinst op.

Overigens vraag je hoe een aantal gevalen te unit testen. Unit testen doe je op losse functies en methods. Die hebben allemaal pre en post condities. Daar test je dus op.
En als je bij jou voorbeeld 2 (wachtwoord generatie) niet een unit test kan schijven in minder tijd dan waarin je je wachtwoord functie hebt geschreven dan is er denk ik iets mis ;)
De rest van je voorbeelden (op 1 na) beschrijven allemaal meerdere gevallen i.p.v. 1 losse method.
Visuele dingen kan je niet unit testen nee, dus dat wordt wat moeilijk. Maar zodra je een functie of method hebt met een input die dan een bepaalde output waarde moet hebben dan is het unit testen in principe vrij makkelijk. Eenmaal je unit tests geschreven en je hebt er daarna alleen maar tijdwinst door als de functies / methods aangepast zijn. Je hoeft dan niet meer handmatig te testen.
Ff kijken of je gelijk hebt...

1. 1 functie (15 regels code, 15 minuten)
2. 1 functie (15 regels code, 4 minuten)
3. 1 functie (1 regel code, 1 minuut excl server side prog.)
4. 1 functie (20 regels code, 2 uur, generieke dlookup functie)
5. Word uiteraard (grotendeels) uitbesteed aan msxml2
6. 1 functie (30 regels code, 6 uur)
7. Verscheidene kleine functies
8. Functies en classen t.b.v. de grafische user-interface.
9. 1 functie
10. Aap

Eeh nee, het merendeel is wél één functie...

En ja ik snap dat je voor een wachtwoord-generatie programma een unit-test kan maken voor de pre- en post-condities. Maar om de pre en post-condities te controleren heb assert functies voor (wat al eerder in dit Topic is genoemd). Waar je op zou moeten testen is of de output wel degelijk random is, én niet overeenkomt met de vorige start van de applicatie. Maar ja als je de functie eenmalig schrijft en er vervolgens nooit meer iets aan gaat wijzigen....

Dus..of mij overtuigen dat ik het ook nodig heb, of aangeven waarom jullie die unit-test wél nodig hebben.

En is het niet zo dat je unit-test nodig hebt in Java omdat je daar geen command-window hebt?

seweso's blog


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
seweso schreef op 04 juni 2004 @ 01:02:
[...]

Dus..of mij overtuigen dat ik het ook nodig heb, of aangeven waarom jullie die unit-test wél nodig hebben.
Unit tests zijn niet noodzakelijk, ze zijn alleen handig en kunnen de ontwikkeltijd verminderen doordat je sneller je componenten kunt testen (nagaan of ze correct werken) als je er veranderingen aan gedaan hebt.
En is het niet zo dat je unit-test nodig hebt in Java omdat je daar geen command-window hebt?
Wat heeft een command window ermee te maken? :?

https://fgheysels.github.io/


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:44

Creepy

Tactical Espionage Splatterer

seweso schreef op 04 juni 2004 @ 01:02:
[...]


Ff kijken of je gelijk hebt...

1. 1 functie (15 regels code, 15 minuten)
2. 1 functie (15 regels code, 4 minuten)
3. 1 functie (1 regel code, 1 minuut excl server side prog.)
4. 1 functie (20 regels code, 2 uur, generieke dlookup functie)
5. Word uiteraard (grotendeels) uitbesteed aan msxml2
6. 1 functie (30 regels code, 6 uur)
7. Verscheidene kleine functies
8. Functies en classen t.b.v. de grafische user-interface.
9. 1 functie
10. Aap

Eeh nee, het merendeel is wél één functie...
Mooi, dan zijn unit tests er dus makkelijk voor te schrijven :D
En ja ik snap dat je voor een wachtwoord-generatie programma een unit-test kan maken voor de pre- en post-condities. Maar om de pre en post-condities te controleren heb assert functies voor (wat al eerder in dit Topic is genoemd). Waar je op zou moeten testen is of de output wel degelijk random is, én niet overeenkomt met de vorige start van de applicatie.
Je kan prima een unit test schrijven die 2 keer je passwoord generatie functie aanroept, en deze twee passworden vergelijkt.
Maar ja als je de functie eenmalig schrijft en er vervolgens nooit meer iets aan gaat wijzigen....
Ah... sue me. Ik maak wel eens fouten in mijn code. Er zitten wel eens bugs in mijn functies ook al denk ik dat ze goed werken. En af en toe doe ik zelfs wat optimalisaties ;)
Dus..of mij overtuigen dat ik het ook nodig heb, of aangeven waarom jullie die unit-test wél nodig hebben.

En is het niet zo dat je unit-test nodig hebt in Java omdat je daar geen command-window hebt?
Tuurlijk kan je ook asserts gebruiken, maar zorg je er dan wel voor dat je die asserts weer netjes uitzet op het moment dat je uitlevert aan een klant? Het zou niet de eerste keer zijn dat ik, zelfs in "goed" werkende software de asserts voorbij zie vliegen op de commandline.
En hoe test je met een assert of de output klopt met de input? In de aanroepende code?

En dat je in java geen commandline hebt is bull. Ik ben unit tests gaan gebruiken toen ik met Delphi bezig was. Unit testen is echt niet een specifiek java iets.

Edit: tuurlijk kan je ook zonder unit tests de boel doortesten, of laten doortesten. Maar zeggen "ah, daar heb ik asserts voor" is naar mijn idee wat kort door de bocht ;)

[ Voor 18% gewijzigd door Creepy op 04-06-2004 09:23 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
Is er hier eigenlijk iemand die ervaring heeft met unit testen (junit) en java application servers (J2EE)?

Voor veel functionaliteit heb je toch veel van je server nodig. Hoe gaat dit dan precies? Of kan het niet?

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
flowerp schreef op 05 juni 2004 @ 17:49:
Is er hier eigenlijk iemand die ervaring heeft met unit testen (junit) en java application servers (J2EE)?

Voor veel functionaliteit heb je toch veel van je server nodig. Hoe gaat dit dan precies? Of kan het niet?
check: http://www.junit.org/news/extension/index.htm

  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
Hmmm, junit en j2ee lijkt dus geen populaire combinatie te zijn. Als de bovengenoemde link -de- plaats hiervoor is, en de nieuwste contributie is uit 2002 dan zegt dit toch wel genoeg. Waarschijnlijk dat j2ee ontwikkelaars niet veel waarde zien in junit testen?

Ik ga er iniedergeval wel naar kijken. Hopen dat het ook bruikbaar is voor Eclipse in combinatie met Orion.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Verwijderd

flowerp schreef op 05 juni 2004 @ 17:49:
Is er hier eigenlijk iemand die ervaring heeft met unit testen (junit) en java application servers (J2EE)?

Voor veel functionaliteit heb je toch veel van je server nodig. Hoe gaat dit dan precies? Of kan het niet?
Wij hebben daarvoor ServerTestCase (http://www.junit.org/junit/download/ServerTestCase.zip , via die link van Alarmnummer wel te vinden). Je moet dan de ServerTestCase tests deployen naar de server, en via een session layer aanroepen. Het resultaat/fout wordt dan mooi doorgegeven naar de cliënt.

Het irritante is dat je bij het ontwikkelen van een test steeds die test apart moet deployen. (wij werken nog met BEA WLS 6.1, waar hot deploy enkel een officiële spec schijnt te zijn, een BEA consulente vertelde dat 8.1 beter zou zijn, maar dat het werken zonder JAR/EAR/WARs nog steeds een kadukke optie was :S)

Waar je ook voor moet opletten zijn rollbacks, als we een fout (al dan niet gewild) gooien in de code (veel fouten gaan gepaard met een rollback om welbekende redenen), en de test vangt die op (omdat de test juist 'test' of die fout gegooid wordt) en de volgende test géén aparte test (methodenaam die begint met test) is, dan krijg je fouten 'transaction already rolled back' en dergelijke. Elke test wordt namelijk apart gestart via die session EJB. Dus daar moet je dan ook wel opletten.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Dit is nog een interessante add-in voor VS.NET:

www.testdriven.net

https://fgheysels.github.io/


  • muba
  • Registratie: April 2002
  • Laatst online: 19-10-2013

muba

Prince of Persia!

Is er een simpele - maar diepgaande - Nederlandstalige uitleg over hoe je unit tests schrijft? Want ik ken het woord, maar ik kan maar niet te weten komen wat het nou precies inhoud.

Reporter: Mister Gandhi, what do you think of western civilisation?
Gandhi: I think it would be a good idea


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
MUBA schreef op dinsdag 30 november 2004 @ 09:52:
Is er een simpele - maar diepgaande - Nederlandstalige uitleg over hoe je unit tests schrijft? Want ik ken het woord, maar ik kan maar niet te weten komen wat het nou precies inhoud.
Als je dit topic door ploegt zul je meer dan genoeg goeie examples tegen komen.

  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 19-05 16:06
Ik gebruik unit testing ook voor de niet triviale dingen maar vooral eigenlijk op nieuwe code waarvan ik een hoge verwachting heb dat het mis kan gaan. Zeker in een HA omgeving hecht ik hier veel waarde aan, net zo veel als aan de monkey tests.

  • Eelke Spaak
  • Registratie: Juni 2001
  • Laatst online: 12-05 15:26

Eelke Spaak

- Vlad -

Om SessionBeans in een J2EE-applicatie te testen, heb ik simpel een consoleprogrammaatje geschreven dat verbinding maakt met de server, en dan wat methodes aanroept om te kijken of ze het goede resultaat leveren.

Is er een reden om dit niet met een static void main() maar met een void test() te doen?

Ik weet niet zoveel van unittests af, dus dit is een eerlijke vraag. :)

TheStreme - Share anything with anyone


  • TukkerTweaker
  • Registratie: November 2001
  • Laatst online: 19-05 16:06
Eelke Spaak schreef op dinsdag 30 november 2004 @ 11:06:
Om SessionBeans in een J2EE-applicatie te testen, heb ik simpel een consoleprogrammaatje geschreven dat verbinding maakt met de server, en dan wat methodes aanroept om te kijken of ze het goede resultaat leveren.
DIt kan in feite een TestCase uit het framework zijn, voordeel van het junit framework (kort door de bocht) is dat je verschillende handige functie's kado krijg, je een test raamwerk op kunt zetten en met build scrpits diverse test kunt uitvoeren. M.a.w. het neemt je een boel werk uit handen i.p.v. dan zelf o p te zetten met consoleprogrammatjes.

  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Interessante materie. Op mijn ontdekkingsreis kwam ik deze tegen, http://jakarta.apache.org/cactus/, misschien dat dit een beter J2EE tester is.

Unit testen klikt heel interessant, maar tot welk niveau is het bruikbaar? Ik krijg de indruk dat je meer per functie aan het testen bent. Hoe werkt dat dan met recursieve functies? Ik heb bijv. een keer een zeer uitgebreide matchings functie gemaakt om paren te combineren. De had ik onderverdeeld in een aantal subfunctie, maar die zijn allemaal afhankelijk van de toestand die de aanroepende procedure.

Stel dat ik daar een TestCase voor schrijf, dan is de test case in eerste instantie dus verantwoordelijk voor het neerzetten van de juiste toestand? En hoe test je dan enkele recursieve functies (die echt alleen zichzelf aanroepen), de unit test kan dan toch ook niet veel meer doen dan afwachten tot dat deze klaar is (of je test duurt te lang en uiteindelijk ontdenk je dat je in een oneindige lus terecht gekomen bent).

www.fendt.com | Nikon D7100 | PS5


Verwijderd

Een recursieve functie moet toch altijd eenmalig door een andere functie worden aangeroepen?

  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Als je een recursieve functie test, dan test je die eigenlijk als een normale functie. Je weet wat je wilt krijgen bij een bepaalde input en dan test je ofdat je dat ook krijgt. Omdat je weet hoe de functie werkt kan je ook extra testen op 'boundary values', dus dan test je de base case apart. Oneindige loop zal nooit oneindig zijn omdat je op een gegeven moment door je stack heen bent. Die exception die dan opgegooit wordt kan je eventueel catchen...

"Beauty is the ultimate defence against complexity." David Gelernter


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Verwijderd schreef op dinsdag 30 november 2004 @ 15:37:
Een recursieve functie moet toch altijd eenmalig door een andere functie worden aangeroepen?
Uiteraard, maar daarna roept hij zichzelf aan totdat er een bepaalde voorwaarde (niet meer) geldig is.

www.fendt.com | Nikon D7100 | PS5


  • FendtVario
  • Registratie: Januari 2002
  • Laatst online: 12-05-2025

FendtVario

The leader drives Vario!

Macros schreef op dinsdag 30 november 2004 @ 15:38:
Omdat je weet hoe de functie werkt kan je ook extra testen op 'boundary values', dus dan test je de base case apart. ...
Dus is de TestCase verantwoordelijk voor het initialiseren van de toestand, of splits je de recursie voor het testen in twee delen waarvan 1 het recursieve deel is en 1 het reken deel? Voor simpele recursieve dingen zet ik nog wel eens alles gewoon in 1 functie.

www.fendt.com | Nikon D7100 | PS5


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 30-04 09:28

Macros

I'm watching...

Ja, de TestCase brengt eerst het object in de gewenste toestand (en alle andere objecten de je nodig hebt om de test uit te voeren)

"Beauty is the ultimate defence against complexity." David Gelernter


  • bloody
  • Registratie: Juni 1999
  • Laatst online: 19:49

bloody

0.000 KB!!

Ik wil TS hierbij aanraden om eens te kijken naar maven (http://maven.apache.org). Dit tooltje (TOOL!) is handig om bv s'nachts al je junit testjes te draaien , zodat je morgenvroeg als je binnenkomt zetten, direct kunt zien wat en hoeveel er fout gaat!.

Ander leuke plugin is de jcoverage die aangeeeft hoeveel 'dekking' je met je junit testjes hebt bereikt op je code. :9 :9 Dus hoeveel je hebt afgetest.

Alles wordt zo lekker voor je geautomatiseerd, en dat is wel zo handig met deadlines.

Nog een note voor TS: maven kan jou geliefde build files zelfs genereren! :)

nope


  • bloody
  • Registratie: Juni 1999
  • Laatst online: 19:49

bloody

0.000 KB!!

een toevoeging voor struts liefhebbers: zie http://strutstestcase.sf.net voor een het testen van struts met junit! (werkt SUPER)

nope


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024
bloody schreef op dinsdag 30 november 2004 @ 21:10:
Ik wil TS hierbij aanraden om eens te kijken naar maven (http://maven.apache.org). Dit tooltje (TOOL!) is handig om bv s'nachts al je junit testjes te draaien , zodat je morgenvroeg als je binnenkomt zetten, direct kunt zien wat en hoeveel er fout gaat!.
Als ik met wat complexere zaken bezig ben dan draai ik alleen maar unit testen (ik compileer dan niet eens). Dus een nachtelijke test is leuk.. maar niet voldoende.

In de toekomst (als unit testen bij ons standaard is.. en niet alleen bij mij) zou het ook een idee zijn om een continuous integration server te gaan draaien, waarbij het niet mogelijk is om code in te checken waarvan de unit tests niet lukken. Weet je zeker dat je altijd een werkbare source hebt.
Ander leuke plugin is de jcoverage die aangeeeft hoeveel 'dekking' je met je junit testjes hebt bereikt op je code. :9 :9 Dus hoeveel je hebt afgetest.
Ik heb clover wel eens gebruikt.

Maar een volautmatische test draaien omdaarmee af te leiden hoeveel coverage je hebt vind ik niet voldoende. Meestal draai ik het in combinatie met een paar tests.. ik krijg dan veel beter te zien wat er gecovered is.. veel informatiever.
Alles wordt zo lekker voor je geautomatiseerd, en dat is wel zo handig met deadlines.
ant test.all vind ik ook snel genoeg :)
Nog een note voor TS: maven kan jou geliefde build files zelfs genereren! :)
Kan wel zijn.. maar de standaard is ANT en ik werk bij een bedrijf waar dit ook de standaard is.. nouja... als ze er dan ook echt gebruik van maken zoals het hoort.. Maar ANT is (helaas) de standaard.. en probeer me daar maar aan te houden.

En ja.. maven is beter :)

[ Voor 11% gewijzigd door Alarmnummer op 30-11-2004 21:32 ]


  • dotcode
  • Registratie: Augustus 2003
  • Laatst online: 17-05 21:04

dotcode

///\00/\\

Testen is niet nodig als je de oorzaak van de bugs kan achterhalen en die kan weg nemen. Zie http://c2.com/cgi/wiki?SourcesOfBugs.

  • jelmervos
  • Registratie: Oktober 2000
  • Niet online

jelmervos

Simple user

Soms heeft een unit-test bijzonder veel objecten nodig om de methode te kunnen testen. Zelf vind ik dit nogal veel tijd kosten, hoe lossen jullie dit op?

"The shell stopped unexpectedly and Explorer.exe was restarted."


  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 20:44

Creepy

Tactical Espionage Splatterer

dotcode schreef op woensdag 01 december 2004 @ 21:12:
Testen is niet nodig als je de oorzaak van de bugs kan achterhalen en die kan weg nemen. Zie http://c2.com/cgi/wiki?SourcesOfBugs.
Naasten testen op crashes e.d. valt er nog veel meer te testen hoor :)

Werkt het produkt zoals de gebruiker het verwacht, kloppen de uitkomsten wel met de ingevoerde waarden etc. etc. etc.

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney

Pagina: 1 2 Laatste