Bagikan melalui


Menguji layanan ASP.NET Core dan aplikasi web

Tip

Konten ini adalah kutipan dari eBook, .NET Microservices Architecture for Containerized .NET Applications, tersedia di .NET Docs atau sebagai PDF yang dapat diunduh gratis dan dapat dibaca secara offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Pengontrol adalah bagian terpusat dari layanan ASP.NET Core API dan aplikasi Web MVC ASP.NET. Dengan demikian, Anda harus memiliki keyakinan bahwa mereka berperilaku seperti yang ditujukan untuk aplikasi Anda. Pengujian otomatis dapat memberi Anda keyakinan ini dan dapat mendeteksi kesalahan sebelum tiba di proses produksi.

Anda perlu menguji bagaimana pengontrol berperilaku berdasarkan input yang valid atau tidak valid, dan respons pengontrol pengujian berdasarkan hasil operasi bisnis yang dilakukannya. Namun, Anda harus memiliki jenis pengujian ini untuk layanan mikro:

  • Pengujian unit. Pengujian ini memastikan bahwa komponen individual aplikasi berfungsi seperti yang diharapkan. Pernyataan menguji API komponen.

  • Pengujian integrasi. Pengujian ini memastikan bahwa interaksi komponen berfungsi seperti yang diharapkan terhadap artefak eksternal seperti database. Pernyataan dapat menguji API komponen, antarmuka pengguna, atau efek samping tindakan seperti I/O database, pengelogan, dll.

  • Pengujian fungsi untuk setiap layanan mikro. Pengujian ini memastikan bahwa aplikasi berfungsi seperti yang diharapkan dari perspektif pengguna.

  • Pengujian layanan. Pengujian ini memastikan bahwa kasus penggunaan layanan end-to-end, termasuk menguji beberapa layanan pada saat yang sama, diuji. Untuk jenis pengujian ini, Anda perlu menyiapkan lingkungan terlebih dahulu. Dalam hal ini, berarti memulai layanan (misalnya, dengan menggunakan docker-compose up).

Mengimplementasikan pengujian unit untuk API Web ASP.NET Core

Pengujian unit melibatkan pengujian bagian dari aplikasi dalam isolasi dari infrastruktur dan dependensinya. Saat Anda membuat unit logika pengontrol pengujian, hanya konten dari satu tindakan atau metode yang diuji, bukan perilaku dependensinya atau kerangka kerja itu sendiri. Pengujian unit tidak mendeteksi masalah dalam interaksi antar komponen—itu adalah tujuan pengujian integrasi.

Saat unit menguji tindakan pengontrol, pastikan Anda hanya fokus pada perilakunya. Pengujian unit pengontrol menghindari hal-hal seperti filter, perutean, atau pengikatan model (pemetaan data permintaan ke ViewModel atau DTO). Karena mereka fokus pada pengujian satu hal saja, pengujian unit umumnya mudah ditulis dan cepat dijalankan. Serangkaian pengujian unit yang ditulis dengan baik dapat dengan sering dijalankan tanpa banyak overhead.

Pengujian unit diimplementasikan berdasarkan kerangka kerja pengujian seperti xUnit.net, MSTest, Moq, atau NUnit. Untuk aplikasi sampel eShopOnContainers, kami menggunakan xUnit.

Saat Anda menulis pengujian unit untuk pengontrol API Web, Anda membuat instans kelas pengontrol secara langsung menggunakan kata kunci baru di C#, sehingga pengujian akan berjalan secepat mungkin. Contoh berikut menunjukkan cara melakukan hal ini saat menggunakan xUnit sebagai kerangka kerja Uji.

[Fact]
public async Task Get_order_detail_success()
{
    //Arrange
    var fakeOrderId = "12";
    var fakeOrder = GetFakeOrder();

    //...

    //Act
    var orderController = new OrderController(
        _orderServiceMock.Object,
        _basketServiceMock.Object,
        _identityParserMock.Object);

    orderController.ControllerContext.HttpContext = _contextMock.Object;
    var actionResult = await orderController.Detail(fakeOrderId);

    //Assert
    var viewResult = Assert.IsType<ViewResult>(actionResult);
    Assert.IsAssignableFrom<Order>(viewResult.ViewData.Model);
}

Mengimplementasikan integrasi dan pengujian fungsi untuk setiap layanan mikro

Seperti yang disebutkan, pengujian integrasi dan pengujian fungsi memiliki tujuan dan sasaran yang berbeda. Namun, cara Anda menerapkan keduanya saat menguji pengontrol ASP.NET Core serupa, jadi di bagian ini kita berfokus pada pengujian integrasi.

Pengujian integrasi memastikan bahwa komponen aplikasi berfungsi dengan benar saat dirakit. ASP.NET Core mendukung pengujian integrasi menggunakan kerangka kerja pengujian unit dan host web pengujian bawaan yang dapat digunakan untuk menangani permintaan tanpa overhead jaringan.

Tidak seperti pengujian unit, pengujian integrasi sering melibatkan masalah infrastruktur aplikasi, seperti database, sistem file, sumber daya jaringan, atau permintaan dan respons web. Pengujian unit menggunakan objek palsu atau tiruan sebagai pengganti masalah ini. Namun, tujuan pengujian integrasi adalah untuk mengonfirmasi bahwa sistem berfungsi seperti yang diharapkan dengan sistem ini, jadi untuk pengujian integrasi Anda tidak menggunakan objek palsu atau tiruan. Sebagai gantinya, Anda menyertakan infrastruktur, seperti akses database atau pemanggilan layanan dari layanan lain.

Karena pengujian integrasi menjalankan segmen kode yang lebih besar daripada pengujian unit, dan karena pengujian integrasi mengandalkan elemen infrastruktur, pengujian tersebut cenderung lebih lambat daripada pengujian unit. Dengan demikian, ada baiknya untuk membatasi berapa banyak pengujian integrasi yang Anda tulis dan jalankan.

ASP.NET Core menyertakan host web pengujian bawaan yang dapat digunakan untuk menangani permintaan HTTP tanpa overhead jaringan, artinya Anda dapat menjalankan pengujian tersebut lebih cepat daripada saat menggunakan host web nyata. Host web pengujian (TestServer) tersedia dalam komponen NuGet sebagai Microsoft.AspNetCore.TestHost. Ini dapat ditambahkan ke proyek pengujian integrasi dan digunakan untuk menghosting aplikasi ASP.NET Core.

Seperti yang Anda lihat dalam kode berikut, saat Anda membuat pengujian integrasi untuk pengontrol ASP.NET Core, Anda membuat instans pengontrol melalui host pengujian. Fungsionalitas ini sebanding dengan permintaan HTTP, tetapi berjalan lebih cepat.

public class PrimeWebDefaultRequestShould
{
    private readonly TestServer _server;
    private readonly HttpClient _client;

    public PrimeWebDefaultRequestShould()
    {
        // Arrange
        _server = new TestServer(new WebHostBuilder()
           .UseStartup<Startup>());
        _client = _server.CreateClient();
    }

    [Fact]
    public async Task ReturnHelloWorld()
    {
        // Act
        var response = await _client.GetAsync("/");
        response.EnsureSuccessStatusCode();
        var responseString = await response.Content.ReadAsStringAsync();
        // Assert
        Assert.Equal("Hello World!", responseString);
    }
}

Sumber daya tambahan

Mengimplementasikan pengujian layanan pada aplikasi multi-kontainer

Seperti yang disebutkan sebelumnya, ketika Anda menguji aplikasi multi-kontainer, semua layanan mikro perlu berjalan dalam host Docker atau kluster kontainer. Pengujian layanan end-to-end yang mencakup banyak operasi yang melibatkan beberapa layanan mikro mengharuskan Anda untuk menyebarkan dan memulai seluruh aplikasi di host Docker dengan menjalankan docker-compose up (atau mekanisme yang sebanding jika Anda menggunakan orkestrator). Setelah seluruh aplikasi dan semua layanannya berjalan, Anda dapat menjalankan integrasi end-to-end dan pengujian fungsi.

Ada beberapa pendekatan yang Anda dapat gunakan. Dalam file docker-compose.yml yang digunakan untuk menyebarkan aplikasi di tingkat solusi, Anda dapat memperluas titik masuk untuk menggunakan pengujian dotnet. Anda juga dapat menggunakan file tulis lain yang akan menjalankan pengujian dalam gambar yang Anda targetkan. Dengan menggunakan file tulis lain untuk pengujian integrasi yang menyertakan layanan mikro dan database pada kontainer, Anda dapat memastikan bahwa data terkait selalu diatur ulang ke keadaan semula sebelum menjalankan pengujian.

Begitu aplikasi tulis aktif, Anda dapat memanfaatkan titik henti dan pengecualian jika menjalankan Visual Studio. Atau, Anda dapat menjalankan pengujian integrasi secara otomatis di alur CI layanan Azure DevOps atau sistem CI/CD lainnya yang mendukung kontainer Docker.

Pengujian di eShopOnContainers

Pengujian aplikasi referensi (eShopOnContainers) belakangan ini direstrukturisasi dan sekarang ada empat kategori:

  1. Pengujianunit, hanya pengujian unit reguler lama biasa, yang terkandung dalam proyek {MicroserviceName}. UnitTests

  2. Pengujian fungsi/integrasi layanan mikro, dengan kasus pengujian yang melibatkan infrastruktur untuk setiap layanan mikro tetapi terisolasi dari yang lain dan terkandung dalam proyek {MicroserviceName}. FunctionalTests.

  3. Pengujian fungsional/integrasi aplikasi, yang berfokus pada integrasi layanan mikro, dengan kasus pengujian yang mengerahkan beberapa layanan mikro. Pengujian ini terletak di proyek Application.FunctionalTests.

Sementara pengujian unit dan integrasi diatur dalam folder pengujian dalam proyek layanan mikro, pengujian aplikasi dan beban dikelola secara terpisah di bawah folder akar, seperti yang ditunjukkan pada Gambar 6-25.

Screenshot of VS pointing out some of the test projects in the solution.

Gambar 6-25. Menguji struktur folder di eShopOnContainers

Pengujian fungsional/integrasi Layanan Mikro dan Aplikasi dijalankan dari Visual Studio, menggunakan runner pengujian reguler, tetapi terlebih dahulu Anda perlu memulai layanan infrastruktur yang diperlukan, dengan sekumpulan file docker-compose yang terkandung dalam folder uji solusi:

docker-compose-test.yml

version: '3.4'

services:
  redis.data:
    image: redis:alpine
  rabbitmq:
    image: rabbitmq:3-management-alpine
  sqldata:
    image: mcr.microsoft.com/mssql/server:2017-latest
  nosqldata:
    image: mongo

docker-compose-test.override.yml

version: '3.4'

services:
  redis.data:
    ports:
      - "6379:6379"
  rabbitmq:
    ports:
      - "15672:15672"
      - "5672:5672"
  sqldata:
    environment:
      - SA_PASSWORD=Pass@word
      - ACCEPT_EULA=Y
    ports:
      - "5433:1433"
  nosqldata:
    ports:
      - "27017:27017"

Jadi, untuk menjalankan pengujian fungsional/integrasi, Anda harus terlebih dahulu menjalankan perintah ini, dari folder uji solusi:

docker-compose -f docker-compose-test.yml -f docker-compose-test.override.yml up

Seperti yang Anda lihat, file docker-compose ini hanya memulai layanan mikro Redis, RabbitMQ, SQL Server, dan MongoDB.

Sumber daya tambahan