Gyakorlat – Egységtesztek hozzáadása az alkalmazáshoz

Befejeződött

Ebben a leckében egységteszteket adunk hozzá a Microsoft Azure Pipelines használatával létrehozott automatizált buildhez. A regressziós hibák belekúsznak a csapat kódjába, és feltörik a ranglista szűrési funkcióját. Egészen pontosan nem a megfelelő játékmód jelenik meg.

Az alábbi képen a probléma látható. Amikor egy felhasználó a "Tejút" lehetőséget választja, hogy csak a játéktérképen szereplő pontszámokat jelenítsen meg, más játéktérképekről, például Andromeda-ból kap eredményeket.

A screenshot of the leaderboard showing incorrect results: Andromeda galaxy scores show in the Milky Way galaxy listing.

A csapat szeretné elkapni a hibát, mielőtt elérené a tesztelőket. Az egységtesztek kiválóan használhatóak a regressziós hibák automatikus teszteléssel való kiszűrésére.

Ha hozzáadja az egységteszteket ezen a ponton a folyamat során, akkor a csapat elsőként kezdheti meg a Space Game webalkalmazás továbbfejlesztését. Az alkalmazás egy dokumentum-adatbázis használatával tárolja a pontszámokat és a játékosok profilját. Jelenleg helyi tesztelési adatokat használ. A későbbiekben az alkalmazást egy élő adatbázishoz tervezik csatlakoztatni.

C#-alkalmazásokhoz számos egységtesztelési keretrendszer érhető el. Az NUnitot azért fogjuk használni, mert népszerű a közösség körében.

A következő egységteszttel dolgozik:

[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));
}

A ranglistán a játéktípus és a játéktérkép bármely kombinációjával végezhető szűrés.

A teszt lekérdezi a pontszámokat a ranglistán, majd ellenőrzi, hogy az eredmények megegyeznek-e a megadott térképpel.

Az NUnit tesztelési módszerében a TestCase használatával beágyazott adatok biztosíthatók a metódus teszteléséhez. Itt az NUnit az FetchOnlyRequestedGameRegion egységtesztelési módszert hívja meg az alábbiak szerint:

FetchOnlyRequestedGameRegion("Milky Way");
FetchOnlyRequestedGameRegion("Andromeda");
FetchOnlyRequestedGameRegion("Pinwheel");
FetchOnlyRequestedGameRegion("NGC 1300");
FetchOnlyRequestedGameRegion("Messier 82");

Figyelje meg az Assert.That metódus meghívását a teszt végén. A helyességi feltétel egy olyan feltétel vagy utasítás, amelyet igazként határoz meg. Ha a feltétel hamisnak bizonyul, az a kód hibáját jelezheti. Az NUnit minden tesztmetódust a megadott beágyazott adatok alapján futtat, az eredményeket pedig sikeres vagy sikertelen tesztként rögzíti.

Számos egységtesztelési keretrendszerben van lehetőség olyan ellenőrző módszerek használatára, amelyek a természetes nyelvhez hasonlóak. Ezek a módszerek megkönnyítik a tesztek olvasását, és segítenek a teszteknek az alkalmazás követelményeinek megfeleltetésében.

Vegye figyelembe az ebben a példában ismertetett állítást:

Assert.That(scores, Is.All.Matches<Score>(score => score.GameRegion == gameRegion));

A sort a következő módon olvashatja:

Érvényesítse, hogy a visszaadott pontszámok játékrégiója megegyezik a megadott játékrégióval.

A következő folyamatot kell követni:

  1. Lekér egy ágat az egységteszteket tartalmazó GitHub-adattárból.
  2. Futtassa helyileg a teszteket, és ellenőrizze, hogy sikeresek-e.
  3. Adjon feladatokat a folyamatkonfigurációhoz a tesztek futtatásához, majd ellenőrizze az eredményeket.
  4. Töltse fel az ágat a GitHub-adattárba.
  5. Figyelje meg, ahogy az Azure Pipelines projekt automatikusan buildeli az alkalmazást, és futtatja a teszteket.

Az ág lehívása a GitHubról

Itt lekéri az ágat a unit-tests GitHubról, és kiveheti vagy átválthat erre az ágra.

Ez az ág tartalmazza azt a Space Game-projektet , amellyel az előző modulokban dolgozott, és egy Azure Pipelines-konfigurációt, amellyel kezdeni kell.

  1. Nyissa meg az integrált terminált a Visual Studio Code-ban.

  2. Futtassa az alábbi git parancsokat a Microsoft-adattárból elnevezett unit-tests ág lekéréséhez, majd váltson erre az ágra.

    git fetch upstream unit-tests
    git checkout -B unit-tests upstream/unit-tests
    

    A parancs formátuma lehetővé teszi kezdőkód lekérését a Microsoft GitHub-adattárból, más néven upstream. Rövidesen leküldi ezt az ágat a GitHub-adattárba, más néven origin.

  3. Választható lépésként nyissa meg az azure-pipelines.yml fájlt a Visual Studio Code-ban, és ismerkedjen meg a kezdeti konfigurációval. Ez a konfiguráció a Buildelési folyamat létrehozása az Azure Pipelines használatával című modulban létrehozott egyszerű konfigurációra emlékeztet. Kizárólag az alkalmazás Kiadás konfigurációját buildeli.

A tesztek helyi futtatása

Célszerű a teszteket helyileg futtatni, mielőtt beküldené őket a folyamatba. Ezt itt fogja elvégezni.

  1. Nyissa meg az integrált terminált a Visual Studio Code-ban.

  2. Futtassa a dotnet build parancsot a megoldás összes projektjének buildeléséhez.

    dotnet build --configuration Release
    
  3. Futtassa a következő dotnet test parancsot az egységtesztek futtatásához:

    dotnet test --configuration Release --no-build
    

    A --no-build jelző határozza meg, hogy a projekt nem buildelhető a futtatása előtt. Nem szükséges buildelnie a projektet, hiszen ezt az előző lépésben már megtette.

    Látnia kell, hogy mind az öt teszt sikeres.

    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
    

    Ebben a példában a tesztek futtatása kevesebb mint egy másodpercet vett igénybe.

    Vegye figyelembe, hogy összesen öt teszt ment végbe. Bár csak egy tesztmetódust határoztunk meg, FetchOnlyRequestedGameRegionezt a tesztet ötször futtatjuk, egyszer minden egyes játéktérképhez, a TestCase beágyazott adatokban megadott módon.

  4. Futtassa a teszteket még egyszer. Ezúttal adja meg a --logger kapcsolót az eredmények naplófájlba történő írásához.

    dotnet test Tailspin.SpaceGame.Web.Tests --configuration Release --no-build --logger trx
    

    A kimenetből látható, hogy egy TRX-fájl jön létre a TestResults könyvtárban.

    A TRX-fájlok olyan XML-dokumentumok, amelyek egy teszt eredményeit tartalmazzák. Ez egy népszerű formátum a teszteredményekhez, mivel a Visual Studio és más eszközök segíthetnek az eredmények vizualizációjában.

    Később látni fogja, hogyan segíthet az Azure Pipelines a teszteredmények vizualizációjában és nyomon követésében a folyamat során.

    Megjegyzés:

    A TRX-fájloknak nem kell szerepelniük a verziókövetésben. A .gitignore fájlokkal megadhatja, hogy mely ideiglenes és egyéb fájlokat hagyja figyelmen kívül a Git. A projekt .gitignore fájlja már be van állítva a TestResults (Teszteredmények) könyvtár tartalmának figyelmen kívül hagyására.

  5. Opcionális lépésként a Visual Studio Code-ban nyissa meg a DocumentDBRepository_GetItemsAsyncShould.cs fájlt a Tailspin.SpaceGame.Web.Tests mappából, és vizsgálja meg a tesztkódot. Még ha nem is szeretne kifejezetten .NET-alkalmazásokat létrehozni, hasznosnak találhatja a tesztkódot, mert hasonlít más egységteszt-keretrendszerekben látható kódra.

Feladatok hozzáadása a folyamat konfigurációjához

Itt konfigurálja a buildelési folyamatot az egységtesztek futtatásához és az eredmények gyűjtéséhez.

  1. A Visual Studio Code-ban módosítsa az azure-pipelines.yml-t az alábbiak szerint:

    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()
    

    Ez a verzió bevezeti ezt a DotNetCoreCLI@2 buildfeladatot.

    - task: DotNetCoreCLI@2
      displayName: 'Run unit tests - $(buildConfiguration)'
      inputs:
        command: 'test'
        arguments: '--no-build --configuration $(buildConfiguration)'
        publishTestResults: true
        projects: '**/*.Tests.csproj'
    

    A buildfeladat a dotnet test parancsot futtatja.

    Figyelje meg, hogy ez a feladat nem adja meg azt az --logger trx argumentumot, amelyet a tesztek manuális futtatásakor használt. Ezt a publishTestResults argumentum fogja hozzáadni. Az argumentum utasítást ad a folyamat számára, hogy a TRX-fájlt egy ideiglenes könyvtárban hozza létre, amely a $(Agent.TempDirectory) beépített változón keresztül érhető el. Ezen kívül közzéteszi a feladat eredményeit a folyamatban.

    Az projects argumentum minden olyan C#-projektet megad, amely megfelel a "**/*" értéknek . Tests.csproj." A "**" rész megfelel az összes könyvtárnak és a "*"-nak. A Tests.csproj rész megegyezik az összes olyan projekttel , amelynek a fájlneve ". Tests.csproj." Az unit-tests ág csak egy egység tesztelési projektet tartalmaz, a Tailspin.SpaceGame.Web.Tests.csproj fájlt. Egy minta megadásával több tesztprojektet is futtathat anélkül, hogy módosítania kellene a buildkonfigurációt.

Az ág leküldése a GitHubra

Itt leküldheti a módosításokat a GitHubra, és láthatja a folyamat futtatását. Ne feledje, hogy jelenleg a unit-tests ágban van.

  1. Az integrált terminálban adja hozzá az azure-pipelines.yml értéket az indexhez, véglegesítse a módosításokat, és küldje el az ágat a GitHubra.

    git add azure-pipelines.yml
    git commit -m "Run and publish unit tests"
    git push origin unit-tests
    

A tesztek végigkövetése az Azure Pipelinesban

Itt láthatja, hogy a tesztek a folyamatban futnak, majd megjelenítik a Microsoft Azure Test Plans eredményeit. Az Azure Test Plans minden eszközt biztosít, amelyre szüksége lehet az alkalmazások sikeres teszteléséhez. Létrehozhat és futtathat manuális tesztterveket, automatikus teszteket hozhat létre, és visszajelzést gyűjthet az érdekelt felektől.

  1. Az Azure Pipelinesban kövesse nyomon a buildet az egyes lépésekben.

    Láthatja, hogy a Run unit tests - Release (Egységtesztek futtatása – Kiadás) feladat futtatja az egységteszteket, ahogy azt korábban Ön tette manuálisan a parancssorból.

    A screenshot of Azure Pipelines showing console output from running unit tests.

  2. Lépjen vissza a folyamat összegzéséhez.

  3. Lépjen a Tests (Tesztek) lapra.

    Itt láthatja a teszt futtatásának összegzését. Mind az öt teszt sikeres volt.

    A screenshot of Azure Pipelines showing the Tests tab with 5 total tests run and 100 percent passing.

  4. Az Azure DevOpsban válassza a Tesztcsomagok, majd a Futtatások lehetőséget.

    A screenshot of Azure DevOps navigation menu with Test Plans section and Runs tab highlighted.

    Megjelennek a legutóbb futtatott tesztek, beleértve azt is, amelyet az imént futtatott.

  5. Kattintson duplán a legutóbbi tesztfuttatásra.

    Itt láthatja az eredmények összegzését.

    A screenshot of Azure DevOps test run results summary showing 5 passed tests.

    Ebben a példában mind az öt teszt sikeres volt. Ha a tesztek sikertelenek, a buildelési feladatra léphet további részletekért.

    A TRX-fájlt a Visual Studióval vagy más vizualizációs eszközzel is megvizsgálhatja.

Bár csak egy tesztet adott hozzá, ez jó kezdet, és megoldja az azonnali problémát. Így a csapat már tudja, hol lehet további teszteket hozzáadni és futtatni a folyamat fejlesztése során.

Az ág egyesítése a főágba

Egy valós forgatókönyvben, ha elégedett az eredménnyel, egyesítheti az unit-tests ágat main, de a rövidség kedvéért egyelőre kihagyjuk ezt a folyamatot.