Gyakorlat – sikertelen teszt javítása

Befejeződött

Ezen a ponton már rendelkezésére áll egy módszer, amellyel egységteszteket futtathat, miközben a módosítások végighaladnak a buildfolyamaton. Továbbá azt is mérheti, hogy a tesztek a kód mekkora részét fedik le.

Mindig célszerű helyben teszteket futtatni, mielőtt a módosításokat beküldené a folyamatba. Mi történik azonban, ha ezt valaki elfelejti, és egy olyan módosítást küld be, amely megakadályozza a build helyes működését?

Ebben a leckében egy hibás egységteszt által okozott hibás buildet fog kijavítani. Ebben a szakaszban a következőket hajtja végre:

  • Kezdőkód lekérése a GitHubról.
  • Kódlefedettségi eszközök hozzáadása a projekthez.
  • A kód feltöltése a saját adattárba.
  • A folyamat automatikus futásának figyelése, és a sikertelen egységtesztek észrevétele.
  • A hiba reprodukálása helyben.
  • A hiba kielemzése és javítása.
  • A javítás feltöltése, és a build sikeres futásának figyelése.

Az új egységteszt áttekintése

A csapat legújabb funkciója magában foglalja a ranglistát. Le kell kérnünk a pontszámok számát az adatbázisból, hogy megírhassunk egy egységtesztet a IDocumentDBRepository<T>.GetItemsAsync módszer ellenőrzéséhez.

A teszt így néz ki. Még nem kell kódot hozzáadnia.

[TestCase(0, ExpectedResult=0)]
[TestCase(1, ExpectedResult=1)]
[TestCase(10, ExpectedResult=10)]
public int ReturnRequestedCount(int count)
{
    const int PAGE = 0; // take the first page of results

    // Fetch the scores.
    Task<IEnumerable<Score>> scoresTask = _scoreRepository.GetItemsAsync(
        score => true, // return all scores
        score => 1, // we don't care about the order
        PAGE,
        count // fetch this number of results
    );
    IEnumerable<Score> scores = scoresTask.Result;

    // Verify that we received the specified number of items.
    return scores.Count();
}

Ne feledjük, hogy az NUnit-tesztekben a TestCase használatával beágyazott adatok biztosíthatók a metódus teszteléséhez. Az NUnit a következőképpen hívja meg a ReturnRequestedCount egységtesztet:

ReturnRequestedCount(0);
ReturnRequestedCount(1);
ReturnRequestedCount(10);

Ez a teszt az ExpectedResult tulajdonság használatával leegyszerűsíti a tesztkódot, és segít nyilvánvalóvá tenni a célját. Az NUnit automatikusan összeveti a visszaadott értéket a tulajdonság értékével, így nem szükséges explicit módon meghívni a helyességi feltételt.

Kiválasztunk néhány értéket, amelyek a tipikus lekérdezéseket jelölik. A 0-t is belefoglaljuk a peremes eset lefedéséhez.

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

Ahogy korábban is tette, kérje le az ágat a failed-test GitHubról, és vegye ki (vagy váltson rá) az ágra.

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

  2. Futtassa az alábbi git fetch parancsokat git checkout a Microsoft-adattárból elnevezett failed-test ág letöltéséhez és az ágra való váltáshoz:

    git fetch upstream failed-test
    git checkout -B failed-test upstream/failed-test
    

    Az ágat failed-test tanulási célokra neveztük el. A gyakorlatban egy ágat a rendeltetése vagy funkciója után nevezne el.

  3. Az alábbi parancsok futtatásával hozzon létre egy helyi eszközjegyzékfájlt, telepítse az ReportGenerator eszközt, és adja hozzá a csomagot a coverlet.msbuild tesztprojekthez:

    dotnet new tool-manifest
    dotnet tool install dotnet-reportgenerator-globaltool
    dotnet add Tailspin.SpaceGame.Web.Tests package coverlet.msbuild
    

    Erre a lépésre azért van szükség, mert az failed-test ág nem tartalmazza az ághoz unit-tests hozzáadott munkát.

  4. Adja hozzá a tesztprojektfájlt és az eszközjegyzékfájlt az előkészítési indexhez, és véglegesítse a módosításokat.

    git add Tailspin.SpaceGame.Web.Tests/Tailspin.SpaceGame.Web.Tests.csproj
    git add .config/dotnet-tools.json
    git commit -m "Configure code coverage tests"
    
  5. Futtassa a következő git push parancsot az failed-test ág GitHub-adattárba való feltöltéséhez:

    git push origin failed-test
    

A sikertelen teszt megtekintése a folyamatban

Tegyük fel, hogy sietett, és nem futtatta le a teszteket egy utolsó alkalommal. Szerencsére a folyamat segíthet a problémák korai észlelésében, amikor egységtesztek vannak. Ezt itt láthatja.

  1. Az Azure Pipelinesban nyomon követheti a buildet, miközben végigfut a folyamaton.

  2. Bontsa ki a Run unit tests - Release (Egységtesztek futtatása – kiadás) feladatot, miközben fut.

    Láthatja, hogy a ReturnRequestedCount tesztmetódus sikertelenül zárul.

    A screenshot of Azure Pipelines dashboard showing output log of an assertion failure on the unit test, expecting 10 but was 9.

    A teszt akkor halad át, ha a bemeneti érték 0, de sikertelen, ha a bemeneti érték 1 vagy 10.

    A build csak akkor lesz közzétéve a folyamatban, ha az előző feladat sikeresen zárul. Itt a build nem lett közzétéve, mert az egységtesztek sikertelenek. Így mások véletlenül nem férhetnek hozzá a hibás buildhez.

A gyakorlatban akkor nem mindig manuálisan követjük a buildet annak futtatása során. Az alábbiakban néhány módszert találhat a hiba felderítésére:

  • E-mailes értesítés az Azure DevOpstól

    Az Azure DevOps konfigurálható úgy, hogy a build befejezésekor e-mail-értesítést küldjön Önnek. Ha a build sikertelen, a tárgysor a „[Build failed]” (Build sikertelen) kifejezéssel kezdődik.

    A screenshot of a portion of a build failed email notification.

  • Azure-tesztcsomagok

    Az Azure DevOpsban válassza a Tesztcsomagok, majd a Futtatások lehetőséget. Megjelennek a legutóbb futtatott tesztek, beleértve az imént futtatottat. Válassza a legutóbbi tesztet. Láthatja, hogy a nyolc teszt közül kettő sikertelen volt.

    A screenshot of Azure DevOps test run outcome showing two of eight failed tests as a ring chart.

  • Az irányítópult

    Az Azure DevOpsban válassza az Áttekintés, majd az Irányítópultok lehetőséget. A hiba megjelenik a Test Results Trend (Teszteredmények trendje) vezérlőn. A Kódlefedettség widget üres, ami azt jelzi, hogy a kódlefedettség nem futott.

    A screenshot of Azure DevOps dashboard trend chart widget showing two failed test in the last test run.

  • A buildjelvény

    Bár az failed-test ág nem tartalmazza a buildjelvényt a README.md fájlban, a GitHubon a build meghiúsulása esetén a következőt fogja látni:

    A screenshot of Azure Pipelines build badge on GitHub indicating a failure.

A hibás teszt elemzése

Ha az egységtesztek sikertelenek, általában két lehetőség közül választhat a hiba jellegétől függően:

  • Ha a teszt hibát mutat a kódban, javítsa ki a kódot, és futtassa újra a teszteket.
  • Ha a funkció megváltozik, módosítsa a tesztet az új követelményeknek megfelelően.

A hiba reprodukálása helyben

Ebben a szakaszban helyben fogja reprodukálni a hibát.

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

  2. A terminálban futtassa ezt a dotnet build parancsot az alkalmazás létrehozásához:

    dotnet build --configuration Release
    
  3. A terminálban futtassa ezt a dotnet test parancsot az egységtesztek futtatásához:

    dotnet test --no-build --configuration Release
    

    Ugyanazokat a hibákat kell látnia, mint a folyamatban. A kimenet íme egy része:

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
      Failed ReturnRequestedCount(1) [33 ms]
      Error Message:
         Expected: 1
      But was:  0
    
      Stack Trace:
         at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
       at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
       at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
    
      Failed ReturnRequestedCount(10) [1 ms]
      Error Message:
         Expected: 10
      But was:  9
    
      Stack Trace:
         at NUnit.Framework.Internal.Commands.TestMethodCommand.Execute(TestExecutionContext context)
       at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__0()
       at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
    
    
    Failed!  - Failed:     2, Passed:     6, Skipped:     0, Total:     8, Duration: 98 ms
    

A hiba okának megkeresése

Megfigyelheti, hogy minden sikertelen teszt egy olyan eredményt hoz létre, amely egyenként ki van kapcsolva. Például ha a várt érték 10, a teszt 9-et ad vissza.

Tekintse meg a tesztelt LocalDocumentDBRepository<T>.GetItemsAsyncmetódus forráskódját. A következőt kell látnia:

public Task<IEnumerable<T>> GetItemsAsync(
    Func<T, bool> queryPredicate,
    Func<T, int> orderDescendingPredicate,
    int page = 1, int pageSize = 10
)
{
    var result = _items
        .Where(queryPredicate) // filter
        .OrderByDescending(orderDescendingPredicate) // sort
        .Skip(page * pageSize) // find page
        .Take(pageSize - 1); // take items

    return Task<IEnumerable<T>>.FromResult(result);
}

Ebben a forgatókönyvben ellenőrizheti a GitHubot, hogy a fájl nemrég módosult-e.

A screenshot of GitHub showing a file diff where a minus one operation was added.

Azt gyanítja, hogy pageSize - 1 eggyel kevesebb eredményt ad vissza, és hogy ez csak pageSize. A mi esetünkben ez a hiba akkor történt, amikor tesztelés nélkül leküldte a munkát, de valós forgatókönyv esetén a gitHubon a fájlt módosító fejlesztővel is ellenőrizheti a módosítás okát.

Tipp.

A beszélgetés és az együttműködés a Githubon is folyhat. Megjegyzéseket fűzhet a lekéréses kérelmekhez, vagy nyithat egy hibajegyet.

A hiba javítása

Ebben a szakaszban a hiba kijavításához módosítsa a kódot az eredeti állapotára, és futtassa a teszteket a javítás ellenőrzéséhez.

  1. A Visual Studio Code-ban nyissa meg a Tailspin.SpaceGame.Web/LocalDocumentDBRepository.cs fájlt a fájlkezelőből.

  2. Módosítsa a metódust az GetItemsAsync itt látható módon:

    public Task<IEnumerable<T>> GetItemsAsync(
        Func<T, bool> queryPredicate,
        Func<T, int> orderDescendingPredicate,
        int page = 1, int pageSize = 10
    )
    {
        var result = _items
            .Where(queryPredicate) // filter
            .OrderByDescending(orderDescendingPredicate) // sort
            .Skip(page * pageSize) // find page
            .Take(pageSize); // take items
    
        return Task<IEnumerable<T>>.FromResult(result);
    }
    

    Ebben a verzióban a pageSize - 1 helyett pageSize áll.

  3. Mentse a fájlt.

  4. Az integrált terminálban hozza létre az alkalmazást.

    dotnet build --configuration Release
    

    Látnia kell, hogy a build sikeres.

    A gyakorlatban futtathatja az alkalmazást, és röviden kipróbálhatja. Tanulási célokból ezt egyelőre kihagyjuk.

  5. A terminálban futtassa az egységteszteket.

    dotnet test --no-build --configuration Release
    

    Láthatja, hogy a tesztek sikeresek.

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
    
    Passed!  - Failed:     0, Passed:     8, Skipped:     0, Total:     8, Duration: 69 ms
    
  6. Az integrált terminálban adja hozzá az összes módosított fájlt az indexhez, véglegesítse a módosításokat, és küldje el az ágat a GitHubra.

    git add .
    git commit -m "Return correct number of items"
    git push origin failed-test
    

    Tipp.

    Ebben a példában a git add pont (.) egy helyettesítő karakter. Ez az összes előkészítetlen fájlt kijelöli az aktuális könyvtárban és annak minden alkönyvtárában.

    Mielőtt ezt a helyettesítő karaktert használna, érdemes a véglegesítés előtt futtatni git status , hogy meggyőződjön arról, hogy előkészítette a megrendezendő fájlokat.

  7. Térjen vissza az Azure Pipelinesra. Figyelje meg, ahogy a módosítás végigfut a folyamaton. A tesztek sikeresek, és az általános build sikeres lesz.

    Ha szeretné ellenőrizni a teszteredményeket, a build befejezésekor a Tesztek és a Kódlefedettség füleket is kiválaszthatja.

    A frissített eredmények trendjének megtekintéséhez az irányítópultot is megtekintheti.

    A screenshot of Azure DevOps dashboard trend chart widget showing a return to all tests passing.

Great! Kijavította a buildet. Ezután megtudhatja, hogyan tisztíthatja meg az Azure DevOps-környezetet.