Alıştırma - Başarısız bir testi düzeltme

Tamamlandı

Bu noktada, değişiklikler derleme işlem hattında ilerledikçe birim testlerini çalıştırmanın bir yolunuz vardır. Ayrıca testlerinizin kapsadığı kod miktarını ölçmenin bir yolu da vardır.

İşlem hattında değişiklik göndermeden önce testlerinizi yerel olarak çalıştırmak her zaman iyi bir fikirdir. Ancak birisi derlemeyi bozan bir değişikliği unutup gönderdiğinde ne olur?

Bu ünitede, başarısız birim testinin neden olduğu bozuk bir derlemeyi düzelteceksiniz. Burada şunları yapacaksınız:

  • GitHub'dan başlangıç kodunu alın.
  • Projenize kod kapsamı araçları ekleyin.
  • Kodu deponuza gönderin.
  • İşlem hattının otomatik olarak çalışmasını ve birim testlerinin başarısız olduğunu izleyin.
  • Hatayı yerel olarak yeniden oluşturun.
  • Hatayı analiz edin ve düzeltin.
  • Bir düzeltme göndererek derlemenin başarılı olduğunu izleyin.

Yeni birim testini gözden geçirme

Ekibin en son özelliği puan tablosunu içerir. Yöntemi doğrulamak için birim testi yazabilmek için veritabanından IDocumentDBRepository<T>.GetItemsAsync puan sayısını almalıyız.

Test şu şekilde görünür. Henüz herhangi bir kod eklemeniz gerekmez.

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

Bir NUnit testinde, TestCase bu yöntemi test etmek için kullanılacak satır içi veriler sağladığını hatırlayın. NUnit birim test yöntemini şu şekilde çağırır ReturnRequestedCount :

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

Bu test ayrıca test kodunu basitleştirmek ve amacını ExpectedResult netleştirmeye yardımcı olmak için özelliğini kullanır. NUnit, dönüş değerini bu özelliğin değeriyle otomatik olarak karşılaştırır ve onaylama işlemini açıkça çağırma gereksinimini ortadan kaldırır.

Tipik sorguları temsil eden birkaç değer seçeceğiz. Ayrıca bu uç olayı kapsayacak şekilde 0 ekleyeceğiz.

GitHub'dan dalı getirme

Daha önce yaptığınız gibi GitHub'dan dalı getirin failed-test ve bu dala göz atın (veya geçiş yapın).

  1. Visual Studio Code'da tümleşik terminali açın.

  2. Microsoft deposundan adlı failed-test bir dalı indirmek ve bu dala geçmek için aşağıdaki git fetch ve git checkout komutlarını çalıştırın:

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

    Bu dalı failed-test öğrenme amacıyla adlandırdık. Uygulamada, bir dalı amacının veya özelliğinin adını alırsınız.

  3. Yerel bir araç bildirim dosyası oluşturmak, aracı yüklemek ReportGenerator ve paketi test projenize eklemek coverlet.msbuild için şu komutları çalıştırın:

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

    Dal, failed-test dala eklediğiniz çalışmayı içermediğinden bu adıma unit-tests ihtiyacınız vardır.

  4. Test projesi dosyanızı ve araç bildirim dosyanızı hazırlama dizinine ekleyin ve değişikliklerinizi işleyin.

    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. Dalını GitHub deponuza yüklemek failed-test için aşağıdaki git push komutu çalıştırın:

    git push origin failed-test
    

İşlem hattında test hatasına bakın

Acelen olduğunu ve testleri son bir kez çalıştırmadan işini hızlandırdığını düşünelim. Neyse ki işlem hattı, birim testleri olduğunda sorunları erken yakalamanıza yardımcı olabilir. Bunu burada görebilirsiniz.

  1. Azure Pipelines'da, işlem hattında çalışırken derlemeyi takip edin.

  2. Birim testlerini çalıştır - Yayın görevini çalışırken genişletin.

    Test yönteminin ReturnRequestedCount başarısız olduğunu görürsünüz.

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

    Test, giriş değeri 0 olduğunda geçer, ancak giriş değeri 1 veya 10 olduğunda başarısız olur.

    Derleme yalnızca önceki görev başarılı olduğunda işlem hattında yayımlanır. Burada, birim testleri başarısız olduğundan derleme yayımlanmadı. Bu, başkalarının yanlışlıkla bozuk bir derleme almasını önler.

Uygulamada, çalıştırılırken derlemeyi her zaman el ile izlemezsiniz. Hatayı bulmanın birkaç yolu şunlardır:

  • Azure DevOps'tan e-posta bildirimi

    Derleme tamamlandığında size e-posta bildirimi göndermek için Azure DevOps'yi yapılandırabilirsiniz. Derleme başarısız olduğunda konu satırı "[Derleme başarısız oldu]" ile başlar.

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

  • Azure Test Planları

    Azure DevOps'ta Test Planları'nın ardından Çalıştırmalar'ı seçin. Yeni çalıştırdığınız test çalıştırmaları da dahil olmak üzere son test çalıştırmalarını görürsünüz. En son tamamlanan testi seçin. Sekiz testin ikisinin başarısız olduğunu görüyorsunuz.

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

  • Pano

    Azure DevOps'ta Genel Bakış'ı ve ardından Panolar'ı seçin. Hatanın Test Sonuçları Eğilimi pencere öğesinde gösterildiğini görürsünüz. Kod Kapsamı pencere öğesi boş, bu da kod kapsamının çalışmadığını gösterir.

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

  • Derleme rozeti

    Dal, failed-test README.md dosyasında derleme rozetini içermese de, derleme başarısız olduğunda GitHub'da şunları görürsünüz:

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

Test hatasını analiz etme

Birim testleri başarısız olduğunda, normalde hatanın niteliğine bağlı olarak iki seçeneğiniz olur:

  • Test kodda bir hata gösterirse kodu düzeltin ve testleri yeniden çalıştırın.
  • İşlevler değişirse testi yeni gereksinimlere uyacak şekilde ayarlayın.

Hatayı yerel olarak yeniden oluşturma

Bu bölümde, hatayı yerel olarak yeniden oluşturacaksınız.

  1. Visual Studio Code'da tümleşik terminali açın.

  2. Uygulamayı derlemek için terminalde şu dotnet build komutu çalıştırın:

    dotnet build --configuration Release
    
  3. Terminalde şu dotnet test komutu çalıştırarak birim testlerini çalıştırın:

    dotnet test --no-build --configuration Release
    

    İşlem hattında gördüğünüz hataların aynısını görmeniz gerekir. Çıktının bir bölümü aşağıdadır:

    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
    

Hatanın nedenini bulma

Başarısız olan her testin birer birer kapalı bir sonuç ürettiğini fark edeceksiniz. Örneğin, 10 beklendiğinde test 9 döndürür.

Test LocalDocumentDBRepository<T>.GetItemsAsyncedilen yöntemin kaynak koduna göz atın. Şunu görmeniz gerekir:

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

Bu senaryoda, dosyanın yakın zamanda değiştirilip değiştirilmediğini görmek için GitHub'a bakabilirsiniz.

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

Bir daha az sonuç döndürdüğünü pageSize - 1 ve bunun yalnızca pageSizeolması gerektiğini düşünüyorsanız. Bizim senaryomuzda bu, işi test etmeden gönderdiğinizde yaptığınız bir hatadır, ancak gerçek bir senaryoda, değişikliğin nedenini belirlemek için GitHub'da dosyayı değiştiren geliştiriciye danışın.

Bahşiş

Tartışma ve işbirliği GitHub'da da gerçekleşebilir. Çekme isteğine açıklama ekleyebilir veya bir sorun açabilirsiniz.

Hatayı düzeltme

Bu bölümde, kodu özgün durumuna döndürerek ve düzeltmeyi doğrulamak için testleri çalıştırarak hatayı düzelteceksiniz.

  1. Visual Studio Code'da, dosya gezgininden Tailspin.SpaceGame.Web/LocalDocumentDBRepository.cs dosyasını açın.

  2. GetItemsAsync Yöntemini burada gösterildiği gibi değiştirin:

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

    Bu sürüm olarak pageSizedeğişirpageSize - 1.

  3. Dosyayı kaydedin.

  4. Tümleşik terminalde uygulamayı derleyin.

    dotnet build --configuration Release
    

    Derlemenin başarılı olduğunu görmeniz gerekir.

    Uygulamada uygulamayı çalıştırabilir ve kısaca deneyebilirsiniz. Öğrenme amacıyla şimdilik bunu atlayacağız.

  5. Terminalde birim testlerini çalıştırın.

    dotnet test --no-build --configuration Release
    

    Testlerin geçtiğini görüyorsunuz.

    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. Tümleşik terminalde, değiştirilen her dosyayı dizine ekleyin, değişiklikleri işleyin ve dalı GitHub'a gönderin.

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

    Bahşiş

    Bu git add örnekteki nokta (.), joker karakterdir. Geçerli dizindeki ve tüm alt dizinlerdeki tüm korumasız dosyaları eşleştirir.

    Bu joker karakteri kullanmadan önce, hazırlamayı planladığınız dosyaları hazırladığınızdan emin olmak için işlemeden önce çalıştırmak git status iyi bir uygulamadır.

  7. Azure Pipelines'a geri dönün. Değişikliğin işlem hattında ilerlemesini izleyin. Testler başarılı olur ve genel derleme başarılı olur.

    İsteğe bağlı olarak, test sonuçlarını doğrulamak için derleme tamamlandığında Testler ve Kod Kapsamı sekmelerini seçebilirsiniz.

    Güncelleştirilmiş sonuç eğilimini görüntülemek için panoyu da kullanıma alabilirsiniz.

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

Harika! Derlemeyi düzeltdiniz. Ardından Azure DevOps ortamınızı temizlemeyi öğreneceksiniz.