Övning – Lägga till enhetstester i ditt program
I den här lektionen lägger vi till enhetstester i den automatiserade versionen som vi skapade med Microsoft Azure Pipelines. Regressionsbuggar kryper in i teamets kod och bryter rankningslistans filtreringsfunktioner. Mer specifikt fortsätter fel spelläge att visas.
Följande bild illustrerar problemet. När en användare väljer "Vintergatan" för att endast visa poäng från den spelkartan får de resultat från andra spelkartor, till exempel Andromeda.
Teamet vill fånga upp felet innan det når testarna. Enhetstester är ett bra sätt att automatiskt testa för regressionsbuggar.
Genom att lägga till enhetstesterna vid den här tidpunkten i processen får teamet ett försprång när de förbättrar webbappen Space Game . Programmet använder en dokumentdatabas för att lagra höga poäng och spelarprofiler. Just nu använder den lokala testdata. Senare planerar de att ansluta appen till en livedatabas.
Många enhetstestramverk är tillgängliga för C#-program. Vi använder NUnit eftersom det är populärt i communityn.
Här är enhetstestet som du arbetar med:
[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));
}
Du kan filtrera rankningslistan efter valfri kombination av speltyp och spelkarta.
Det här testet frågar rankningslistan efter höga poäng och verifierar att varje resultat matchar den angivna spelkartan.
I en NUnit-testmetod TestCase
tillhandahåller infogade data att använda för att testa den metoden. Här anropar FetchOnlyRequestedGameRegion
NUnit enhetstestmetoden enligt följande:
FetchOnlyRequestedGameRegion("Milky Way");
FetchOnlyRequestedGameRegion("Andromeda");
FetchOnlyRequestedGameRegion("Pinwheel");
FetchOnlyRequestedGameRegion("NGC 1300");
FetchOnlyRequestedGameRegion("Messier 82");
Observera anropet Assert.That
till metoden i slutet av testet. Ett påstående är ett villkor eller en instruktion som du deklarerar vara sant. Om villkoret visar sig vara falskt kan det tyda på en bugg i koden. NUnit kör varje testmetod med hjälp av de infogade data som du anger och registrerar resultatet som ett godkänt eller misslyckat test.
Många enhetstestramverk tillhandahåller verifieringsmetoder som liknar naturligt språk. De här metoderna gör det enkelt att läsa och hjälpa dig att mappa testerna till programmets krav.
Överväg försäkran i det här exemplet:
Assert.That(scores, Is.All.Matches<Score>(score => score.GameRegion == gameRegion));
Du kan läsa den här raden som:
Bekräfta att spelregionen för varje returnerad poäng matchar den angivna spelregionen.
Här är processen att följa:
- Hämta en gren från GitHub-lagringsplatsen som innehåller enhetstesterna.
- Kör testerna lokalt för att verifiera att de har godkänts.
- Lägg till uppgifter i pipelinekonfigurationen för att köra testerna och samla in resultaten.
- Skicka grenen till din GitHub-lagringsplats.
- Se hur ditt Azure Pipelines-projekt automatiskt skapar programmet och kör testerna.
Hämta grenen från GitHub
Här hämtar du grenen unit-tests
från GitHub och checkar ut eller växlar till den grenen.
Den här grenen innehåller space game-projektet som du arbetade med i de föregående modulerna och en Azure Pipelines-konfiguration till att börja med.
Öppna den integrerade terminalen i Visual Studio Code.
Kör följande
git
kommandon för att hämta en gren med namnetunit-tests
från Microsoft-lagringsplatsen och växla sedan till den grenen.git fetch upstream unit-tests git checkout -B unit-tests upstream/unit-tests
Med formatet för det här kommandot kan du hämta startkod från Microsoft GitHub-lagringsplatsen, som
upstream
kallas . Snart skickar du den här grenen till din GitHub-lagringsplats, somorigin
kallas .Som ett valfritt steg öppnar du filen azure-pipelines.yml i Visual Studio Code och bekanta dig med den inledande konfigurationen. Konfigurationen liknar den grundläggande konfiguration som du skapade i modulen Skapa en bygg-pipeline med Azure-pipelines. Den skapar endast programmets versionskonfiguration.
Köra testerna lokalt
Det är en bra idé att köra alla tester lokalt innan du skickar några tester till pipelinen. Det ska vi göra nu.
Öppna den integrerade terminalen i Visual Studio Code.
Kör
dotnet build
för att skapa varje projekt i lösningen.dotnet build --configuration Release
Kör följande
dotnet test
kommando för att köra enhetstesterna:dotnet test --configuration Release --no-build
Flaggan
--no-build
anger att projektet inte ska skapas innan det körs. Du behöver inte skapa projektet eftersom du skapade det i föregående steg.Du bör se att alla fem testerna godkänns.
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
I det här exemplet tog testerna mindre än en sekund att köra.
Observera att det fanns fem totalt antal tester. Även om vi bara definierade en testmetod
FetchOnlyRequestedGameRegion
körs det testet fem gånger, en gång för varje spelkarta enligt vad som anges i infogadeTestCase
data.Kör testerna en andra gång. Den här gången anger du
--logger
alternativet för att skriva resultatet till en loggfil.dotnet test Tailspin.SpaceGame.Web.Tests --configuration Release --no-build --logger trx
Du ser från utdata att en TRX-fil skapas i katalogen TestResults .
En TRX-fil är ett XML-dokument som innehåller resultatet av en testkörning. Det är ett populärt format för testresultat eftersom Visual Studio och andra verktyg kan hjälpa dig att visualisera resultaten.
Senare ser du hur Azure Pipelines kan hjälpa dig att visualisera och spåra dina testresultat när de körs via pipelinen.
Kommentar
TRX-filer är inte avsedda att ingå i källkontrollen. Med en .gitignore-fil kan du ange vilka temporära filer och andra filer som du vill att Git ska ignorera. Projektets .gitignore-fil har redan konfigurerats för att ignorera allt i katalogen TestResults.
Som ett valfritt steg öppnar du filen DocumentDBRepository_GetItemsAsyncShould.cs i Visual Studio Code från mappen Tailspin.SpaceGame.Web.Tests och undersöker testkoden. Även om du inte är intresserad av att skapa .NET-appar specifikt kan testkoden vara användbar eftersom den liknar kod som du kanske ser i andra enhetstestramverk.
Lägga till uppgifter i pipelinekonfigurationen
Här konfigurerar du bygg-pipelinen för att köra enhetstesterna och samla in resultaten.
Ändra azure-pipelines.yml enligt följande i Visual Studio Code:
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()
Den här versionen introducerar den här
DotNetCoreCLI@2
bygguppgiften.- task: DotNetCoreCLI@2 displayName: 'Run unit tests - $(buildConfiguration)' inputs: command: 'test' arguments: '--no-build --configuration $(buildConfiguration)' publishTestResults: true projects: '**/*.Tests.csproj'
Den här bygguppgiften
dotnet test
kör kommandot .Observera att den här uppgiften inte anger det
--logger trx
argument som du använde när du körde testerna manuellt. ArgumentetpublishTestResults
lägger till det åt dig. Det här argumentet talar om för pipelinen att generera TRX-filen till en tillfällig katalog som är tillgänglig via den$(Agent.TempDirectory)
inbyggda variabeln. Den publicerar också aktivitetsresultatet till pipelinen.Argumentet
projects
anger alla C#-projekt som matchar "**/*. Tests.csproj." Delen "**" matchar alla kataloger och "*. Tests.csproj" -delen matchar alla projekt vars filnamn slutar med ". Tests.csproj." Grenenunit-tests
innehåller bara ett enhetstestprojekt, Tailspin.SpaceGame.Web.Tests.csproj. Genom att ange ett mönster kan du köra fler testprojekt utan att behöva ändra byggkonfigurationen.
Skicka grenen till GitHub
Här skickar du ändringarna till GitHub och ser pipelinekörningen. Kom ihåg att du för närvarande är på grenen unit-tests
.
I den integrerade terminalen lägger du till azure-pipelines.yml i indexet, checkar in ändringarna och push-överför grenen till GitHub.
git add azure-pipelines.yml git commit -m "Run and publish unit tests" git push origin unit-tests
Se hur Azure Pipelines kör testerna
Här ser du testerna som körs i pipelinen och visualiserar sedan resultaten från Microsoft Azure-testplaner. Azure Test Plans innehåller alla verktyg som du behöver för att testa dina program. Du kan skapa och köra manuella testplaner, generera automatiserade tester och samla in feedback från intressenter.
I Azure Pipelines spårar du bygget genom vart och ett av stegen.
Du ser att aktiviteten Kör enhetstester – Versionskörning kör enhetstesterna precis som du gjorde manuellt från kommandoraden.
Gå tillbaka till pipelinesammanfattningen.
Gå till fliken Tester .
Du ser en sammanfattning av testkörningen. Alla fem testerna har godkänts.
I Azure DevOps väljer du Testplaner och sedan Körningar.
Du ser de senaste testkörningarna, inklusive den du precis körde.
Dubbelklicka på den senaste testkörningen.
Du ser en sammanfattning av resultaten.
I det här exemplet har alla fem testerna godkänts. Om några tester misslyckades kan du gå till byggaktiviteten för att få mer information.
Du kan också ladda ned TRX-filen för att undersöka den via Visual Studio eller något annat visualiseringsverktyg.
Även om du bara har lagt till ett test är det en bra början och det åtgärdar det omedelbara problemet. Nu har teamet en plats där de kan lägga till fler tester och köra dem när de förbättrar sin process.
Slå samman grenen till main
Om du är nöjd med resultatet i ett verkligt scenario kan du slå samman grenen unit-tests
till main
, men för korthet hoppar vi över den processen för tillfället.