Oefening: eenheidstests toevoegen aan uw toepassing
In deze les voegen we eenheidstests toe aan de geautomatiseerde build die we hebben gemaakt met Microsoft Azure Pipelines. Regressiefouten kruipen in de code van uw team en breken de filterfunctionaliteit van het leaderboard af. In het bijzonder wordt de verkeerde gamemodus weergegeven.
In de volgende afbeelding ziet u het probleem. Wanneer een gebruiker 'Milky Way' selecteert om alleen scores van die gamekaart weer te geven, krijgen ze resultaten van andere gamekaarten, zoals Andromeda.
Het team wil de fout ondervangen voordat het de testers bereikt. Eenheidstests zijn een uitstekende manier om automatisch te testen op regressiefouten.
Door de eenheidstests op dit moment in het proces toe te voegen, krijgt het team een voorsprong bij het verbeteren van de Space Game-web-app . De toepassing maakt gebruik van een documentdatabase voor het opslaan van hoge scores en spelerprofielen. Op dit moment worden lokale testgegevens gebruikt. Later zijn ze van plan om de app te verbinden met een livedatabase.
Er zijn veel moduletestframeworks beschikbaar voor C#-toepassingen. We gebruiken NUnit omdat het populair is bij de community.
Hier volgt de eenheidstest waarmee u werkt:
[TestCase("Milky Way")]
[TestCase("Andromeda")]
[TestCase("Pinwheel")]
[TestCase("NGC 1300")]
[TestCase("Messier 82")]
public void FetchOnlyRequestedGameRegion(string gameRegion)
{
const int PAGE = 0; // take the first page of results
const int MAX_RESULTS = 10; // sample up to 10 results
// Form the query predicate.
// This expression selects all scores for the provided game region.
Expression<Func<Score, bool>> queryPredicate = score => (score.GameRegion == gameRegion);
// Fetch the scores.
Task<IEnumerable<Score>> scoresTask = _scoreRepository.GetItemsAsync(
queryPredicate, // the predicate defined above
score => 1, // we don't care about the order
PAGE,
MAX_RESULTS
);
IEnumerable<Score> scores = scoresTask.Result;
// Verify that each score's game region matches the provided game region.
Assert.That(scores, Is.All.Matches<Score>(score => score.GameRegion == gameRegion));
}
U kunt het leaderboard filteren op elke combinatie van speltype en spelkaart.
Deze test voert een query uit op het leaderboard voor hoge scores en controleert of elk resultaat overeenkomt met de opgegeven gamekaart.
In een NUnit-testmethode TestCase
kunt u inlinegegevens gebruiken om die methode te testen. Hier roept NUnit de FetchOnlyRequestedGameRegion
eenheidstestmethode als volgt aan:
FetchOnlyRequestedGameRegion("Milky Way");
FetchOnlyRequestedGameRegion("Andromeda");
FetchOnlyRequestedGameRegion("Pinwheel");
FetchOnlyRequestedGameRegion("NGC 1300");
FetchOnlyRequestedGameRegion("Messier 82");
Let op de aanroep van de Assert.That
methode aan het einde van de test. Een bewering is een voorwaarde of instructie die u verklaart waar te zijn. Als de voorwaarde onwaar blijkt te zijn, kan dit duiden op een fout in uw code. NUnit voert elke testmethode uit met behulp van de inlinegegevens die u opgeeft en registreert het resultaat als een geslaagde of mislukte test.
Veel frameworks voor eenheidstests bieden verificatiemethoden die lijken op natuurlijke taal. Met deze methoden kunt u tests gemakkelijk lezen en helpen u de tests toe te wijzen aan de vereisten van de toepassing.
Bekijk de bewering in dit voorbeeld:
Assert.That(scores, Is.All.Matches<Score>(score => score.GameRegion == gameRegion));
U kunt deze regel lezen als:
Bevestig dat de gameregio van elke geretourneerde score overeenkomt met de opgegeven gameregio.
Dit is het proces dat u moet volgen:
- Haal een vertakking op uit de GitHub-opslagplaats die de eenheidstests bevat.
- Voer de tests lokaal uit om te controleren of ze zijn geslaagd.
- Voeg taken toe aan uw pijplijnconfiguratie om de tests uit te voeren en de resultaten te verzamelen.
- Push de vertakking naar uw GitHub-opslagplaats.
- Bekijk hoe uw Azure Pipelines-project de toepassing automatisch bouwt en de tests uitvoert.
De branch ophalen vanuit GitHub
Hier haalt u de unit-tests
vertakking op van GitHub en checkt u deze vertakking uit of schakelt u over naar die vertakking.
Deze vertakking bevat het Space Game-project waarmee u hebt gewerkt in de vorige modules en een Azure Pipelines-configuratie om mee te beginnen.
Open in Visual Studio Code de geïntegreerde terminal.
Voer de volgende
git
opdrachten uit om een vertakking op te halen met de naamunit-tests
uit de Microsoft-opslagplaats en schakel vervolgens over naar die vertakking.git fetch upstream unit-tests git checkout -B unit-tests upstream/unit-tests
Met de indeling van deze opdracht kunt u starterscode ophalen uit de Microsoft GitHub-opslagplaats, ook wel bekend als
upstream
. Binnenkort pusht u deze vertakking naar uw GitHub-opslagplaats, ook wel bekend alsorigin
.Als optionele stap opent u het azure-pipelines.yml-bestand in Visual Studio Code en maakt u vertrouwd met de eerste configuratie. De configuratie lijkt op de basisconfiguratie die u hebt gemaakt in de module Een build-pipeline maken met Azure Pipelines. Hiermee wordt alleen de releaseconfiguratie van de toepassing geconfigureerd.
De tests lokaal uitvoeren
Het is een goed idee om alle tests lokaal uit te voeren voordat u tests naar de pijplijn verzendt. Dat gaat u hier doen.
Open in Visual Studio Code de geïntegreerde terminal.
Voer deze opdracht uit
dotnet build
om elk project in de oplossing te bouwen.dotnet build --configuration Release
Voer de volgende
dotnet test
opdracht uit om de eenheidstests uit te voeren:dotnet test --configuration Release --no-build
De
--no-build
vlag geeft aan dat het project niet moet worden gebouwd voordat het wordt uitgevoerd. U hoeft het project niet te bouwen omdat u het in de vorige stap hebt gebouwd.U ziet dat alle vijf de tests slagen.
Starting test execution, please wait... A total of 1 test files matched the specified pattern. Passed! - Failed: 0, Passed: 5, Skipped: 0, Total: 5, Duration: 57 ms
In dit voorbeeld hebben de tests minder dan één seconde geduurd om uit te voeren.
U ziet dat er vijf totaaltests zijn. Hoewel we slechts één testmethode hebben gedefinieerd,
FetchOnlyRequestedGameRegion
wordt die test vijf keer uitgevoerd, één keer voor elke gamekaart zoals opgegeven in deTestCase
inlinegegevens.Voer de tests een tweede keer uit. Geef deze keer de
--logger
optie op om de resultaten naar een logboekbestand te schrijven.dotnet test Tailspin.SpaceGame.Web.Tests --configuration Release --no-build --logger trx
U ziet in de uitvoer dat er een TRX-bestand wordt gemaakt in de map TestResults .
Een TRX-bestand is een XML-document dat de resultaten van een testuitvoering bevat. Het is een populaire indeling voor testresultaten, omdat Visual Studio en andere hulpprogramma's u kunnen helpen de resultaten te visualiseren.
Later ziet u hoe u met Azure Pipelines uw testresultaten kunt visualiseren en bijhouden terwijl ze door de pijplijn worden uitgevoerd.
Notitie
TRX-bestanden zijn niet bedoeld om te worden opgenomen in broncodebeheer. Met een .gitignore-bestand kunt u opgeven welke tijdelijke en andere bestanden u door Git wilt negeren. Het .gitignore-bestand van het project is al ingesteld om alles in de map TestResults te negeren.
Als optionele stap opent u in Visual Studio Code het bestand DocumentDBRepository_GetItemsAsyncShould.cs uit de map Tailspin.SpaceGame.Web.Tests en bekijkt u de testcode. Zelfs als u niet specifiek geïnteresseerd bent in het bouwen van .NET-apps, vindt u mogelijk de testcode nuttig omdat deze lijkt op code die u in andere eenheidstestframeworks ziet.
Taken toevoegen aan uw pijplijnconfiguratie
Hier configureert u de build-pijplijn om uw eenheidstests uit te voeren en de resultaten te verzamelen.
Wijzig in Visual Studio Code azure-pipelines.yml als volgt:
trigger: - '*' pool: vmImage: 'ubuntu-20.04' demands: - npm variables: buildConfiguration: 'Release' wwwrootDir: 'Tailspin.SpaceGame.Web/wwwroot' dotnetSdkVersion: '6.x' steps: - task: UseDotNet@2 displayName: 'Use .NET SDK $(dotnetSdkVersion)' inputs: version: '$(dotnetSdkVersion)' - task: Npm@1 displayName: 'Run npm install' inputs: verbose: false - script: './node_modules/.bin/node-sass $(wwwrootDir) --output $(wwwrootDir)' displayName: 'Compile Sass assets' - task: gulp@1 displayName: 'Run gulp tasks' - script: 'echo "$(Build.DefinitionName), $(Build.BuildId), $(Build.BuildNumber)" > buildinfo.txt' displayName: 'Write build info' workingDirectory: $(wwwrootDir) - task: DotNetCoreCLI@2 displayName: 'Restore project dependencies' inputs: command: 'restore' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Build the project - $(buildConfiguration)' inputs: command: 'build' arguments: '--no-restore --configuration $(buildConfiguration)' projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: 'Run unit tests - $(buildConfiguration)' inputs: command: 'test' arguments: '--no-build --configuration $(buildConfiguration)' publishTestResults: true projects: '**/*.Tests.csproj' - task: DotNetCoreCLI@2 displayName: 'Publish the project - $(buildConfiguration)' inputs: command: 'publish' projects: '**/*.csproj' publishWebProjects: false arguments: '--no-build --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)' zipAfterPublish: true - task: PublishBuildArtifacts@1 displayName: 'Publish Artifact: drop' condition: succeeded()
In deze versie wordt deze
DotNetCoreCLI@2
buildtaak geïntroduceerd.- task: DotNetCoreCLI@2 displayName: 'Run unit tests - $(buildConfiguration)' inputs: command: 'test' arguments: '--no-build --configuration $(buildConfiguration)' publishTestResults: true projects: '**/*.Tests.csproj'
Met deze build-taak wordt de
dotnet test
opdracht uitgevoerd.U ziet dat met deze taak niet het
--logger trx
argument wordt opgegeven dat u hebt gebruikt bij het handmatig uitvoeren van de tests. HetpublishTestResults
argument voegt dat voor u toe. Dit argument vertelt de pijplijn om het TRX-bestand te genereren naar een tijdelijke map die toegankelijk is via de$(Agent.TempDirectory)
ingebouwde variabele. Ook worden de taakresultaten naar de pijplijn gepubliceerd.Het
projects
argument geeft alle C#-projecten op die overeenkomen met **/*. Tests.csproj." Het deel ** komt overeen met alle mappen en de *. Het onderdeel Tests.csproj komt overeen met alle projecten waarvan de bestandsnaam eindigt op '. Tests.csproj." Deunit-tests
vertakking bevat slechts één eenheidstestproject, Tailspin.SpaceGame.Web.Tests.csproj. Door een patroon op te geven, kunt u meer testprojecten uitvoeren zonder dat u de buildconfiguratie hoeft te wijzigen.
De vertakking naar GitHub pushen
Hier pusht u uw wijzigingen naar GitHub en ziet u de pijplijnuitvoering. Zoals u weet, bevindt u zich momenteel in de vertakking unit-tests
.
Voeg in de geïntegreerde terminal azure-pipelines.yml toe aan de index, voer de wijzigingen door en push de vertakking naar GitHub.
git add azure-pipelines.yml git commit -m "Run and publish unit tests" git push origin unit-tests
Bekijk hoe Azure Pipelines de tests uitvoert
Hier ziet u de tests die worden uitgevoerd in de pijplijn en visualiseert u vervolgens de resultaten van Microsoft Azure-testplannen. Azure Test Plans biedt alle hulpprogramma's die u nodig hebt om uw toepassingen te testen. U kunt handmatige testplannen maken en uitvoeren, geautomatiseerde tests genereren en feedback verzamelen van belanghebbenden.
Traceer in Azure Pipelines de build via elk van de stappen.
U ziet dat de eenheidstests uitvoeren- Releasetaak de eenheidstests uitvoert, net zoals u handmatig hebt uitgevoerd vanaf de opdrachtregel.
Ga terug naar de pijplijnsamenvatting.
Naar het tabblad Tests gaan.
U ziet een samenvatting van de testuitvoering. Alle vijf de tests zijn geslaagd.
Selecteer In Azure DevOps testplannen en selecteer vervolgens Runs.
U ziet de meest recente testuitvoeringen, inclusief de test die u zojuist hebt uitgevoerd.
Dubbelklik op de meest recente testuitvoering.
U ziet een samenvatting van de resultaten.
In dit voorbeeld zijn alle vijf de tests geslaagd. Als er tests zijn mislukt, kunt u naar de build-taak gaan voor meer informatie.
U kunt het TRX-bestand ook downloaden om het te onderzoeken via Visual Studio of een ander visualisatieprogramma.
Hoewel u slechts één test hebt toegevoegd, is het een goed begin en wordt het onmiddellijke probleem opgelost. Het team heeft nu een plek om meer tests toe te voegen en ze uit te voeren naarmate ze hun proces verbeteren.
Uw vertakking samenvoegen in de hoofdmap
In een praktijkscenario, als u tevreden bent met de resultaten, kunt u de unit-tests
vertakking samenvoegen naar main
, maar voor kortheid slaan we dat proces voorlopig over.