Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
IntelliTest genereert invoer voor geparameteriseerde eenheidstests door de vertakkingsvoorwaarden in het programma te analyseren. Testinvoer wordt gekozen op basis van of ze nieuw vertakkingsgedrag van het programma kunnen activeren. De analyse is een incrementeel proces. Het verfijnt een predicaat q: I -> {true, false} over de formele testinvoerparameters I.
q vertegenwoordigt de set van gedragingen die IntelliTest al heeft waargenomen. In eerste instantie, q := falseomdat er nog niets is waargenomen.
De stappen van de lus zijn:
IntelliTest bepaalt invoer
izodanig datq(i)=falseeen beperkingslosser wordt gebruikt. Door de constructie neemt de invoerieen uitvoeringspad dat nog niet eerder is gezien. In eerste instantie betekent dit datielke invoer kan zijn, omdat er nog geen uitvoeringspad is gedetecteerd.IntelliTest voert de test uit met de gekozen invoer
ien bewaakt de uitvoering van de test en het programma dat wordt getest.Tijdens de uitvoering gebruikt het programma een bepaald pad dat wordt bepaald door alle voorwaardelijke vertakkingen van het programma. De set met alle voorwaarden die bepalen hoe de uitvoering wordt uitgevoerd, wordt de padvoorwaarde genoemd, geschreven als predicaat
p: I -> {true, false}voor de formele invoerparameters. IntelliTest berekent een weergave van dit predicaat.IntelliTest instelt
q := (q or p). Met andere woorden, het registreert het feit dat het het pad heeft gezien dat wordt vertegenwoordigd doorp.Ga naar stap 1.
De beperkingslosser van IntelliTest kan omgaan met waarden van alle typen die kunnen worden weergegeven in .NET-programma's:
IntelliTest filtert invoer uit die de gestelde veronderstellingen schendt.
Naast de directe invoer (argumenten voor geparameteriseerde eenheidstests), kan een test verdere invoerwaarden uit de statische klasse PexChoose tekenen. De keuzes bepalen ook het gedrag van geparameteriseerde mocks.
Beperking oplosser
IntelliTest maakt gebruik van een beperking oplosser om de relevante invoerwaarden van een test en het programma te bepalen dat wordt getest.
IntelliTest maakt gebruik van de Z3-beperking oplosser.
Dynamische codedekking
Als neveneffect van de runtimebewaking verzamelt IntelliTest dynamische codedekkingsgegevens. Dit wordt dynamisch genoemd omdat IntelliTest alleen weet over code die is uitgevoerd. Daarom kunnen er geen absolute waarden worden opgegeven voor dekking op dezelfde manier als bij andere dekkingsprogramma's.
Wanneer IntelliTest bijvoorbeeld de dynamische dekking rapporteert als basisblokken van 5/10, betekent dit dat er vijf blokken van tien werden behandeld, waarbij het totale aantal blokken in alle methoden die tot nu toe zijn bereikt door de analyse (in plaats van alle methoden die in de assembly onder test staan) tien is. Later in de analyse, naarmate er meer bereikbare methoden worden gedetecteerd, kunnen zowel de teller (5 in dit voorbeeld) als de noemer (10) toenemen.
Gehele getallen en kommagetallen
De beperkingslosser van IntelliTest bepaalt de invoerwaarden van primitieve typen primitieven, zoals byte, int, float en andere, om verschillende uitvoeringspaden voor de test en het programma onder test te activeren.
Objects
IntelliTest kan exemplaren van bestaande .NET-klassen maken of u kunt IntelliTest gebruiken om automatisch mock-objecten te maken die een specifieke interface implementeren en zich op verschillende manieren gedragen, afhankelijk van het gebruik.
Bestaande klassen instantiëren
Wat is het probleem?
IntelliTest bewaakt de uitgevoerde instructies wanneer er een test en het programma onder test worden uitgevoerd. Het bewaakt met name alle toegang tot velden. Vervolgens wordt een beperking oplosser gebruikt om nieuwe testinvoer te bepalen, inclusief objecten en hun veldwaarden, zodat de test en het programma onder test zich op andere interessante manieren gedragen.
Dit betekent dat IntelliTest objecten van bepaalde typen moet maken en hun veldwaarden moet instellen. Als de klasse zichtbaar is en een zichtbare standaardconstructor heeft, kan IntelliTest een exemplaar van de klasse maken. Als alle velden van de klasse zichtbaar zijn, kan IntelliTest de velden automatisch instellen.
Als het type niet zichtbaar is of als de velden niet zichtbaar zijn, moet IntelliTest helpen bij het maken van objecten en deze in interessante statussen brengen om maximale codedekking te bereiken. IntelliTest kan reflectie gebruiken om exemplaren op willekeurige manieren te maken en te initialiseren, maar dit is meestal niet wenselijk omdat het object een status kan hebben die nooit kan optreden tijdens de normale uitvoering van het programma. In plaats daarvan is IntelliTest afhankelijk van hints van de gebruiker.
Zichtbaarheid
.NET heeft een uitgebreid zichtbaarheidsmodel: typen, methoden, velden en andere leden kunnen privé, openbaar, intern en meer zijn.
Wanneer IntelliTest tests genereert, wordt geprobeerd alleen acties uit te voeren (zoals aanroepen van constructors, methoden en instellingsvelden) die juridisch zijn met betrekking tot .NET-zichtbaarheidsregels binnen de context van de gegenereerde tests.
De regels zijn als volgt:
Zichtbaarheid van interne leden
- IntelliTest gaat ervan uit dat de gegenereerde tests toegang hebben tot interne leden die zichtbaar waren voor de omsluitende PexClass. .NET heeft de InternalsVisibleToAttribute om de zichtbaarheid van interne leden uit te breiden naar andere assembly's.
Zichtbaarheid van privé- en familieleden (beveiligd in C#) van de PexClass
- IntelliTest plaatst de gegenereerde tests altijd rechtstreeks in de PexClass of in een subklasse. Daardoor gaat IntelliTest ervan uit dat het alle zichtbare klasseleden (protected in C#) kan gebruiken.
- Als de gegenereerde tests rechtstreeks in de PexClass worden geplaatst (meestal met behulp van gedeeltelijke klassen), gaat IntelliTest ervan uit dat deze ook alle persoonlijke leden van de PexClass kan gebruiken.
Zichtbaarheid van openbare leden
- IntelliTest gaat ervan uit dat alle geëxporteerde leden kunnen worden gebruikt die zichtbaar zijn in de context van de PexClass.
Geparameteriseerde mocks
Hoe test ik een methode met een parameter van een interfacetype? Of van een niet-verzegelde klasse? IntelliTest weet niet welke implementaties later worden gebruikt wanneer deze methode wordt aangeroepen. En misschien is er niet eens een echte implementatie beschikbaar op testtijd.
Het conventionele antwoord is het gebruik van mock-objecten met expliciet gedrag.
Een mock-object implementeert een interface (of breidt een niet-verzegelde klasse uit). Het vertegenwoordigt geen echte implementatie, maar alleen een snelkoppeling waarmee tests kunnen worden uitgevoerd met behulp van het mock-object. Het gedrag wordt handmatig gedefinieerd als onderdeel van elke testcase waarin het wordt gebruikt. Er bestaan veel hulpprogramma's waarmee u eenvoudig mockobjecten en hun verwachte gedrag kunt definiëren, maar dit gedrag moet nog steeds handmatig worden gedefinieerd.
IntelliTest kan de waarden genereren in plaats van in code vastgelegde waarden in mock-objecten. Net zoals met geparameteriseerde unittests, schakelt IntelliTest ook geparameteriseerde mocks in.
Geparameteriseerde mocks hebben twee verschillende uitvoeringsmodi:
- kiezen: bij het verkennen van code zijn geparameteriseerde mocks een bron van aanvullende testinvoer en probeert IntelliTest interessante waarden te kiezen
- replay: bij het uitvoeren van een eerder gegenereerde test gedragen geparameteriseerde mocks zich als stubs met gedrag (met andere woorden, vooraf gedefinieerd gedrag).
Gebruik PexChoose om waarden te verkrijgen voor geparameteriseerde mocks.
Structuren
De redenering van IntelliTest over structwaarden is vergelijkbaar met de manier waarop deze met objecten omgaat.
Matrices en tekenreeksen
IntelliTest bewaakt de uitgevoerde instructies terwijl er een test en het programma onder test worden uitgevoerd. Met name wanneer het programma afhankelijk is van de lengte van een tekenreeks of een matrix (en de ondergrenzen en lengten van een multidimensionale matrix). Ook ziet u hoe het programma gebruikmaakt van de verschillende elementen van een tekenreeks of matrix. Vervolgens wordt een constraint solver gebruikt om te bepalen welke lengten en elementwaarden ervoor kunnen zorgen dat de test en het programma dat wordt getest zich op interessante manieren gedragen.
IntelliTest probeert de grootte van de matrices en tekenreeksen te minimaliseren die nodig zijn om interessant programmagedrag te activeren.
Aanvullende invoer verkrijgen
De statische klasse PexChoose kan worden gebruikt om extra invoer voor een test te verkrijgen en kan worden gebruikt om geparameteriseerde mocks te implementeren.
Heb je feedback?
Plaats uw ideeën en functieaanvragen in de ontwikkelaarscommunity.