Latihan - Menambahkan pengujian unit ke aplikasi Anda

Selesai

Di unit ini, kita akan menambahkan pengujian unit ke build otomatis yang kita buat dengan Microsoft Azure Pipelines. Bug regresi merayap ke dalam kode tim Anda dan merusak fungsionalitas pemfilteran papan peringkat. Secara khusus, mode permainan yang salah terus muncul.

Gambar berikut mengilustrasikan masalahnya. Ketika pengguna memilih "Bima Sakti" untuk hanya menampilkan skor dari peta permainan itu, mereka mendapatkan hasil dari peta game lain, seperti Andromeda.

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

Tim ingin menangkap kesalahan sebelum mencapai penguji. Pengujian unit adalah cara yang bagus untuk secara otomatis menguji bug regresi.

Menambahkan pengujian unit pada saat ini dalam proses akan memberi tim awal saat mereka meningkatkan aplikasi web Space Game . Aplikasi ini menggunakan database dokumen untuk menyimpan skor tinggi dan profil pemutar. Saat ini, ia menggunakan data pengujian lokal. Kemudian, mereka berencana untuk menyambungkan aplikasi ke database langsung.

Banyak kerangka kerja pengujian unit tersedia untuk aplikasi C#. Kami akan menggunakan NUnit karena populer dengan komunitas.

Berikut adalah pengujian unit yang sedang Anda kerjakan:

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

Anda dapat memfilter papan peringkat dengan kombinasi jenis permainan dan peta game apa pun.

Pengujian ini mengkueri papan peringkat untuk skor tinggi dan memverifikasi bahwa setiap hasil cocok dengan peta game yang disediakan.

Dalam metode pengujian NUnit, TestCase menyediakan data sebaris yang digunakan untuk menguji metode tersebut. Di sini, NUnit memanggil FetchOnlyRequestedGameRegion metode pengujian unit, sebagai berikut:

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

Perhatikan panggilan ke metode Assert.That di akhir pengujian. Pernyataan adalah kondisi atau pernyataan yang Anda nyatakan benar. Jika kondisinya ternyata salah, itu dapat menunjukkan bug dalam kode Anda. NUnit menjalankan setiap metode pengujian menggunakan data sebaris yang Anda tentukan dan merekam hasilnya sebagai pengujian yang lulus atau gagal.

Banyak kerangka kerja pengujian unit menyediakan metode verifikasi yang menyerupai bahasa alami. Metode ini membantu membuat pengujian mudah dibaca dan membantu Anda memetakan pengujian ke persyaratan aplikasi.

Pertimbangkan pernyataan yang dibuat dalam contoh ini:

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

Anda dapat membaca baris ini sebagai:

Tegaskan bahwa wilayah permainan dari setiap skor yang dikembalikan cocok dengan wilayah permainan yang disediakan.

Berikut adalah proses yang harus diikuti:

  1. Ambil cabang dari repositori GitHub yang berisi pengujian unit.
  2. Jalankan pengujian secara lokal untuk memverifikasi bahwa mereka lulus.
  3. Tambahkan tugas ke konfigurasi alur Anda untuk menjalankan pengujian dan mengumpulkan hasilnya.
  4. Dorong cabang ke repositori GitHub Anda.
  5. Tonton proyek Azure Pipelines Anda secara otomatis membangun aplikasi dan menjalankan pengujian.

Ambil cabang dari GitHub

Di sini, Anda akan mengambil unit-tests cabang dari GitHub dan memeriksa, atau beralih ke cabang itu.

Cabang ini berisi proyek Space Game yang anda kerjakan di modul sebelumnya dan konfigurasi Azure Pipelines untuk memulai.

  1. Di Visual Studio Code, buka terminal terintegrasi.

  2. Jalankan perintah git berikut untuk mengambil cabang bernama unit-tests dari repositori Microsoft, lalu beralih ke cabang tersebut.

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

    Format perintah ini memungkinkan Anda mendapatkan kode pemula dari repositori Microsoft GitHub, yang dikenal sebagai upstream. Tak lama, Anda akan mendorong cabang ini ke repositori GitHub Anda, yang dikenal sebagai origin.

  3. Sebagai langkah opsional, buka file azure-pipelines.yml di Visual Studio Code dan biasakan diri Anda dengan konfigurasi awal. Konfigurasinya menyerupai yang dasar yang Anda buat di modul Buat alur build dengan Azure Pipelines. Ini hanya membangun konfigurasi Rilis aplikasi.

Jalankan pengujian secara lokal

Sebaiknya jalankan semua pengujian secara lokal sebelum Anda mengirimkan pengujian apa pun ke alur. Anda akan melakukan itu di sini.

  1. Di Visual Studio Code, buka terminal terintegrasi.

  2. Jalankan dotnet build untuk membangun setiap proyek dalam solusi.

    dotnet build --configuration Release
    
  3. Jalankan perintah dotnet test berikut untuk menjalankan pengujian unit:

    dotnet test --configuration Release --no-build
    

    Bendera --no-build menentukan untuk tidak membangun proyek sebelum menjalankannya. Anda tidak perlu membangun proyek karena sudah membuatnya di langkah sebelumnya.

    Anda akan melihat bahwa kelima tes lulus.

    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
    

    Dalam contoh ini, pengujian membutuhkan waktu kurang dari satu detik untuk dijalankan.

    Perhatikan bahwa ada lima total tes. Meskipun kami hanya mendefinisikan satu metode pengujian, FetchOnlyRequestedGameRegion, pengujian tersebut dijalankan lima kali, sekali untuk setiap peta game seperti yang ditentukan dalam TestCase data sebaris.

  4. Jalankan pengujian kedua kalinya. Kali ini, berikan opsi --logger untuk menulis hasilnya ke file log.

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

    Anda melihat dari output bahwa file TRX dibuat di direktori TestResults.

    File TRX adalah dokumen XML yang berisi hasil uji coba. Ini adalah format populer untuk hasil pengujian karena Visual Studio dan alat lain dapat membantu Anda memvisualisasikan hasilnya.

    Nantinya, Anda akan melihat bagaimana Azure Pipelines dapat membantu Anda memvisualisasikan dan melacak hasil pengujian saat berjalan melalui alur.

    Catatan

    File TRX tidak dimaksudkan untuk disertakan dalam kontrol sumber. File .gitignore memungkinkan Anda menentukan file sementara dan file lain yang ingin Diabaikan Git. File .gitignore proyek sudah disiapkan untuk mengabaikan apa pun di direktori TestResults.

  5. Sebagai langkah opsional, di Visual Studio Code, buka file DocumentDBRepository_GetItemsAsyncShould.cs dari folder Tailspin.SpaceGame.Web.Tests dan periksa kode pengujian. Bahkan jika Anda tidak tertarik untuk membangun aplikasi .NET secara khusus, Anda mungkin menemukan kode pengujian yang berguna karena menyerupai kode yang mungkin Anda lihat dalam kerangka kerja pengujian unit lainnya.

Menambahkan tugas ke konfigurasi alur Anda

Di sini, Anda akan mengonfigurasi alur build untuk menjalankan pengujian unit dan mengumpulkan hasilnya.

  1. Di Visual Studio Code, ubah azure-pipelines.yml seperti berikut:

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

    Versi ini memperkenalkan tugas build DotNetCoreCLI@2 ini.

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

    Tugas build ini menjalankan perintah dotnet test.

    Perhatikan bahwa tugas ini tidak menentukan argumen --logger trx yang Anda gunakan saat menjalankan pengujian secara manual. Argumen publishTestResults menambahkannya untuk Anda. Argumen ini memberi tahu alur untuk menghasilkan file TRX ke direktori sementara, yang dapat diakses melalui variabel bawaan $(Agent.TempDirectory). Ini juga menerbitkan hasil tugas ke alur.

    Argumen projects menentukan semua proyek C# yang cocok dengan "**/*. Tests.csproj." Bagian "**" cocok dengan semua direktori, dan "*. Bagian Tests.csproj" cocok dengan semua proyek yang nama filenya diakhapi dengan ". Tests.csproj." Cabang unit-tests hanya berisi satu proyek pengujian unit, Tailspin.SpaceGame.Web.Tests.csproj. Dengan menentukan pola, Anda dapat menjalankan lebih banyak proyek pengujian tanpa perlu memodifikasi konfigurasi build Anda.

Dorong cabang ke GitHub

Di sini, Anda akan mendorong perubahan ke GitHub dan melihat eksekusi alur. Ingatlah bahwa Anda saat ini berada di cabang unit-tests.

  1. Di terminal terintegrasi, tambahkan azure-pipelines.yml ke indeks, terapkan perubahan, dan dorong cabang hingga GitHub.

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

Tonton Azure Pipelines menjalankan pengujian

Di sini Anda melihat pengujian berjalan di alur lalu memvisualisasikan hasil dari Microsoft Azure Test Plans. Azure Test Plans menyediakan semua alat yang Anda butuhkan untuk berhasil menguji aplikasi Anda. Anda dapat membuat dan menjalankan rencana pengujian manual, menghasilkan pengujian otomatis, dan mengumpulkan umpan balik dari pemangku kepentingan.

  1. Di Azure Pipelines, lacak build melalui setiap langkah.

    Anda melihat bahwa tugas Jalankan pengujian unit - Rilis menjalankan pengujian unit seperti yang Anda lakukan secara manual dari baris perintah.

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

  2. Navigasikan kembali ke ringkasan alur.

  3. Pindah ke tab Pengujian.

    Anda melihat ringkasan uji coba. Kelima tes telah lulus.

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

  4. Di Azure DevOps, pilih Uji Paket, lalu pilih Jalankan.

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

    Anda melihat uji coba terbaru, termasuk yang baru saja Anda jalankan.

  5. Klik dua kali uji coba terbaru.

    Anda melihat ringkasan hasil.

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

    Dalam contoh ini, kelima tes telah lulus. Jika ada pengujian yang gagal, Anda dapat membuka tugas build untuk mendapatkan detail selengkapnya.

    Anda juga dapat mengunduh file TRX untuk memeriksanya melalui Visual Studio atau alat visualisasi lainnya.

Meskipun Anda hanya menambahkan satu pengujian, ini adalah awal yang baik dan memperbaiki masalah segera. Sekarang, tim memiliki tempat untuk menambahkan lebih banyak tes dan menjalankannya saat mereka meningkatkan proses mereka.

Menggabungkan cabang Anda ke utama

Dalam skenario dunia nyata, jika Anda senang dengan hasilnya, Anda mungkin menggabungkan unit-tests cabang ke main, tetapi untuk brevity, kami akan melewati proses itu untuk saat ini.