Cvičení – přidání testů jednotek do vaší aplikace
V této lekci přidáme testy jednotek do automatizovaného sestavení, které jsme vytvořili pomocí Microsoft Azure Pipelines. Regresní chyby se plíží do kódu vašeho týmu a porušují funkce filtrování tabulky výsledků. Konkrétně se opakovaně zobrazuje nesprávný herní režim.
Tento problém znázorňuje následující obrázek. Když uživatel vybere "Milky Way", aby zobrazil pouze skóre z této herní mapy, získá výsledky z jiných herních map, jako je Andromeda.
Tým chce chybu zachytit, než dosáhne testerů. Testování jednotek je skvělý způsob, jak automaticky testovat výskyt chyb regrese.
Přidání testů jednotek v tomto okamžiku v procesu poskytne týmu počáteční začátek, když vylepšuje webovou aplikaci Space Game . Aplikace používá k ukládání nejvyšších skóre a profilů hráčů databázi dokumentů. V tuto chvíli používá místní testovací data. Později plánují připojit aplikaci k živé databázi.
Mnoho architektur testování jednotek je k dispozici pro aplikace jazyka C#. Použijeme NUnit, protože je oblíbená pro komunitu.
Tady je test jednotek, se kterým pracujete:
[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));
}
Tabulku výsledků můžete filtrovat pomocí libovolné kombinace typu hry a herní mapy.
Tento test posílá do tabulky výsledků dotazy na nejlepší výsledky a ověřuje, že každý výsledek odpovídá zadané herní mapě.
U testovací metody nástroje NUnit poskytuje funkce TestCase
vložená data, která se používají k otestování této metody. V této části NUnit volá metodu FetchOnlyRequestedGameRegion
testu jednotek následujícím způsobem:
FetchOnlyRequestedGameRegion("Milky Way");
FetchOnlyRequestedGameRegion("Andromeda");
FetchOnlyRequestedGameRegion("Pinwheel");
FetchOnlyRequestedGameRegion("NGC 1300");
FetchOnlyRequestedGameRegion("Messier 82");
Všimněte si volání kontrolní metody Assert.That
na konci testu. Kontrolní výraz je podmínka nebo příkaz, u kterých deklarujete, že mají hodnotu True. Pokud je výsledkem podmínky hodnota False, může to znamenat chybu ve vašem kódu. NUnit spouští každou testovací metodu pomocí vložených dat, která určíte, a zaznamenává výsledek jako úspěšný nebo neúspěšný test.
Mnoho rozhraní pro testování jednotek poskytuje metody ověřování, které se podobají přirozenému jazyku. Tyto metody usnadňují čtení testů a pomáhají mapovat testy na požadavky aplikace.
Představte si kontrolní výraz provedený v tomto příkladu:
Assert.That(scores, Is.All.Matches<Score>(score => score.GameRegion == gameRegion));
Tento řádek byste mohli číst jako:
Zkontroluj, že herní oblast u každého vráceného skóre odpovídá zadané herní oblasti.
Tady je postup, který chcete provést:
- Načtěte větev z úložiště GitHub, které obsahuje testy jednotek.
- Spusťte testy místně a ověřte, že jsou úspěšné.
- Do konfigurace vašeho kanálu přidejte úlohy, které budou spouštět testy a shromažďovat výsledky.
- Nasdílejte změny větve do vašeho úložiště v GitHubu.
- Sledujte, jak váš projekt v Azure Pipelines automaticky sestavuje aplikaci a spouští testy.
Načtení větve z GitHubu
Tady načtete větev z GitHubu unit-tests
a tuto větev si můžete rezervovat nebo přepnout do této větve.
Tato větev obsahuje projekt Space Game , se kterým jste pracovali v předchozích modulech, a konfiguraci Azure Pipelines, se kterou můžete začít.
V editoru Visual Studio Code otevřete integrovaný terminál.
Spuštěním následujících
git
příkazů načtěte větev pojmenovanouunit-tests
z úložiště Microsoftu a pak přepněte na danou větev.git fetch upstream unit-tests git checkout -B unit-tests upstream/unit-tests
Formát tohoto příkazu umožňuje získat počáteční kód z úložiště Microsoft GitHub, označovaného jako
upstream
. Za chvíli tuto větev nasdílíte do svého úložiště GitHub, označované jakoorigin
.Jako volitelný krok otevřete soubor azure-pipelines.yml v editoru Visual Studio Code a seznamte se s počáteční konfigurací. Tato konfigurace připomíná základní konfiguraci, kterou jste vytvořili v modulu Vytvoření kanálu buildu v Azure Pipelines. Sestavuje pouze konfiguraci aplikace pro vydání.
Spouštění testů místně
Před odesláním jakýchkoli testů do kanálu je vhodné všechny testy spouštět místně. Uděláš to tady.
V editoru Visual Studio Code otevřete integrovaný terminál.
Spuštěním příkazu
dotnet build
sestavte každý projekt v řešení.dotnet build --configuration Release
Spuštěním následujícího
dotnet test
příkazu spusťte testy jednotek:dotnet test --configuration Release --no-build
Příznak
--no-build
určuje, že se projekt nemá sestavovat před spuštěním tohoto příkazu. Projekt nemusíte sestavovat, protože jste ho sestavili v předchozím kroku.Měli byste vidět, že všech pět testů projde.
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
V tomto příkladu se testy spustily méně než jednu sekundu.
Všimněte si, že celkem to bylo pět testů. I když jsme definovali pouze jednu testovací metodu,
FetchOnlyRequestedGameRegion
tento test běží pětkrát, jednou pro každou herní mapu, jak je uvedeno vTestCase
vložených datech.Spusťte testy podruhé. Tentokrát zadejte možnost
--logger
, aby se výsledky zapisovaly do souboru protokolu.dotnet test Tailspin.SpaceGame.Web.Tests --configuration Release --no-build --logger trx
Z výstupu vidíte, že se v adresáři TestResults vytvoří soubor TRX.
Soubor TRX je dokument ve formátu XML, který obsahuje výsledky spuštění testů. Je to oblíbený formát výsledků testů, protože Visual Studio a další nástroje vám můžou pomoct vizualizovat výsledky.
Později se dozvíte, jak vám azure Pipelines může pomoct vizualizovat a sledovat výsledky testů při jejich procházení kanálem.
Poznámka:
Soubory TRX nejsou určené k zahrnutí do správy zdrojového kódu. Soubor .gitignore umožňuje určit, které dočasné a další soubory má Git ignorovat. Soubor .gitignore v našem projektu je už nastavený tak, aby ignoroval všechno v adresáři TestResults.
Jako volitelný krok otevřete v editoru Visual Studio Code soubor DocumentDBRepository_GetItemsAsyncShould.cs ze složky Tailspin.SpaceGame.Web.Tests a prozkoumejte testovací kód. I když vás konkrétně nezajímá sestavování aplikací .NET, může být testovací kód užitečný, protože se podobá kódu, který se může zobrazit v jiných architekturách testování jednotek.
Přidání úloh do konfigurace kanálu
V této části nakonfigurujete kanál buildu tak, aby spouštěl testy jednotek a shromáždí výsledky.
V editoru Visual Studio Code upravte azure-pipelines.yml následujícím způsobem:
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()
Tato verze zavádí úlohu sestavení
DotNetCoreCLI@2
.- task: DotNetCoreCLI@2 displayName: 'Run unit tests - $(buildConfiguration)' inputs: command: 'test' arguments: '--no-build --configuration $(buildConfiguration)' publishTestResults: true projects: '**/*.Tests.csproj'
Tato úloha sestavení spouští příkaz
dotnet test
.Všimněte si, že tento úkol neurčuje
--logger trx
argument, který jste použili při ručním spuštění testů. ArgumentpublishTestResults
to přidá za vás. Tento argument dává kanálu pokyn, aby generoval soubor TRX v dočasném adresáři, který bude přístupný prostřednictvím integrované proměnné$(Agent.TempDirectory)
. Publikuje také výsledky úlohy do kanálu.Argument
projects
určuje všechny projekty jazyka C#, které odpovídají **/*. Tests.csproj." Část ** odpovídá všem adresářům a *. Část Tests.csproj odpovídá všem projektům, jejichž název souboru končí na ". Tests.csproj." Větevunit-tests
obsahuje pouze jeden projekt testování jednotek, Tailspin.SpaceGame.Web.Tests.csproj. Zadáním vzoru můžete spouštět více testovacích projektů bez nutnosti upravovat konfiguraci sestavení.
Nasdílení větve do GitHubu
Tady nasdílíte změny do GitHubu a zobrazí se spuštění kanálu. Připomínáme, že se nacházíte ve větvi unit-tests
.
V integrovaném terminálu přidejte do indexu azure-pipelines.yml , potvrďte změny a nasdílejte větev do GitHubu.
git add azure-pipelines.yml git commit -m "Run and publish unit tests" git push origin unit-tests
Sledování spouštění testů v Azure Pipelines
Tady uvidíte spuštění testů v kanálu a pak vizualizovat výsledky z testovacích plánů Microsoft Azure. Řešení Azure Test Plans poskytuje všechny nástroje, které potřebujete k úspěšnému testování aplikací. Můžete vytvářet a spouštět ruční testovací plány, generovat automatizované testy a shromažďovat zpětnou vazbu od zúčastněných stran.
V Azure Pipelines trasujte sestavení jednotlivými kroky.
Uvidíte, že úloha Run unit tests - Release (Spuštění testů jednotek – vydání) spustí testy jednotek stejně, jako jste to udělali manuálně vy z příkazového řádku.
Přejděte zpět na souhrn kanálu.
Přesuňte se na kartu Tests (Testy).
Zobrazí se vám souhrn spuštění testů. Všech pět testů bylo úspěšných.
V Azure DevOps vyberte Testovací plány a pak vyberte Spustit.
Zobrazí se vám několik posledních spuštění testů včetně testů, které jste právě spustili.
Poklikejte na poslední testovací běh.
Zobrazí se vám souhrn výsledků.
V tomto příkladu bylo všech pět testů úspěšných. Pokud nějaké testy selhaly, můžete přejít na úlohu sestavení a získat další podrobnosti.
Můžete si také stáhnout soubor TRX a prozkoumat ho prostřednictvím sady Visual Studio nebo jiného nástroje pro vizualizaci.
I když jste přidali jenom jeden test, je to dobrý začátek a opraví okamžitý problém. Teď mají členové týmu místo pro přidávání a spouštění dalších testů tak, jak zlepšují svůj proces.
Sloučení větve do hlavní větve
Pokud jste byli s výsledky spokojení, můžete v reálném scénáři sloučit unit-tests
větev do main
, ale kvůli stručnosti tento proces prozatím přeskočíme.