Wat is lustesten? Methodologie, voorbeeld

โšก Slimme samenvatting

Looptesten valideren de lusconstructies binnen een programma en controleren wat er gebeurt wanneer een lus wordt overgeslagen, eenmaal wordt betreden, wordt uitgevoerd op de grens ervan en รฉรฉn keer verder wordt doorlopen dan het maximaal toegestane aantal.

  • ๐Ÿ”˜ Definitie: Een white-box besturingsstructuurtechniek gericht op lusvaliditeit, niet op schermen.
  • ๐Ÿ” Vier klassen: Eenvoudige, geneste, aaneengesloten en ongestructureerde lussen vereisen elk hun eigen strategie.
  • ๐Ÿ“ Drie controlepunten: Toegang tot de lus, gedrag tijdens de uitvoering en de exitconditie.
  • ๐Ÿงช Grensovergangen: Nul, รฉรฉn, twee, een typisch aantal, vervolgens b-1, b en b+1 herhalingen.
  • ๐Ÿชœ Geneste volgorde: Begin bij de binnenste lus, houd de buitenste lussen op de minimale spanning en werk dan naar buiten toe.
  • ๐Ÿž Gevonden defecten: Off-by-one-limieten, niet-geรฏnitialiseerde tellers, oneindige lussen en capaciteitsknelpunten.
  • โš ๏ธ Beperking: Lusfouten bevinden zich in code op een lager niveau en zijn zelden subtiel als ze eenmaal aan het licht komen.

Looptestmethodologie, soorten lussen en voorbeeldtestgevallen

Wat is lustesten?

Lus testen Dit is een type softwaretest dat zich volledig richt op de geldigheid van de lusconstructies in een programma. Het is een onderdeel van het testen van controlestructuren, samen met padtesten, datavalidatietests en conditietests.

Lustesten is een witte doos testen Deze techniek wordt toegepast door iemand die de broncode kan lezen en de lusvoorwaarde, de teller en het exitpad kan zien. De tester hoeft het gedrag niet af te leiden uit de gebruikersinterface; de โ€‹โ€‹lus zelf is het object dat getest wordt.

Het onderstaande diagram laat zien waar lus testen zich bevindt binnen de testfamilie van de besturingsstructuur.

Lustesten worden gezien als een onderdeel van het testen van de besturingsstructuur.

Soorten lus Getest

Voordat je een strategie kiest, moet je eerst bepalen naar welke van de vier lussoorten je kijkt. Voorbeelden van geteste lussoorten zijn:

  • Eenvoudige lus โ€” een enkele lus met รฉรฉn ingang en รฉรฉn uitgang, zoals een eenvoudige lus. besteld,, en or doen terwijl bouwen.
  • Geneste lus โ€” een lus binnen een andere geplaatst, zodat de binnenste lus volledig wordt uitgevoerd bij elke doorgang van de buitenste lus.
  • Aaneengeschakelde lus โ€” twee of meer lussen die na elkaar in volgorde worden uitgevoerd.
  • Ongestructureerde lus โ€” een ongeplande combinatie van geneste en aaneengesloten lussen, meestal het resultaat van sprongen in of uit de body van een lus.

De klasse bepaalt de benodigde inspanning. Een eenvoudige lus vereist slechts een handvol iteraties; een ongestructureerde lus vereist meestal een herontwerp van de code voordat deze รผberhaupt getest kan worden.

Waarom lustesten?

Lustesten worden om de volgende redenen uitgevoerd

  • Testen kan de problemen met de herhaling van de lus oplossen
  • Looptesten kunnen knelpunten in prestaties en capaciteit aan het licht brengen.
  • Door lussen te testen, kunnen de niet-geรฏnitialiseerde variabelen in de lus worden vastgesteld.
  • Het helpt bij het identificeren van problemen met de initialisatie van lussen.

Er is ook een commerciรซle reden. Een lus die รฉรฉn iteratie te vaak doorloopt, verstoort het totaal; een lus die nooit eindigt, laat een proces vastlopen. Beide defecten zijn goedkoop te vinden zolang de code zich nog op een ontwikkelmachine bevindt, maar duur om te ontdekken in een productieomgeving.

Hoe u lustesten uitvoert: volledige methodologie

Bij het testen van een lus moet deze op drie verschillende niveaus worden gecontroleerd:

  • Wanneer de lus wordt betreden
  • Tijdens de uitvoering ervan, en
  • Wanneer de lus overblijft

De teststrategie voor al deze lussen is als volgt.

Eenvoudige lus

Een eenvoudige lus heeft รฉรฉn ingang en รฉรฉn uitgang, zoals hieronder weergegeven.

Eenvoudig lusstroomdiagram met รฉรฉn ingangspunt en รฉรฉn uitgangsvoorwaarde.

Een eenvoudige lus wordt op de volgende manier getest:

  1. Sla de hele lus over
  2. Doorloop de lus รฉรฉn keer.
  3. Maak 2 keer door de lus
  4. Merk a gaat door de lus waar a < bDat is een typisch aantal iteraties in het middensegment.
  5. Merk b, b-1 en b+1 gaat door de lus waar b is het maximale aantal toegestane iteraties door de lus.

De laatste twee gevallen bevatten de meeste waarde. Overslaanping De lus bewijst dat de exit-voorwaarde wordt geรซvalueerd voordat de code wordt uitgevoerd, en de bHet +1-geval bewijst dat de lus weigert verder te werken dan de aangegeven limiet, in plaats van een array te overlopen.

Geneste lus

Een geneste lus vermenigvuldigt het aantal mogelijke iteratiecombinaties, waardoor deze van binnen naar buiten wordt getest in plaats van allemaal tegelijk.

Geneste lusstroomdiagram met een binnenste lus die wordt omsloten door een buitenste lus.

Voor een geneste lus moet je de volgende stappen volgen.

  1. Stel alle andere lussen in op hun minimumwaarde en begin bij de binnenste lus.
  2. Voer voor de binnenste lus een eenvoudige lustest uit en houd de buitenste lussen op hun minimale iteratieparameterwaarde
  3. Voer de test uit voor de volgende lus en werk van daaruit verder.
  4. Ga door totdat de buitenste lus is getest.

Aaneengeschakelde lussen

Aaneengesloten lussen bevinden zich na elkaar in hetzelfde uitvoeringspad, zoals het diagram laat zien.

Stroomdiagram van aaneengesloten lussen die twee lussen tonen die achter elkaar worden uitgevoerd.

Bij aaneengesloten lussen worden twee lussen, indien ze onafhankelijk van elkaar zijn, getest met behulp van de eenvoudige lusmethode; anders worden ze getest als geneste lussen.

Als de lussteller van de ene lus echter als beginwaarde voor de andere wordt gebruikt, worden de twee lussen niet als onafhankelijk beschouwd.

Ongestructureerde lussen

Ongestructureerde lussen zijn het lastigst, omdat de besturing op willekeurige punten in en uit de lus springt.

Ongestructureerd lusstroomdiagram met besturingssprongping in en uit de lus

Voor ongestructureerde lussen moet het ontwerp worden aangepast aan het gebruik van gestructureerde programmeerconstructies. Zodra de code is gereduceerd tot eenvoudige, geneste of aaneengesloten vormen, is de bovenstaande matchingstrategie van toepassing.

Voorbeeld van lus testen met testgevallen

Een uitgewerkt voorbeeld maakt het aantal iteraties concreet. Beschouw een routine die een lopend resultaat vermenigvuldigt met elk geheel getal van 1 tot ... n, een faculteitsberekening. De lussteller begint bij 1, de exitvoorwaarde is teller > nEn de lus is zo gedefinieerd dat deze maximaal 12 keer doorlopen mag worden voordat het resultaat het gedeclareerde integer-type overschrijdt.

Als we dit als een eenvoudige lus beschouwen, vertalen de hierboven aanbevolen iteratieaantallen zich naar het volgende: testgevallen.

Testgeval Waarde van n Passes uitgevoerd Wat het bewijst
TC01 0 0 (lus overgeslagen) De exit-conditie wordt geรซvalueerd voordat de code wordt uitgevoerd, en het resultaat behoudt de initiรซle waarde van 1.
TC02 1 1 Eรฉn enkele doorgang levert het juiste resultaat op en de teller wordt รฉรฉn keer verhoogd.
TC03 2 2 De accumulator draagt โ€‹โ€‹een waarde over tussen twee opeenvolgende doorgangen.
TC04 5 5 Een typische telling in het middenbereik levert de verwachte 120 op, wat het normale gedrag bevestigt.
TC05 11 11 Eรฉn doorgang onder het maximum wordt nog steeds normaal voltooid (b-1).
TC06 12 12 Het opgegeven maximum wordt geaccepteerd en de lus eindigt (b).
TC07 13 verworpen Eรฉn doorgang boven het maximum wordt geweigerd in plaats van stilzwijgend over te lopen (b+ 1).

Merk op dat TC01 en TC07 de twee gevallen zijn die ontwikkelaars het vaakst overslaan, en dat dit de twee gevallen zijn die fouten met overgeslagen initialisatie en overloop aan het licht brengen. Een negatieve waarde van n behoort tot dezelfde set als de specificatie de levering ervan toestaat, wat lus testen koppelt aan negatief testen.

Veelvoorkomende defecten gevonden door middel van lus testen

Lustests blijven steeds dezelfde kleine groep fouten vinden, en dat is de reden waarom het vaste aantal iteraties de moeite waard is om elke keer opnieuw uit te voeren.

  • Off-by-one grenzen โ€” een aandoening die geschreven is als < met de meeste <= was de bedoeling, dus de lus wordt รฉรฉn keer te weinig of รฉรฉn keer te veel doorlopen.
  • Niet-geรฏnitialiseerde tellers of accumulatoren โ€” een totaalbedrag dat een restwaarde van een vorige oproep bevat.
  • Oneindige lussen โ€” een exitvoorwaarde waaraan de lusbody nooit kan voldoen, omdat de teller slechts bij sommige takken wordt bijgewerkt.
  • Aannames overgeslagen lussen โ€” code na de lus die een variabele leest die de lusbody had moeten instellen, maar die mislukt als de lus nul keer wordt uitgevoerd.
  • Capaciteits- en prestatieproblemen โ€” een lus die correct is, maar de database bij elke iteratie opnieuw leest, waardoor de kosten toenemen met het aantal iteraties.
  • Geneste-lusinterferentie โ€” een binnenste lus die de teller van de buitenste lus hergebruikt en de iteratieteller van de buitenste lus stilletjes wijzigt.

Omdat elke fout overeenkomt met een specifiek aantal iteraties, zijn de hier gevonden defecten gemakkelijk te reproduceren en snel te verhelpen in vergelijking met defecten die bij hogere iteraties worden aangetroffen. testniveaus.

Lus testen versus andere testtechnieken voor regelstructuren

Lus testen is een onderdeel van de familie van regelstructuren en kan gemakkelijk verward worden met verwante technieken. De onderstaande tabel maakt onderscheid tussen deze technieken.

Techniek Wat het beoogt Typisch dekkingsdoel
Loop testen Lusconstructies: ingang, iteratietelling en uitgang Nul, รฉรฉn, typisch en grenswaarde van het aantal iteraties voor elke lus
Conditietesten Booleaanse expressies binnen beslissingen Bij elke voorwaarde werden zowel de ware als de onware uitkomsten beoordeeld.
Testen van de gegevensstroom Definitie en gebruik van elke variabele Elk paar definities en toepassingen is minstens รฉรฉn keer geoefend.
Basispad testen Onafhankelijke paden door het besturingsstroomdiagram Een aantal paden gelijk aan de cyclomatische complexiteit

In de praktijk vullen deze technieken elkaar aan in plaats van met elkaar te concurreren. Cyclomatische complexiteit Het vertelt je hoeveel onafhankelijke paden er zijn, basispadtesten dekken deze af, en lustesten voegen vervolgens het aantal iteraties toe dat paddekking alleen niet zou afdwingen. Ze zijn allemaal dynamisch testen activiteiten, aangezien de code moet worden uitgevoerd om de resultaten te kunnen zien.

Beperking bij lustesten

De techniek heeft wel degelijk beperkingen, en door die te kennen voorkom je overinvestering.

  • Loop-bugs komen vooral voor in software op laag niveau
  • De bugs die tijdens het testen van de lus worden geรฏdentificeerd, zijn niet erg subtiel
  • Veel van deze bugs kunnen door het besturingssysteem worden gedetecteerd, omdat ze geheugenoverschrijdingen, detecteerbare pointerfouten en soortgelijke fouten veroorzaken.
  • Het bepalen van de klasse van elke lus en het dienovereenkomstig testen ervan kost tijd, wat moeilijk te rechtvaardigen is bij codefragmenten die weinig risico met zich meebrengen.

Veelgestelde vragen

Ontwikkelaars en technische testers met toegang tot de broncode, meestal tijdens testen van een eenheid of codebeoordeling. Bedrijfstesters kunnen het niet toepassen, omdat de lusvoorwaarde niet zichtbaar is voor de gebruikersinterface.

Een model leest de lusvoorwaarde en stelt automatisch de nul-, รฉรฉn-, typische en grenswaarden voor het aantal iteraties voor, inclusief het geval van overloop. Een reviewer bevestigt vervolgens nog steeds of elk verwacht resultaat overeenkomt met de specificatie.

Het systeem stelt ze snel op, omdat het iteratiepatroon formulematig is. Agenten kunnen de testsuite ook uitvoeren en rapporteren welke tellingen mislukken, maar het bepalen van het maximaal toegestane aantal geslaagde tests blijft een ontwerpbeslissing die door een mens wordt genomen.

Voer de test uit met een time-out of iteratiecontrole, zodat de test snel mislukt in plaats van dat de testsuite vastloopt. Controleer het aantal geregistreerde passes, niet alleen de uiteindelijke uitvoerwaarde.

Veel minder dan elke mogelijke combinatie. Door van binnen naar buiten te testen, blijft het aantal ruwweg optelbaar over de niveaus in plaats van vermenigvuldigd, omdat de buitenste lussen op hun minimumwaarde worden vastgezet terwijl de binnenste lus wordt gebruikt.

Er is geen specifiek hulpmiddel voor. Teams combineren een framework voor unit-tests, zoals... JUnit Of gebruik pytest met een coverage tool die de branch coverage rapporteert, en lees vervolgens het rapport om te bevestigen dat het pad zonder iteraties is bereikt.

Nee. Branch coverage is voldaan zodra een lus eenmaal is betreden en verlaten. Lus testen vereist bovendien het aantal overgeslagen stappen en het aantal grensovergangen, iets wat branch coverage alleen nooit afdwingt.

Wanneer het ongestructureerd is, controleer dan de sprong.ping In of uit het lichaam. Herstructureren in eenvoudige, geneste of aaneengesloten vormen is goedkoper dan het ontwerpen van tests voor elk onregelmatig insteekpunt.

Vat dit bericht samen met: