Door Bas de Ruiter en Jesse van Muijden

Bdd op Tweakers

Hoe Tweakers Behat integreerde

17-03-2019 • 06:00

141

Singlepage-opmaak

Conclusie

Door Behat te gebruiken hebben we tijdens het ontwikkelen meer zekerheid gekregen dat er door nieuwe codewijzigingen geen bestaande features stukgaan. Het is niet zo dat er direct significant minder nieuwe bugs ontstaan. We doen naast de unit- en integrationtests ook al een codereview en een handmatige user acceptance-test voor alle wijzigingen, waardoor er toch al weinig bugs doorglippen. Wel leidt Behat tot meer zelfvertrouwen om oude code ingrijpender te refactoren.

Op het gebied van de ontwikkeling van ubiquitous language is nog groei mogelijk. Het is een uitdaging om alle collega’s, met hun verscheidenheid aan rollen en expertise, de toegevoegde waarde van een gezamenlijke domeintaal te laten inzien. Misschien is de grootste winst die we op dit gebied hebben geboekt, dat we bewuster zijn geworden van het werk dat nog moet worden verzet. Er is immers nog veel nodig voordat het de norm wordt dat developers en stakeholders samenwerken aan het ontdekken van het domein en het ontwikkelen van een gedeelde domeintaal.

Het was een grote investering om Behat te integreren in de developmentworkflow van Tweakers. Het bleek vrij ingewikkeld om het technisch op te zetten. De grootste hindernissen waren het netjes configureren van Behat in een grote applicatie met veel legacycode en het opzetten van de ontwikkelomgevingen met Docker. Uiteindelijk is dit naar tevredenheid gelukt, maar er is ook nog veel ruimte voor het verbeteren van de prestaties van de Docker-omgeving. In de loop van het project zijn de prestaties al aanzienlijk verbeterd, wat het gebruiksgemak voor de developers merkbaar ten goede kwam. Een soepele ervaring voor developers is essentieel om op lange termijn van de opgezette Bdd-stack te kunnen blijven profiteren.

In de toekomst moet blijken welke voordelen Behat gaat opleveren voor het softwaredevelopmentproces van Tweakers in bredere zin. Zal Behat bijdragen aan het beperken van de hoeveelheid nieuwe bugs die worden geïntroduceerd? Gaat Behat scope creep voorkomen, developers helpen om doelgericht te werken, misschien zelfs hun productiviteit te verhogen? Gaat Behat helpen om de communicatie tussen stakeholders en development te stroomlijnen, zodat de organisatie sneller van idee naar productie kan? We gaan het meemaken.

Het mag gezegd worden dat het voor ons een prachtig project was om aan te werken. Zoals je verwacht, krijgen we bij Tweakers tijd voor technisch onderzoek en innovatie. Voor developers biedt Tweakers een unieke combinatie van nostalgische legacycode uit het krijttijdperk en het experimenteren met moderne technologie als Docker en Behat. Daarnaast kiest elke developer naar eigen inzicht een ontwikkelomgeving en is er ruimte voor opensourcecontributie. Dus, kom werken bij Tweakers; we zoeken nog leuke collega’s ;)

Toekomstige stappen

In de komende tijd blijven we schaven aan de prestaties van de Dockerized developmentomgevingen op de verschillende besturingssysteem. Ook willen we de inhoud van de featurefiles toegankelijker maken voor alle stakeholders, in de vorm van automatisch gegenereerde, levende documentatie met behulp van Pickles. Wegens de prestatie-issues die we al hadden, hebben we de integratie van Selenium voor het testen van JavaScript-functionaliteit nog voor ons uit geschoven.

We zijn benieuwd naar jullie mening over wat de beste end-to-end-teststrategie voor Tweakers zou kunnen zijn. Of misschien heeft er nog iemand goede ideeën om de prestaties van Docker te verbeteren. Als je nog andere ideeën hebt, horen we die uiteraard ook graag.

Reacties (141)

141
139
118
11
1
3
Wijzig sortering
Scenario: Listing product editions on the product listing
Given I have a product "Sony WH-1000XM3"
And this product has 2 product editions
When I view the details of this product
Then I should see a list of it's product editions
Bijna goed ;)
Specification by Example gaat uit van concrete voorbeelden die niet voor interpretatie vatbaar zijn... Dit is niet concreet, en dus voor interpretatie vatbaar. Immers: welke 2 edities? En welke lijst van product edities? Diezelfde als de twee die in de 'Given' staan? (dat is uiteraard voor de hand liggend - maar het staat er niet!).

Dus beter is
Scenario: Listing product editions on the product listing
Given there is a product "Sony WH-1000XM3"
And this product has editions "grey" and "black"
When a Tweaker views the details of this product
Then the Tweaker should see a list showing "Sony WH-1000XM3" including its "gray" and "black" editions


Nu kun je echter met de vraag blijven zitten of dit enkel moet werken bij exact twee edities...
Dus is het volgende ook een optie (aan het team om te bepalen of dit misschien weer wat overkill is):

Given there is a product "Sony WH-1000XM3"
And this product has 3 product editions
When a Tweakers views the details of this product
Then the Tweaker should see a list showing "Sony WH-1000XM3" including its 3 editions

Given there is a product "Sony WH-1000XM3"
And this product has edition "black"
When a Tweaker views the details of this product
Then the Tweaker should see a list showing "Sony WH-1000XM3" including its "black" edition


Overigens wél impressed hoe BDD hier uitgelegd is, namelijk als combi van (A)TDD en DDD.... Dáár gaan de meeste clubs namelijk de fout in. Die zien het als een testtool en gebruiken het dus enkel voor (A)TDD om vervolgens te klagen dat de Gherkin syntax wel een erg omslachtige manier is om je testscripts op te schrijven (no shit! Daar is het ook niet voor bedoeld...).Zie dit trouwens wél terug in de achtergrond afbeelding... Daar zit implementatie in verwerkt... Een grote no-no als het gaat om Specification by Example: "When I visit the News Portal And I navigate to Older news"...
Een eindgebruiker is daar niet in geïnteresseerd... Die wil gewoon oud nieuws zien, ofwel: "When a Tweakers.net visitor requests 'Older News'"... (merk ook op: zonder de 'ik'-vorm, immers wie is dat?? Niet erg concreet...).

Tot slot: is er een reden om in het Engels te werken? Indien iedereen Nederlands kan lezen/schrijven kun je de scenario's beter ook in het Nederlands doen... Of zijn er collega's die de Nederlandse taal niet voldoende machtig zijn (en Engels wel)? Dan is Engels natuurlijk prima!

(Nb. ik werk zelf alweer bijna 8 jaar met BDD en Specification by Example, heb het geleerd van o.a. de bedenkers Dan North en Gojko Adzic. Geef er ook al vele jaren workshops en trainingen in... Inmiddels zet ik wat zwaarder in op Impact Mapping (ook van Gojko), het achterhalen waarom een eindgebruiker functionaliteit zou willen, wie de eindgebruiker dan eigenlijk is, hoe het gedrag van die gebruiker veranderd kan worden middels software en tot slot wat er dan gedaan moet worden).

[Reactie gewijzigd door kazz1980 op 23 juli 2024 06:32]

Mee eens dat waar mogelijk het gebruik van "I" voorkomen moet worden. Op de plekken waar het gebruikt wordt verwijst "I" altijd naar de role, 'as an editor' bijvoorbeeld. De feature files zijn zo georganiseerd dat daar ook geen onduidelijkheid of inconsistentie kan ontstaan.
Niet helemaal eens met je commentaar over specification by example. Wel heel goed opgemerkt. In dit scenario zijn de eigenschappen van de editions incidental details. Er is bewust gekozen om deze weg te laten, want "focus on the behaviour of the story and steer clear of incidental details which don’t contribute anything" (https://cucumber.io/blog/cucumber-antipatterns-part-one/). Bij examples die wel verder uitgespecificeerd zijn worden daarnaast zo veel mogelijk realistische waarden gebruikt.
De stap die je voorstelt "should see a list including it's black edition", daar wilden we uiteindelijk ook naartoe. De strategie om de site breed te testen liet echter niet toe om voor alle features zo specifiek te gaan. Het lijkt misschien een kleine extra moeite, maar Tweakers heeft echt veel features. Om er daar zo veel mogelijk van te kunnen raken, zijn veel features nog niet specifieker gedekt met het oog op de planning.

[Reactie gewijzigd door jessevanmuijden op 23 juli 2024 06:32]

Eens Jesse! Durf te besluiten dat iets incidental detail is. Ik zie er veel te veel scenario's in verzuipen :(. (En vervolgens haakt iedereen razendsnel af.)

Het Engels vind ik wel een heel terechte opmerking. Deze site is toch niet Engelstalig?

Wat ik nog volledig mis in het verhaal: BDD != End to End testen. Dat is nogal een vervelend misverstand. Prima dat je er ook end to end mee test, maar dat hoeft lang niet altijd en is ook niet de primaire kracht, die zit in de communicatie (en voor directe communicatielijnen is end to end vaak een sta in de weg).

In feite is het gebruik van de Symfony hook al een voorbeeld van het niet helemaal end to end doen, heel terecht. Maar je kunt hier veel verder mee gaan, met veel voordeel naarmate je ubiquitous language zich ontwikkelt. Kern is dat iets een feature is die je business interessant vindt en waar je dus met hen, o.a. via scenario's, over wilt afstemmen. Gebruik je die met zo min mogelijk omwegen om je code te testen (dicht tegen unit testen aan dus), dan zul je zien dat je ubiquitous language ook je code-ontwerp gaat beïnvloeden (en die alignment is positief - ). Werk je 'ver weg' end-to-end, dan mis je dit en wordt je fixture code ook (nodeloos) ingewikkeld.

[/me heeft trouwens ook zo'n bak met credentials op dit gebied en nog een leuke workshop op de plank liggen die dit laatste punt tot leven brengt (wel in Java).]
Het Engels vind ik wel een heel terechte opmerking. Deze site is toch niet Engelstalig?
Ons team is verbazingwekkend genoeg volledig Nederlands, maar wij zijn de enige in het gebouw, en ik durf bijna wel te stellen het enige volledig nederlandstalige team binnen de persgroep. Vandaar dat onze code ook zoveel mogelijk in het engels is zodat kennisdeling binnen de persgroep gewoon makkelijker gaat.
Ter aanvulling op Kees;

Een van onze zustersites heeft de domeinobjecten allemaal in het Nederlands gedaan (dus de entities enzo). Zij hebben echter een grotendeels niet-Nederlandstalig ontwikkelteam (en voor hun is Engels ook niet de eerste taal), maar het is wel interessant - en juist verwarrend - om ze dan in hun verder Engelstalige communicatie ineens Nederlandse termen ertussendoor te horen zeggen... Maar daar was dat inderdaad gedaan omdat de rest van het bedrijf ("de business") wel allemaal Nederlander is.

Maar dat was niet echt de hoofdreden, meer een bijkomend voordeel mochten we wel een collega krijgen die geen Nederlands kan. Het is vooral een beetje automatisme geweest tijdens het uitwerken; al onze code is tenslotte ook in het Engels ;)
Ik kom dit vaak tegen, inclusief deze antwoorden, dat automatisme. Waarom kijk je naar je code, terwijl het om afstemming met je business gaat? Wat is de voertaal tijdens het afstemmen van functionaliteit met stakeholders? Heeft je zustersite er last van, of klinkt het slechts wat komisch? Aan getNieuws() etc. wen je vrij snel en het is keurig conform de realiteit: code syntax is nu eenmaal pseudo engels en je ubiquitous language (primair) wat je business spreekt.
Sja, de voertaal. Dat is in principe Nederlands. Maar de naamgeving is een mix van Engelse, Nederlandse en in het Nederlands geadopteerde Engelse termen (al dan niet met vernederlandste spelling, zoals samenstellingen).

Ik heb verder geen idee in hoeverre de zustersite er last van heeft. Zoveel werk ik niet met ze samen en degenen die ik het hoorde toepassen werkten er op dat moment al een tijdje, maar het zal (nieuwe) niet-Nederlanders wel extra moeite kosten om te leren begrijpen. En de ongebruikelijke uitspraak van die termen zal de andere kant op ook niet helpen :P

En waarom heet het dan getNieuws en niet haalNieuwsOp? ;)
En waarom heet het dan getNieuws en niet haalNieuwsOp? ;)
Dat mag je wat mij betreft helemaal zelf weten. Ik meen me vagelijk te herinneren dat dat beter in lijn is met gebruiken binnen PHP en Symfony. Maar ik zal eerlijk bekenen sinds 2008 nauwelijks PHP te hebben aangeraakt. Mijn technische achtergrond is toen vooral in Java verder gegaan en daar zijn getters en setters een ingeburgerd iets, dus zou je met haalXxxOp() juist tegen conventies in gaan (die zelfs diep in taal en frameworks zijn ingebakken).

Een kernidee is dat je niet om taalvaagheid heen werkt, elk vanuit je eigen begrip van de zaak, maar het gesprek erover aan gaat. Daar zit enorm veel lange termijn waarde. Het maakt de inburgering ook een heel langdurig proces. Dit zijn geen 'ineens goed' zaken, maar het gestaag aantrekken van communicatielijnen / wederzijdse feedback waarvan veelal nauwelijks de waarde wordt ingezien totdat die langzamerhand ervaren wordt.

Ik herinner me dat ik met een stagair op een NS/ProRail project sprak over enkele work arounds die hij tegen kwam rondom de lengte van een trein in bakken. Hij vroeg zich af waarom de code zo rommelig was. Ik vroeg hem eens de definitie van 'bak' te gaan achterhalen. In no time had hij er meer dan vier verschillende gevonden (waarvoor de code dus géén verschillende entiteiten onderkende).

[Voor de inhoudelijk nieuwsgierigen: in goederenvervoer, met krappe rangeersporen, tellen die vier locs vooraan toch echt altijd mee. In reizigersvervoer niet, want er kan geen volk in. Nou ja.. oh wacht.. maar wat dan als die loc voor de wissel tussen spoor a/b moet stoppen? Etc.]

Hier raakt BDD aan Domain Driven Design (waar het begrip ubiquitous language als ik me niet vergis ook vandaan komt). Niet dat men er daar altijd zo maar even eenduidig uitkomt, maar dan onderkent men de bounded context waarbinnen de definitie geldt; elk begrip is gedefinieerd binnen een bepaalde context en die contexten worden strikt gescheiden gehouden, met expliciete vertalers wanneer data van de ene naar de andere gaat.

[Reactie gewijzigd door Gwaihir op 23 juli 2024 06:32]

Janoz Moderator PRG/SEA @ACM18 maart 2019 16:53
En waarom heet het dan getNieuws en niet haalNieuwsOp? ;)
Omdat 'Nieuws' onderdeel is van het (business)domein, terwijl 'get' onderdeel is van de codeconventie.

https://gathering.tweaker...message/34074719#34074719
En waarom heet het dan getNieuws en niet haalNieuwsOp? ;)
Wij doen alles in het Engels; variabelen, functienamen, commentaar, databasevelden, alles. Woorden in het Engels zijn gemiddeld korter dan in het Nederlands, dus je code wordt er compacter door. "getNews" vs "haalNieuwsOp" is een goed voorbeeld. Mogelijk gaat de code bij ons naar internationale werknemers, dus dan hoeft er geen vertaalslag plaats te vinden en voorkom je verwarring in comment blocks (die natuurlijk ook in het Engels zijn geschreven). Op StackOverflow zie ik ook regelmatig onbegrijpelijke code met allemaal Duitse of Franse variabelen en functienamen, ik haak altijd heel snel af in zulke topics.

Als iedereen Engels gebruikt wordt de naamgeving ook consistenter. De helft in het Nederlands en de helft in het Engels staat ook rommelig. Datastructuren zoals design patterns hebben gestandaardiseerde namen, die vertaal je toch ook niet in het Nederlands? Of noem je een GatewayFactory een DoorgangFabriek? En noem je een EventListener een GebeurtenisLuisteraar? Doe gewoon alles in het Engels, staat veel netter. Vind ik.
Ik kom dit vaak tegen, inclusief deze antwoorden, dat automatisme. Waarom kijk je naar je code, terwijl het om afstemming met je business gaat?
Exact dit... Mijn advies aan organisaties die beginnen met BDD is altijd: Welke taal spreek je in de vergaderzaal en tijdens de sessies dat (nieuwe) functionaliteit bedacht / gerefined wordt? Gebruik dié taal... Ongeacht of dat Nederlands, Engels, Talk like a Pirate of Klingon is... Want de tooling ondersteunt zo'n beetje iedere denkbare taal! (en zo niet: het is bijna allemaal open source - voeg je het lekker zelf toe...).

Bij Tweakers is Engels blijkbaar redelijk gangbaar in de organisatie (ook al is Tweakers zelf weer Nederlandstalig qua team). De afweging voor Engels kan dan de juiste zijn, ondanks dat het hele team zelf Nederlandstalig is...

[Reactie gewijzigd door kazz1980 op 23 juli 2024 06:32]

Daarnaast is het vaak vele malen simpeler om je code gewoon in het engels te schrijven doordat de meeste talen ook gebruik maken van engelse termen.

“For (Article article : shoppingCart)”
Leest nu eenmaal een stuk makkelijker weg dan
“For (Artikel artikel : winkelWagen)”

Daarnaast is altijd duidelijk dat een woord aan bepaalde constructies voldoet wat weer handig is met code generation.

Bij het kadaster hebben we soms ook nederlandse domein objecten. Best wel lelijk en verwarrend soms.
Sorry, maar juist het Kadaster is een typische omgeving waar je het domein heerlijk in het nederlands wilt houden. Daar wordt genoeg terminologie gebruikt die misschien wel helemaal niet duidelijk of eenduidig te vertalen is. Het is soms al wat lastig afstemmen met de business, maar als je dan ook nog eens van een compleet andere naamgeving gebruikt ga je al helemaal langs elkaar heen praten...
Ja sure daarom betrekken wij de business juist in de code en proberen we zoveel mogelijk te doen aan de hand van configuratie dmv linked data. Onze code bevat dan geen domeinkennis en mag lekker in het engels en de configuratie lekker in het nederlands. Wij draaien nu BusDevOps om zo meer begrip te kweken tussen beide partijen.

Ik zit af en toe tegen nog wat oudere, maar toch relatief recente code aan te kijken waar dan iets staat als RuimtelijkePlansRegistry. Beetje jammer want het meervoud is engels en het nederlands is incorrect. Gewoon omdat de programmeur nederlands niet als first language had (en nee het was ook geen java ;)).
Wat betreft de 'incidental details', als er over nagedacht is en het team (incl business analist/PO, materie deskundige, business vertegenwoordiger, whatever) is het er over eens dat het incidental details zijn dan is het prima ;) De kracht van BDD is vooral de dialoog die ontstaat bij het neerpennen van de scenario's wat weer leidt tot een shared understanding. Dat het veeeeel moeite is, zeker om met terugwerkende kracht BDD te gaan werken, weet ik maar al te goed... Zeker in het begin is het een langzaam proces over het algemeen. Dus soms bewust de weg afsnijden is dan een prima keuze. Er kan later altijd gerefactored worden!

Veel werk dus.... Maar, het loont absoluut wel! Erg gaaf om jullie ervaringen tot zover te zien. Zal het gaan gebruiken in mijn workshops (geen bezwaar neem ik aan?).
Precies dat. Van mij geen bezwaar, alleen maar leuk!
Dankjewel voor je uitgebreide reactie. Erg leuk om te lezen en leuk dat je het in je workshop wilt gebruiken. :)

Ik ben ook heel benieuwd wat dit project ons uiteindelijk gaat brengen. Hopelijk inderdaad richting nog betere communicatie met stakeholders.

Overigens is de domain language Engels. We hebben het echt over de "product listing", "news portal" en de "frontpage". Alleen "Vraag & Aanbod" heeft geen Engelse naam.
Wat ik mis in het stuk is, waarom er gekozen is om elke developer naar het vak testen te halen ipv een afdeling / groep die het testen op zich neemt? Andere vraag, wil je de testomgeving niet gelijk hebben met de productie server en je eigenlijk dan op headless chrome / headless firefox uit komt met selenium ? En echt een user na gaat bootsen die klikt, die typt...
Op de andere vraag: ja. Op de eerste vraag zou ik antwoorden dat behat als BDD tool ingezet is en niet primair als test tool. Het doel juist om meerdere afdelingen eigenaar van de Gherkin features te maken i.p.v. dit bijvoorbeeld bij een test team neer te leggen.
De stap die je voorstelt "should see a list including it's black edition"
Ik denk dat de opmerking van @kazz1980 over het gebruik van Engels wel een terechte is. :X
Ach, in het Nederlands maken we wellicht ook fouten in de spelling en grammatica. We zijn tenslotte niet aangenomen voor onze vaardigheid in de Nederlandse (of Engelse) taal :P
Interessant, want ik heb altijd geleerd dat Gherkin beter in de ik-vorm kan worden geschreven.
Denk dat ik even terug naar de theorie zal moeten, want jouw opmerking makes sense.

Impact mapping kende ik nog niet, wel example mapping. Is dat gerelateerd?

Dat is het nadeel als je al weer enige tijd niet meer met Cucumber bezig bent, dan mis je veranderingen/verbeteringen in het platform.
Belangrijk bij de theorie is ook dat deze niet in beton is gegoten. Inzichten zijn ook veranderd de laatste jaren... Met name de toevoeging van Impact Mapping is wel relevant. Iets waarvan Gojko Adzic nu achteraf aangeeft dat hij dat liever eerst had geschreven vóórdat hij met Spec. by Example kwam... Het is niet (echt) gerelateerd aan Example Mapping of Story Mapping...

Het gaat over het mappen van de antwoorden op de vragen 'Waarom?', 'Wie?', 'Hoe?', 'Wat?'. (Waarom wil de eindgebruiker dit, Wie is die endrgebruiker, Hoe gaat het gedrag van de eindgebruiker veranderen (met deze nieuwe functionaliteit) en Wat moet daar dan voor gedaan worden. In deze volgorde... De Waarom-vraag heel expliciet vooraan en direct daarna de Wie-vraag... (en van daaruit dus ook het vermijden van de ik-vorm).

Ik raad het boek zeer aan... De theorie is een pagina of 20-30 maximaal... Dus je bent er zo doorheen. En het geeft wel veel inzicht! Al gaat het pas echt leven wanneer je het daadwerkelijk gaat toepassen... (bij mijn huidige project is het iets dat we bijna dromen... Bij de eerste 3 amigo sessie die we hebben is het bijna een strijd wie het eerst een (zinvolle) vraag stelt met 'Waarom' aan de business :P )

[Reactie gewijzigd door kazz1980 op 23 juli 2024 06:32]

Ik ben wat afhankelijk waar mijn werkgever mij wegzet, maar ik blijf mezelf wel oriënteren op de ontwikkelingen in Cucumber. In de hoop er weer mee in aanraking te kunnen komen, of om het zelf in te kunnen zetten bij vervolgopdrachten. Dank voor de tips. Boek is besteld :)
Graag gedaan! ;) En als je concrete vragen hebt: stuur gerust een PB.
Misschien handig om de link naar het boek te delen :P https://www.impactmapping.org/book.html
Hmm.. dit gaat over nogal wat. Waarschuwing: dit wordt wat samengevat ;).

Qua relatie: Impact Mapping doe je liefst vroeg. Ik doe het liefst nog voordat je een Story Map hebt; het gaat heel erg over wat kern is in het maken van impact. Als je daarna Story Mapping gaat doen heb je daar automatisch al wat meer focus in. Je Impact Map helpt je keuzes te maken binnen je Story Map (en dat wanneer je bijleert ook weer op nieuw te doen). Heb je al een Story Map, maar blijven de te releasen brokken onpraktisch groot, ga dan als nog impact mapping doen.

Helaas is het nog een enorm ondergeschoven kindje. Ik denk dat het komt omdat het zo enorm context gevoelig is en daardoor moeilijk vanaf papier tot leven te brengen. Ik vind het boekje sterk en kernachtig, maar dat het ook echt leeft voor me, komt wellicht door eerdere / andere besmetting. (Hadden we dit gesprek twee weken eerder gehad, dan had ik dan ook van harte de meetup erover aangeraden die ik onlangs met Gojko mocht hosten.)

Example Mapping gebruik je vervolgens om verder in te zoomen. Het haalt heel veel onduidelijkheid naar boven / weg en levert de examples op waar je vervolgens met SbE an sich de scenarios voor opstelt.

[En om het lijstje dan nog wat completer te maken, mocht je deze termen nog ergens tegen komen: impact mapping is afgeleid van o.a. effect-mapping. Vroege info van Gojko over het onderwerp gebruikt nog die benaming. En Matt Wynne begon wat nu example mapping heet onder de naam ignorance mapping.]
Dit is heel leerzaam, dank je wel. Het helpt mij zeker op weg tot verdere verdieping over de onderwerpen. Much appreciated
Bedankt voor deze zeer mooie aanvulling @kazz1980. Gedegen achtergrond en kennis over de concepten achter BDD blijken dan toch maar weer van groot belang om iets succesvol toe te kunnen passen.
Klopt. En daar gaat het héél vaak mis... Te vaak heb ik gezien dat organisaties BDD introduceren enkel omdat het een hippe term is... Zonder enig begrip van wat het feitelijk is. En dé valkuil is dus dat het gezien wordt als testtool, in plaats van een methodiek om de specificaties in business taal op te schrijven en vervolgens óók te gebruiken voor geautomatiseerde testen.
True, ik hoop dat de BDD lijn in de toekomst bij Tweakers ook in een positieve lijn doorgetrokken blijft worden. Alle lichten staan daar nu in ieder geval voor op groen. BDD introduceren omdat het hip is, dat is bij Tweakers niet van toepassing. Daarmee zou je het development team echt tekort doen. Vergeet niet dat behat geïntegreerd is in een grote applicatie die jarenlang niet behavior driven ontwikkeld is. Niet alleen de bestaande applicatie code en infrastructuur, maar ook de alledaagse werkwijze van zowel technische als zakelijke collega's vragen dan de nodige aanpassingen. Daardoor was het in dit geval praktisch om stapsgewijs te werk te gaan i.p.v. in één klap organisatiebreed perfecte BDD te forceren. Bijvoorbeeld, door eerst de concessie van 'test after development' te doen, hadden we snel een werkend voorbeeld, wat weer hielp om de bdd mindset aan te wakkeren bij product en business teams. Naarmate de dynamiek tussen teams zich ontwikkelde, werden ook de Gherkin features steeds beter. En terwijl je samen leert en de domeintaal ontdekt, krijg je ook weer te maken met refactoring van Gherkin features. Dus je moet de voorbeelden uit het artikel ook een beetje in de juiste context zien, pun intended. ;)
Thx voor de toelichting. Ik denk dat jullie de goede weg op gaan. Het is een keuze om klein te beginnen en meteen helemaal goed óf juist meteen de volle breedte te pakken, maar bewust nog concessies te doen.
Heb het nooit goed zien gaan wanneer clubs in één keer alles goed wilden doen met BDD, dan is het gedoemd te mislukken... Dus, top! Lekker bezig! ;)
Een eindgebruiker is daar niet in geïnteresseerd... Die wil gewoon oud nieuws zien, ofwel: "When a Tweakers.net visitor requests 'Older News'"... (merk ook op: zonder de 'ik'-vorm, immers wie is dat?? Niet erg concreet...).
Je zal toch e.o.a. context moeten scheppen. Want als iemand gewoon ineens bedenkt "ik wil oud nieuws zien", dan hebben we daar niet zomaar een antwoord op.

De specifieke story gaat dan ook over de functionaliteit op het dagoverzicht van nieuws waar onderaan set links gaat naar de vorige (en volgende) dag. Dit is overigens een van de stories die achteraf erbij is gemaakt, want de functionaliteit bestond al vele jaren voordat behat bestond ;)
Dus het had vast anders geformuleer kunnen worden als we helemaal BDD zouden werken (wat we niet deden en nog steeds niet doen).
Het is een beetje een semantische discussie...
Maar het gaat om een gebruiker die feitelijk 'ouder nieuws' opvraagt. Het gaat niet om iemand die bedenkt dat hij/zij iets wil... (immers: voorlopig kan IT nog niet veel met de gedachten van gebruikers noch kan IT voorspellen wat iemand wil!).

Het gaat er vooral om dat je een antwoord geeft op functioneel gedrag van de gebruiker. En een gebruiker geeft er in basis niet veel om waar hij/zij moet klikken (of swipen, of spraakopdracht, of...) en of hij/zij vanaf een bepaalde pagina naar een volgende pagina moet navigeren.

Die context heb je uiteraard wel nodig voor de onderliggende testautomatisering en daarom kun je dit uitwerken in de onderliggende step defs (glue code) die de testautomatisering weer aansturen.

Het met terugwerkende kracht omzetten van functionaliteit in scenario's is één van de lastigste dingen bij BDD. En soms kun je dan ook kiezen om shortcuts te nemen en bewust toch implementatie in de scenario's toe te laten (al dan niet tijdelijk). Zo lang dat een bewuste keuze is: niks mis mee! Wat dat betreft is BDD (gelukkig!) erg Agile. Experimenteer en leer (PDCA). En kies de weg die het beste past binnen het team en welke leidt tot de beste resultaten. Hoe dan ook zijn jullie erg goed bezig voor zover ik kan oordelen op basis van artikel en opmerkingen!! Vele malen beter dan pakweg 80% van de organisaties die met BDD beginnen... :/

[Reactie gewijzigd door kazz1980 op 23 juli 2024 06:32]

Tot slot: is er een reden om in het Engels te werken? Indien iedereen Nederlands kan lezen/schrijven kun je de scenario's beter ook in het Nederlands doen... Of zijn er collega's die de Nederlandse taal niet voldoende machtig zijn (en Engels wel)? Dan is Engels natuurlijk prima!
Als niet-Tweakers dev: Omdat ontwikkeltools niet in het Nederlands zijn, en zeker libraries niet. Symphony bijvoorbeeld heeft (waarschijnlijk) geen Nederlandse vertaling. Om het voorbeeld van de Transformer erbij te pakken, komt de BaseTransformer hoogstwaarschijnlijk uit een 3rd party library. Dus zal je voor de ArtikelTransformer of de GebruikerTransformer Engels en Nederlands tussen elkaar door gebruiken, wat niet altijd lekker werkt. Zeker als je buiten business classes ook zelf bepaalde tooling uitbreidt, is het schrijven van TransformerGereedschap->VindTransformer vreemd, zeker als je dan verschil hebt met een ingebouwde ViewTools->FindView functie die wel Engels is.

(Gebruikte class / functienamen zijn fictief, maar wel gebaseerd op praktische ervaringen uit mijn loopbaan)
En dát is juist een heel goede reden om niet in het Engels te willen werken... Immers, Gherkin gaat over specificatie. En dat is niet afhankelijk van een tool of ontwikkeltaal... Immers, je omschrijft functionaliteit - niet de (technische) implementatie... Wanneer het gaat om de onderliggende automatisering kun je direct over op het Engels (via de step defs of glue code). Het is heel belangrijk om bij scenario's de implementatie niet te betrekken, door niet Engels te werken (wanneer de implementatie wél Engels is ivm tooling) heb je een extra continue reminder om niet in implementatie-taal te gaan praten maar je te beperken tot functioneel gedrag.
Ik wilde er zelf ook al een comment over schrijven. Ik merk wel dat je hierdoor meteen weer de business side verliest. Zij willen namelijk helemaal niet zo specifiek zijn waardoor je als developer alsnog de tests aan het schrijven bent.

Het ligt natuurlijk ook aan een stukje opvoeding en draagvlak, maar ik ben tegelijkertijd ook van mening dat er niet veel PO's zijn die features kunnen schrijven die zo specifiek zijn als wij graag zien. Daarvoor moet je toch vaak iets meer als een developer denken.
Met betrekking tot prestaties van behat hebben wij vooral gemerkt dat een vrij aanzienlijk deel van de tijd gaat zitten in de persistence: de hele tijd wegschrijven naar de database om die vervolgens weer helemaal te resetten voor de volgende test.
Door ieder scenario in een transactie te wikkelen, en die aan het einde weer terug te draaien, merkte we een behoorlijke versnelling van onze behat suite.

Daarnaast was een grote bottleneck de totale tijd die het kan duren voordat de hele behat suite gedraaid is. Vooral in een CI/CD omgeving is snelle feedback gewoon heel belangrijk. We gebruiken Circleci voor het draaien van onze hele suite bij iedere commit (nouja, iedere push), en hebben gebruikt gemaakt van hun workflows om behat features zoveel mogelijk parallel te laten lopen. Gevolg: een suite die eerst ~15 minuten er over deed is nu klaar in ~1,5. Daarmee is de feedback loop voor developers drastisch korter geworden en kunnen ze veel meer focussen
Bij ons duurt lineair uitvoeren van de volledige behat suite nu zo te zien zo'n 4,5 minuut op onze CI-server.
Dat is inclusief het uitvoeren van composer install in een kale omgeving, het maken van de Symfony caches en het starten van de docker containers. En daarnaast wordt er dan ook gelijk documentatie gegenereerd op basis van de feature files en de testresultaten.

Als ik de (losse) tijden die behat meldt optel is blijkbaar slechts zo'n 1,5 minuut nodig voor behat. De rest zit dus o.a. in die overhead van die andere taken. Gelukkig blijft die overhead redelijk constant, dus hoe meer tests we hebben hoe minder erg het wordt. En ja, we zouden uiteraard ook nog kunnen kijken of we dat kunnen verbeteren :)
Maar dat behat-stuk parallel maken is voorlopig dus nog niet heel erg relevant voor ons :)

Maar dat is op zich wel goed te doen en voor normale pushes voeren we alleen de suites uit die relevant zouden moeten zijn.

De performanceklachten hebben meer te maken met het uitvoeren van de tests op de lokale laptops.

Op mijn Windows laptop, die ruwweg even krachtig zou moeten zijn als die VM, duurt het uitvoeren van behat via "Windows Subsystem for Linux" en zonder al die andere taken zo'n 3-3,5 minuut. Daar gaat dus al wat "mis", maar dat is nog te overzien.
Maar als we het op Linux en Mac via Docker uitvoeren, terwijl Docker gebruik maakt van de codebase die we in onze IDE bewerken (dus op het normale filesystem)... dan duurt het iets van 10 minuten. En ironisch genoeg zou de (interne) netwerkcommunicatie dan juist sneller moeten zijn; dat verschil valt overigens weg als we de codebase in de Docker container kopieren en dan behat (of unit/integration tests) uitvoeren.

Het is ook een populaire klacht over zowel de Mac als Windows versie van Docker, dat die I/O vanuit Docker op het OS-filesytem veel trager is dan op Linux.

Overigens kunnen voor ons transacties niet op die manier (het zou idd wel makkelijk zijn), want ook onze java-omgeving moet de data kunnen zien :)

[Reactie gewijzigd door ACM op 23 juli 2024 06:32]

Om de composer sneller te maken en niet bij elke Gitlab job de complete installatie te doen: Je zou nog kunnen kijken om een aparte container te maken die niets anders doet dan de composer install.

Vervolgens laat je de applicatie laag de composer map als artifact erin kopiëren. Scheelde bij ons ook een minuutje bij elke run. Gooi er eventueel een Gitlab cron/trigger bij die de composer container elke nacht laat updaten en je bent altijd bij!
De composer install op gitlab duurt niet zo lang dat we daar serieuze winst op kunnen halen: een volledige install met hot cache duurt ~7s omdat we voor gitlab een ramdisk gebruiken.

Maar dank voor het meedenken, ik bedacht hierdoor wel iets anders wat potentieel beter/sneller gemaakt kan worden :)
Dan doet de t.net Gitlab het iets sneller dan onze SSD vps ;)

@ACM je kunt met branching en tagging wel eea bewerkstelligen, maar alles valt of staat met de totale branching & merging strategie uiteraard. Project waar ik nu in zit heeft te weinig devs om echt last te hebben van verschillende versies qua deps, naast überhaupt kleine aantallen deps uit composer. Dus helaas kan ik dat niet goed beantwoorden. Maargoed, nogmaals, met tags en branches kom je al een heel eind.

Wel interessant om te zien wat er dan wel zoveel tijd in beslag neemt. Uiteindelijk kun je zoveel mogelijk gelijke acties cachen en elimineren. Maar gelukkig krijgt @Kees ideeën ;)
Interessant. Wij hebben echter af en toe relatief lang lopende branches (paar dagen tot weken) met "alvast" veranderde dependencies. Dus dan zou je voor die omgeving een ander artifact moeten hebben.
En als die branch gemerged wordt in je, wil je natuurlijk niet dat ineens je composer-zaken niet kloppen met de dan nieuwe situatie.

Hoe gaan jullie daarmee om?

Overigens hebben wij wel een gedeelde composer cache beschikbaar voor iedere testrun, die bovendien op "/dev/shm" bewaard wordt (dus in memory staat). Al met al duurt onze composer install volgens @Kees zo'n 7 seconde.
Misschien ten overvloede, maar in MySQL kun je je tabellen ook expliciet in memory laten draaien (met het veranderen van de table storage engine). En mocht je deze data toch nog willen opslaan ter naslagwerk, kun je misschien iets doen met een master/slave replication gebeuren, waar je de master 'quick and dirty' (pun intended hehe *ahum*...) z'n tabellen in memory laat schrijven, en de slave (Delayed) naar disk.
De memory storage engine ken ik, maar is geen goede vervanger voor InnoDB. De semantiek is gewoon heel anders, waaronder geen ondersteuning voor foreign keys en transacties.

MySQL werkt verder best ok met gewoon dingen op disk opslaan. Zie mijn reactie op Bosmonster met verdere verduidelijking waar wij echt tegenaanliepen.
Ik heb daar al een 'smerige' truc op bedacht; voor ik mysql start kopieer ik de hele database naar een ramdisk (in de testomgevingen, niet op productie ;)). Dat gaat vrij snel (1-2 seconden) en daarna heb je dus geen 'last' meer van writes naar de disk.
Docker voor Mac werkt toch juist ook via een VM? Een van de redenen dat het traag is ten opzichte van Linux.

[Reactie gewijzigd door Bosmonster op 23 juli 2024 06:32]

Docker op Windows en Mac OS is inderdaad in een VM. Maar daar gaat het in mijn reactie niet om. E.e.a. daarin zal vast langzamer zijn dan op Linux, maar dat is vooralsnog niet de grootste bottleneck.

Het gaat namelijk niet om de I/O in Docker (en dus in die VM), maar dit zit in de 'mount' die het filesystem van het host-OS binnen de Docker-containers beschikbaar maakt.
Ja sorry dat bedoel ik ook. Communicatie tussen VM en host is gewoon relatief traag. Daarom is Docker op Mac/Windows niet ideaal. Binnen de VM is het altijd wel prima.
http://docker-sync.io/

Het is misschien ook de vraag hoe vaak je alles lokaal moet draaien. Als het een kleine change is kan je het makkelijk pushen en zie je de results in je eigen 'feature' branche. Een grotere feature zou je een paar keer lokaal kunnen draaien maar dan ben je een langere tijd bezig met het dev'n dan die enkele keren de tests draaien.
Hehe, wij noemden het op een gegeven ook wel CI-driven development als we gingen pushen alleen om de features in linux uit te laten voeren. :+
En daarin ligt dan ook het antwoord op de vraag van @Douweegbertje: het ATDD aspect valt in het water indien gemakkelijk lokaal draaien niet gaat.

Heb je altijd de volledige infra nodig, of kan een overgroot deel ook individueel, vanuit de IDE even gestart worden?
Ik ben niet zeker dat investeren in een lokale setup om e2e testen te runnen veel waard is.
In een test pyramid, staan e2e testen bijna aan de top. Developers moeten vooral lokaal hun unit testen draaien. Integration testen doen wij ook, maar hierover kan je discussieren.
end-2-end testen horen imho op een CI omgeving. Hier moeten die natuurlijk snel werken, vandaar kan ik me volledig vinden in de parallellisatie die @johnydoe voorstelt.
Mits wij actief zijn in een microservice architectuur hebben wij een centraal docker-compose script die al onze microservices, databases en queues opstart voor lokaal development. dit zorgt ervoor dat CI scripts niet enkel voor de devops zijn die zich met CI bezighouden, maar een tool worden voor alle developers.
De docker-omgeving/stack wordt gebruikt voor meerdere taken:
- "lokale ontwikkelomgeving"
- behat (en dus min of meer end to end testing)
- integration testing

En we gebruiken dezelfde opzet op de lokale machines als in de CI-omgeving. De ontwikkelomgeving is eigenlijk gewoon een kopie van de omgeving die voor behat/integration wordt gebruikt, maar de mysql daarin vernietigd zijn database niet na afsluiten :P

Effectief is dus investeren in dit sneller krijgen op CI het dan ook sneller krijgen lokaal. We draaien in de praktijk lokaal wel vooral de tests van de features die we in ontwikkeling hebben en niet alle tests.

Dus effectief doen we ruwweg hetzelfde als wat jij beschrijft :)
docker op niet-linux ga je nooit net zo snel krijgen als op wel-linux. Bij kleine projecten zie je geen verschil maar hoe groter hoe gekker. Voor je het weet ben je je applicatie aan het omschrijven / tweaken om het op docker snel te maken, ipv dat je bezig bent met je echte business. (docker-compose.yml, docker-compose.windows.yml), etc.. Hoe vaak ik configuraties heb gezien die specifiek voor windows nodig waren. Als je niet goed reviewd zit het zo in productie.

Onze developers zijn allemaal overgestapt van windows naar linux. Je gaat windows tooling missen. Kies dan eerst voor native linux tools (en wen er een aantal maanden aan) en als je ze dan echt echt mist zonder redelijke workaround, dan is Wine een optie (ook al is de UI dan vaak minder).
Wat een verademing is het om af te stappen van gitbash/cmd/powershell naar (in mijn geval) Konsole. Geen gekke constructies meer met haakjes, quotes, unresponsive output, maar gewoon de voorbeelden die op internet 1 op 1 copy-pasten en gaan. Dat is onze ervaring althans :) Voor diegenen die wel degelijk aan hun OS gehecht zijn (hoi Apple): sommigen installeren een aparte linux VM binnen OSX, incl alle tooling. Photoshop/sketch op de mac, en phpstorm in de VM. DIt om de shared filesystem delays te omzeilen.

Oh ja, zet opcache AAN in development, met settings die er niet voor zorgen dat wijzigingen gecached blijven.

Enkele tweaks die ik heb toegepast om de behat test snelheid omhoog te krijgen:
Als je in staat bent om mysql uit te wisselen voor sqlite, doe dat, en zet 'm in /dev/shm of een andere plaats naar keuze dmv tmpfs. De database staat dan in memory en dat gaat echt lekker.
Zet logging uit, hopelijk is behat output voldoende. Zorg dat alle caches warm zijn (je bent integraties aan het testen, de code mag best in productie modus draaien).
De mooiste hack waar ik enorm trots op ben (bepaal zelf maar of het sarcastisch bedoeld was): Als je fixtures met users nodig hebt, sla de wachtwoorden op in plain text :) Het scheelt seconden als je niet constant fake user passwords met bcrypt moet vullen. Check daarna wel ff dat productie dat dan weer niet doet ;-)
Je kan je Bcrypt rounds in dev of tst ook op 1 zetten. Waarschijnlijk staat die in productie op 12+ en dan kan het idd lang duren (1+ sec per wachtwoord).

Symfony: https://symfony.com/doc/c...e-bcrypt-password-encoder
Laravel: https://laravel.com/docs/5.8/hashing#basic-usage
Het wordt aangeraden gewoon plain-text te gebruiken voor tests. Dit kun je ook per environment instellen. Stukken sneller dan bcrypt, zelfs op 1.
> Als je in staat bent om mysql uit te wisselen voor sqlite, doe dat

grote NO NO om in test in andere database te gebruiken dan in productie.
Docker performance is inderdaad een drama. Bij ons wordt vooral op OSX ontwikkeld. En je merkt de performance hit van docker en de niet native support in OSX. Vooral oudere macbook pro's ondervonden hier veel hinder aan.

Als de containers eenmaal draaiden (een rebuild duurde ook al vrij lang) dacht je dat je er vaak wel was, maar ogenschijnlijk kleine changes zorgden er toch weer voor dat soms delen van de containers gerebuild gingen worden.

Een van de grootste performance tweaks bij ons was het afstappen van de native docker support van PyCharm. Om onduidelijke redenen was dit gigantisch traag. Dit hebben wij uiteindelijk ondervangen door in de web-container een sshd te draaien en in PyCharm een remote interpreter in te stellen ipv de native docker support te gebruiken. Dit gaf een fikse performance boost en maakte uiteindelijk ontwikkelen een iets kleinere hel (hier gebruikten we de mogelijkheid dat docker-compose bestanden gelayered kunnen worden. De development yml bevatte de info voor de sshd en die werd bovenop de productie xml gelegd. Dus een accept/productie docker heeft nooit een sshd draaien terwijl ene development docker dat wel heeft).

Misschien een beetje een open deur, maar in de staging/acceptatie/productieomgeving kan je ook nog kiezen of je daadwerkelijk met docker containers gaat werken. De elegantie van docker is natuurlijk erg goed, maar als je voor een dedicated web-machine en dedicated db-machine gaat is de afweging wel of niet dockerizen er eentje die je alleen zelf kunt maken.
Je weet dat dat aan OSX ligt en niet aan Docker he? Hun file system is niet geschikt om zaken te mounten in docker. Dat zorgt voor de performance hit.

Snap ook echt niet dat developers nog op Mac's werken.
Want wat is het betere alternatief? Linux? Windows? Windows docker perfomance is het ook niet. Dus dan zou je al voor Linux moeten kiezen wat ook zeker zijn nadelen heeft.
Want wat is het betere alternatief?
Als Linux PC geen optie is: Linux VM op Windows PC. Hands down! :*)
Windows 10 + Virtualbox + Ubuntu LTS werkt prima. Meerdere monitoren ook.
(ik heb geen klagen over docker performance)

Tips voor wie dit wil proberen:
  • Nieuwe machine = gewoon standaard instellingen werken het beste. (met >4 cores en >8GB geheugen en >80GB disk)
  • Meestal werkt de grafische 2D/3D acceleratie averechts dus die laat ik uit.
  • Netwerk gebruik NetwerkBridgeAdapter (ipv NAT) en het hangt als echte PC op je LAN
  • In de guest steeds de laatste addons installeren.

[Reactie gewijzigd door Barryke op 23 juli 2024 06:32]

Je weet dat dat aan OSX ligt en niet aan Docker he?
Nee want dit is niet juist. Docker is een Linux technologie en werkt alleen op Linux. Docker op een ander OS (lees: Windows en macOS) kan dus eigenlijk helemaal niet. Daar hebben ze echter bij Docker een trucje voor gevonden: je gebruikt gewoon de ingebouwde hypervisor van het OS om een barebone Linux vm (ik geloof dat ze Alpine gebruiken) te draaien waarin je Docker kunt installeren. Met allerlei andere laagjes map je dan de hele mikmak (networking, filesystem, commando's, etc.) aan die vm zodat je toch lokaal alles dusdanig kunt gebruiken zoals je dat op Linux ook zou kunnen doen.

Die structuur is iets wat je heel goed in je gedachten moet houden. Zomaar een bind mount aanmaken in macOS kan niet altijd. Je zult namelijk eerst moeten zorgen dat de mount waarop hetgeen staat dat je wilt bind mounten aan een container is toegevoegd aan het File Sharing tabje in de Docker for Mac instellingen. Pas dan kun je die bind mount doen. Wanneer je heel veel images hebt vanwege allerlei tests kun je ook ineens tegen de situatie aanlopen dat je out of diskspace bent met Docker terwijl je gewone schijf dat nog lang niet is. Wat hier dan bedoelt wordt is dat je Docker vm out of diskspace is. Idem voor networking: je moet allerlei lagen onderzoeken als je een DNS result terugkrijgt die je niet verwacht. Je moet het maar net weten...

Dat is wat voor de diverse problemen voor zowel Docker for Mac als Docker for Windows zorgt. Iets wat je niet gaat oplossen omdat Docker zo met Linux verweven is. Het ligt dus niet aan macOS noch Windows maar aan Docker.
Snap ook echt niet dat developers nog op Mac's werken.
Omdat Docker maar 1 van de vele tools is en het best prima werkt op een Mac. Daarbij komt dat ook lang niet altijd filesystems gemapt worden omdat dit ook problemen oplevert op de productie systemen. In veel setups kun je geen gebruik maken van lokale storage omdat je container op iedere node van het cluster kan draaien. Je storage moet dus heel flexibel zijn. Met dat soort scenario's dien je ook rekening te houden.

[Reactie gewijzigd door ppl op 23 juli 2024 06:32]

Op pagina '7. Tools' wordt geschreven:
Het nadeel van deze werkwijze is wel dat we nog geen goede IDE-plug-in hebben gevonden die het mogelijk maakt om door te klikken op de ‘magic’ matchermethods als 'toBeWarningMeAbout()'.

Nu kan ik net niet helemaal doorzien waar dat naartoe zou moeten verwijzen. Maar gebruiken jullie de PhpStorm plugin DynamicReturnTypes al? Met een eigen configuratiebestand (zelfs logica in een los Javascript bestand is mogelijk) kun je wel het een en ander bereiken.

Wel hebben we de laatste tijd wat last dat de plugin ineens niets meer lijkt te doen. Maar we switchen nogal veel van context. De plugin uitschakelen en inschakelen (ja, IT Crowd) lijkt het euvel voor nu op te lossen.
Er is op het meegegeven object waar die assertion op toegepast wordt een methode 'isWarningMeAbout'. De doorklik zou dan dus moeten gaan naar die specifieke methode in de class van dat object.
Dus de conversieregels op zich zijn simpel, maar de 'return type' is dan steeds effectief het object dat je meegeeft en daar de methode op aangeroepen.

De conversieregels op zich zijn dan verder niet zo moeilijk, het is effectief steeds zo'n soort vertaling met bijvoorbeeld ook 'toHave*' <-> 'has*'.

Ik ken de genoemde plugin niet, maar kan ie dit? Dan zou het inderdaad interessant zijn.
Als het specifiek om het volgende stukje gaat:
expect($this->accountActivationPage)->toBeWarningMeAbout('Ongeldige activatiesleutel');
Je probleem is dan denk ik dat PhpStorm niet weet te bepalen wat er specifiek uit `expect` komt. Als er een class is waar je `accountActivationPage` naar kunt linken/omzetten, dan kan de plugin dat denk ik prima regelen (hoewel de parameter volledig `$this->accountActivationPage` is en je daar wat voor in JavaScript zal moeten doen.

Wij gebruiken het voor een aantal factory methods waar als parameter simpelweg de classname in gaat. Ook voor gebruik van Symfony `Kernel::service()` waar dependency injection niet haalbaar is. Dat is erg simpel te regelen.

Even een link voor de rest: https://github.com/pbyrne84/DynamicReturnTypePlugin

Maar kijk ook even door de issuelijst. Er lijken in PhpStorm wat wijzigingen aan te komen waardoor development van deze plugin al een tijdje stil ligt. In sommige issues worden ook wel wat alternatieven genoemd die misschien beter van toepassing zijn, zoals Phony.

Succes!
Het geeft me wel weer een beetje het gevoeld dat met ubiquitous language we terug in de tijd gaan.

Ik heb destijds op school programeren gehad en daar begon je altijd met pseudo code en pseudo diagrams.

Ik weet dat het software was van cap gemini en dat je het systeem definieer waarna je daarna een export kon doen naar pseudo code en flow charts.

Beetje een versimpeling van UML

Trouwens hoe lang zal het duren dat de AI slim genoeg is om van dit soort pseudo code / test cases zelf efficiency code kan genereren.

Moet toch te doen zijn

[Reactie gewijzigd door dutchruler op 23 juli 2024 06:32]

Het is inderdaad een taal die effectief voldoet aan programmeerregels, en er toch uitziet als "normaal".

Maar pseudo code is echt wel een stap verder. Als er programmeertermen en andere technische termen in die tekst staan, dan doe je het in principe verkeerd. Zo moet je niet iets als "Given there is a news article in the database" schrijven, maar domweg "Given there is a news article". Dat het in een database staat en via een ORM-laag daar ingestopt en uitgehaald wordt is als het goed is irrelevant :)

Ik verwacht ook zeker dat er tzt meer te automatiseren gaat worden aan de vertaalslag van de diverse clausules. Mijn 'Given there is a newsarticle' zou in principe zonder dat je specifiek daarvoor code moet schrijven ervoor kunnen zorgen dat een test-nieuwsbericht in die database terecht komt. Dat zou overigens nu al kunnen, maar dan moet je het natuurlijk allemaal zelf gaan uitwerken :P

't Hoeft tenslotte alleen maar te weten welke Entity het moet aanmaken voor "news article" en/of via welke Repository het moet worden opgeslagen.
Dat is echt wat anders! Het mooie van Gherkin is namelijk dat het business taal is. Domain Driven...
Pseudocode is juist meer taal van de ontwikkelaar, ook al is het in jip-en janneke opgeschreven zodat een niet-ontwikkelaar het ook kan begrijpen. Maar psuedo code blijft gaan over de technische implementatie. Gherkin gaat daar juist niét over... Die gaat over hoe functionaliteit het gedrag van de eindgebruiker gaat veranderen. Implementatie hoort dus absoluut niet thuis in BDD scenario's.
Mooi artikel. Ben vooral benieuwd hoeveel moeite het was om tweakers.net in een docker container te krijgen en welke problemen / keuzes er gemaakt zijn.
Ik bedoel tweakers bestaat niet alleen uit een frontpage, maar uit veel verschillende onderdelen. Hoe is dit aangepakt, en hoeveel tijd heeft dit gekost?
Het grootste probleem waar we tegenaan liepen was de database. Die is behoorlijk verweven en er is nooit een test-database gemaakt met test-data, wat eigenlijk beter zou zijn dan op een kopie van de productiedb testen. De volledige database (300G) + losse services erbij wil je dus niet op je lokale omgeving hebben dat zouden iets te dure laptops worden dan ;)

Uiteindelijk ben ik er gewoon eens een paar dagen voor gaan zitten en heb een 'reduce' script geschreven met daarin queries als 'pak de laatste 100 nieuwsberichten, reviews, shopsurveys, productreviews, forumtopics, v&a advertenties', 'pak alle reacties daarop', 'pak alle gebruikers van die reacties', 'pak alle images in die nieuwsberichten', 'pak alle gekoppelde producten', 'pak van alle categorien minimaal 5 producten' etc. Met als gevolg dat de database nu iets minder dan 1GB groot is, en de 'engine' (een java/lucene based index/zoekmachine) nog maar 5s nodig heeft om op te starten ipv 5 minuten.

De lokale testomgeving had ik al een paar maanden klaar voordat we het ook echt gingen gebruiken met dit project en heeft naast een webserver(apache)+php container ook memcached, activemq, tomcat, mysql, mongodb, mailhog en thumbor containers.
Lijkt me moeilijk om bij te houden. Met de specifieke JOIN/WHERE condities die queries uitvoeren om er dan voor te zorgen dat de juiste test data aanwezig is. 100 of 5 stuks van iets wilt niet zeggen dat deze dingen ook de juiste properties hebben.
Bijhouden is niet heel ingewikkeld, dat kunnen de devvers zelf doen als ze een nieuwe tabel aanmaken en er moet testdata in staan (default word alleen de structuur gekopieert).

Maar er zitten inderdaad ook queries tussen van 50 regels die vanalles aan elkaar koppelen, maar daar veranderd niet zo vaak iets in gelukkig.
Vergeet niet ook je productiedata even te anonimiseren voordat je het ergens anders gaat gebruiken ;)
Puik artikel! En gaaf dat er zoveel enthousastelingen hier zijn.
Zelf pas ik het toe op mijn 'hobby' projectjes. Maar ik zou hier graag volwassener in willen worden.

@jessevanmuijden @kazz1980 @ACM @winkbrace @Gwaihir, ik heb de volgende boeken aangeschaft.

BDD in Action - John Ferguson Smart
Specifications by Example - Gojko Adzic

Hebben jullie nog andere aanraders? Alvast bedankt!
Impact Mapping - Gojko Adzic (echt een must wat mij betreft...)
The Goal - Goldratt (niet zozeer over BDD, maar het past volledig in de mindset dat je het doet voor de business en met een bepaald doel voor ogen)
Writing Great Specifications - Kamil Nicieja (over het gebruik van Spec by Example in de praktijk. Gedateerd en vol met zaken die we inmiddels zien als dé valkuilen (zoals het gebruik van de ik-vorm)... Maar alsnog wel nuttig... Al is het maar om kritisch te kunnen kijken naar hoe een ander het toegepast heeft en te leren van de zaken die fout gedaan zijn).
En lees vooral ook de blogs van Dan North:https://dannorth.net/blog/

En als je eens een training/workshop wilt volgen...? Ga hier geen reclame maken... maar als je meer wilt weten, stuur gerust een PB! Ook vragen mogen gerust via een PB en indien agenatechnisch/reistechnisch haalbaar ben ik ook vaak wel bereid om een kopje koffie te doen om te babbelen over BDD in de praktijk... (leer ik namelijk ook weer van!).

[Reactie gewijzigd door kazz1980 op 23 juli 2024 06:32]

Dank je wel, ik heb "Impact Mapping" gekocht. In deze volgordelijkheid ga ik het lezen.

Impart Mapping
Specification by Example
BBD in action

Betreft het 'brainstormen' en/of workshop, ik hou het in gedachte! Thanks
Het is nogal een schot hagel, zo zonder te weten waar je specifiek naar zoekt / mee worstelt.

Neem aan dat je bij je hobby projectjes ook zelf het development doet. Dan zou ik ook 'ns kijken naar de links met TDD en DDD.
- Growing Object Oriented Software - zet neer hoe je van buiten naar binnen je software doet. Het spreekt niet van BDD (gaat er lichtjes aan vooraf), maar hun 'van buiten' kan uitstekend je set scenario's zijn
- Implementing Domain-Driven Design - is naar ik meen het meer toegankelijke boek om mee in het onderwerp te duiken.

En:
- de blogs van Liz Keogh
- (de blogs /) newsletter van Gojko

Verder geeft Gojko Adzic nog steeds meerdere malen per jaar de workshops Specification by Example en Impact Mapping in Nederland. (Disclosure: heb ik geen stake in, zijn gewoon het aanraden waard.)
Dank je wel. Ik heb "Implementing Domain-Driven Design" ook maar toegevoegd op mijn lijstje.

Zijn de workshops van Gojko Adzic een must, ook na het lezen van zijn boeken?
Een no brainer, voor mij althans; goede waarde voor tijd en geld. Vooral impact mapping komt zo goed tot leven voor je.

"Zijn ze een must?" leest voor mij als: "is er geen alternatief?" Dat is er wel; ook zonder de workshops kun je er prima komen.
Ik ontwikkel ook met Docker op OSX en had eerst de zelfde problemen met de snelheid. Het is ook bekend dat de filesystem laag die bestanden deelt tussen host en container ontzettend traag is.

Echter is er wel degelijk een oplossing die het (bijna) zo snel maakt als onder linux en echt werkbaar maakt: het weg mieteren van de all-in-one Docker applicatie en het installeren van docker en docker-machine via homebrew. Als engines heb je dan ruime keus maar zelf gebruik ik docker-machine-engine-xhyve dat de native VM mogelijkheden van OSX gebruikt. Met het aanmaken van een machine geef je aan NFS te willen gebruiken. Ook even op letten dat je op moment van schrijven boot2docker v18.06.1-ce gebruikt, deze moet je handmatig downloaden en het pad meegeven bij het aanmaken. Het heeft wat quirks maar het werkt prima.

Na het opstarten van de machine kun je in zijn configuratie NFS weer uitzetten (een van de quirks), de export blijft bestaan en hij blijft NFS gebruiken.

Ik kan het inmiddels bijna blind doen gelukkig :Y)
Bedankt voor de tips. We gebruiken bij mij op het werk nog Vagrant. Maar Docker belooft (zeker op Linux) een erg grote snelheidswinst. Ik onthou deze tips voor wanneer we dit verder door gaan zetten.

[Reactie gewijzigd door ArmEagle op 23 juli 2024 06:32]

Dat je "nog" Vagrant gebruikt komt een beetje over alsof dat een zwaar verouderd iets waar je zo snel mogelijk vanaf moet? Dat lijkt me namelijk helemaal niet het geval.
Zo bedoelde ik het niet. Vagrant is een grote hulp om iedereen eenzelfde ontwikkelomgeving te laten draaien. Ik bedoelde met 'nog' meer dat er wat proefjes gedaan worden met Docker en dat dit jaar voor ons mogelijk Vagrant gaat vervangen.

Maar ik zal de tekst een klein beetje aanpassen.
Ah OK, geen probleem hoor. Ik wilde je behoeden voor het per se moeten overstappen op Docker omdat Vagrant in combinatie met VM's en wat provisioning niet meer the way to go zou zijn :)
Zou inderdaad niet weten waarom Vagrant niet meer the way to go zou zijn. Prima tooling imho.
Voel je vrij om een mailtje te doen of dm te sturen als jullie vragen hebben :)
Leuk stuk om te lezen... Weer eens een echt tech artikel.. :)

Aangezien onze ontwikkelstraten anders zijn opgebouwd (CD pipelines vanuit Gitlab via Jenkins naar Nexus voor Kubernetes en Openshift) kan ik niet direct tips geven hoe zaken anders en sneller kunnen.

Wel is mijn ervaring toen we de overstap maakte naar microservices (waarbij het nu bijna een sport is om containers zo klein mogelijk te maken) de performance beter werd. De ontwikkelaars tweaken de containers continu om ze zo snel en efficiënt mogelijk te laten draaien.

Perfomance op desktops kan ik niet zo veel over melden. Ik draai zelf lokaal via VirtualBox Docker-CE in Swarm mode op Debian VM's omdat ik het op mijn MacOS zelf maar omslachtig vind.

[Reactie gewijzigd door Blommie01 op 23 juli 2024 06:32]

Wat is de reden dat jullie vanuit GitLab nog steeds via Jenkins werken?
Openshift.

Wat ook mee speelt is dat alle ontwikkelaars maar ook onze QA er mee kan lezen en schrijven. ;)

[Reactie gewijzigd door Blommie01 op 23 juli 2024 06:32]

Op dit item kan niet meer gereageerd worden.