Sdílet prostřednictvím


Testování služeb a webových aplikací ASP.NET Core

Návod

Tento obsah je výňatek z eBooku, architektury mikroslužeb .NET pro kontejnerizované aplikace .NET, které jsou k dispozici na .NET Docs nebo jako zdarma ke stažení PDF, které lze číst offline.

Architektura mikroslužeb .NET pro kontejnerizované eBooky aplikací .NET

Kontrolery jsou ústřední součástí jakékoli služby rozhraní API ASP.NET Core a webové aplikace ASP.NET MVC. Proto byste měli mít jistotu, že se chovají tak, jak jsou určené pro vaši aplikaci. Automatizované testy vám můžou poskytnout tuto jistotu a mohou detekovat chyby, než se dostanou do produkčního prostředí.

Musíte otestovat, jak se kontroler chová na základě platných nebo neplatných vstupů, a odpovědi kontroleru testů na základě výsledku obchodní operace, kterou provádí. Pro mikroslužby byste ale měli mít tyto typy testů:

  • Testy jednotek. Tyto testy zajišťují, aby jednotlivé komponenty aplikace fungovaly podle očekávání. Kontrolní výrazy testují rozhraní API komponenty.

  • Integrační testy. Tyto testy zajišťují, aby interakce komponent fungovaly podle očekávání s externími artefakty, jako jsou databáze. Kontrolní výrazy můžou testovat rozhraní API komponent, uživatelské rozhraní nebo vedlejší účinky akcí, jako jsou vstupně-výstupní operace databáze, protokolování atd.

  • Funkční testy pro každou mikroslužbu Tyto testy zajišťují, aby aplikace fungovala podle očekávání z pohledu uživatele.

  • Testy služeb. Tyto testy zajišťují testování kompletních případů použití služby, včetně testování více služeb najednou. Pro tento typ testování musíte nejprve připravit prostředí. V tomto případě to znamená spuštění služeb (například pomocí docker-compose up).

Implementace testů jednotek pro webová rozhraní API ASP.NET Core

Testování částí zahrnuje testování části aplikace izolovaně od infrastruktury a závislostí. Pokud provádíte testování jednotek logiky kontroleru, testuje se pouze obsah jedné akce nebo metody, nikoli chování jejích závislostí nebo samotné architektury. Testy jednotek nezjišťují problémy při interakci mezi komponentami – to je účelem testování integrace.

Při testování jednotek kontrolerů se ujistěte, že se zaměříte pouze na jejich chování. Test jednotek kontroleru se vyhne například filtrům, směrováním nebo vazbám modelu (mapování dat požadavků na model ViewModel nebo DTO). Vzhledem k tomu, že se zaměřují pouze na testování jedné věci, testy jednotek jsou obecně jednoduché napsat a rychle spustit. Dobře napsaná sada testů jednotek se může spouštět často bez velké režie.

Testy jednotek se implementují na základě testovacích architektur, jako jsou xUnit.net, MSTest, Moq nebo NUnit. Pro ukázkovou aplikaci eShopOnContainers používáme xUnit.

Při psaní testu jednotek pro kontroler webového rozhraní API vytvoříte instanci třídy kontroleru přímo pomocí nového klíčového slova v jazyce C#, aby test běžel co nejrychleji. Následující příklad ukazuje, jak to provést při použití xUnit jako testovací architektury.

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

Implementace integračních a funkčních testů pro každou mikroslužbu

Jak je uvedeno, integrační testy a funkční testy mají různé účely a cíle. Způsob implementace obojího při testování ASP.NET řadičů Core je ale podobný, takže v této části se soustředíme na integrační testy.

Testování integrace zajišťuje správné fungování komponent aplikace při sestavení. ASP.NET Core podporuje testování integrace pomocí architektur testů jednotek a integrovaného testovacího webového hostitele, který lze použít ke zpracování požadavků bez režie na síť.

Na rozdíl od testování jednotek často testy integrace zahrnují aspekty infrastruktury aplikací, jako je databáze, systém souborů, síťové prostředky nebo webové požadavky a odpovědi. Testy jednotek používají falešné nebo napodobené objekty místo těchto obav. Účelem integračních testů je ale potvrdit, že systém funguje podle očekávání s těmito systémy, takže pro integrační testování nepoužíváte falešné nebo napodobené objekty. Místo toho zahrnete infrastrukturu, jako je přístup k databázi nebo vyvolání služby z jiných služeb.

Vzhledem k tomu, že integrační testy pracují s většími segmenty kódu než testy jednotek, a protože integrační testy spoléhají na prvky infrastruktury, jsou obvykle řádově pomalejší než testy jednotek. Proto je vhodné omezit počet testů integrace, které píšete a spouštíte.

ASP.NET Core obsahuje integrovaného testovacího webového hostitele, kterého je možné použít ke zpracování požadavků HTTP bez režijních nákladů na síť, což znamená, že tyto testy můžete spouštět rychleji než při použití skutečného webového hostitele. Testovací webový hostitel (TestServer) je k dispozici v komponentě NuGet jako Microsoft.AspNetCore.TestHost. Dá se přidat do projektů integračních testů a použít ho k hostování aplikací ASP.NET Core.

Jak vidíte v následujícím kódu, při vytváření integračních testů pro kontrolery ASP.NET Core vytvoříte instanci kontrolerů prostřednictvím testovacího hostitele. Tato funkce je srovnatelná s požadavkem HTTP, ale běží rychleji.

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

Další materiály

Implementace testů služby v aplikaci s více kontejnery

Jak už bylo zmíněno dříve, když testujete vícekontenerové aplikace, musí být všechny mikroslužby spuštěné v rámci hostitele Nebo clusteru kontejnerů Dockeru. Kompletní testy služeb, které zahrnují více operací zahrnujících několik mikroslužeb, vyžadují nasazení a spuštění celé aplikace v hostiteli Dockeru spuštěním docker-compose up (nebo srovnatelného mechanismu, pokud používáte orchestrátor). Jakmile je celá aplikace a všechny její služby spuštěné, můžete spouštět kompletní integraci a funkční testy.

Existuje několik přístupů, které můžete použít. V souboru docker-compose.yml, který používáte k nasazení aplikace na úrovni řešení, můžete rozbalit vstupní bod a použít dotnet test. Můžete také použít jiný soubor pro psaní, který by spouštěl testy na obrázku, na který cílíte. Pomocí jiného souboru pro integrační testy, které obsahují vaše mikroslužby a databáze v kontejnerech, můžete před spuštěním testů zajistit, aby se související data vždy resetovala do původního stavu.

Jakmile je aplikace pro psaní spuštěná a spuštěná, můžete využít zarážky a výjimky, pokud používáte Visual Studio. Nebo můžete testy integrace spouštět automaticky ve svém kanálu CI v Azure DevOps Services nebo v jakémkoli jiném systému CI/CD, který podporuje kontejnery Dockeru.

Testování v eShopOnContainers

Testy referenční aplikace (eShopOnContainers) byly nedávno restrukturalizovány a nyní existují čtyři kategorie:

  1. Testy jednotek, pouze běžné běžné testy jednotek, obsažené v {MicroserviceName}. Projekty UnitTests

  2. Testy funkčnosti/integrace mikroslužeb s testovacími případy zahrnujícími infrastrukturu pro každou mikroslužbu, ale izolovanou od ostatních a jsou obsaženy v části {MicroserviceName}. Projekty FunctionalTests

  3. Testy funkčnosti/integrace aplikací, které se zaměřují na integraci mikroslužeb, s testovacími případy, které mají několik mikroslužeb. Tyto testy jsou umístěny v projektu Application.FunctionalTests.

I když jsou testy jednotek a integrace uspořádány do testovací složky v rámci projektu mikroslužby, aplikace a zátěžové testy se spravují samostatně v kořenové složce, jak je znázorněno na obrázku 6–25.

Snímek obrazovky se službou VS ukazující na některé testovací projekty v řešení

Obrázek 6–25 Test struktury složek v eShopOnContainers

Mikroslužby a testy funkčnosti/integrace aplikací se spouštějí ze sady Visual Studio pomocí spouštěče běžných testů, ale nejprve je potřeba spustit požadované služby infrastruktury se sadou souborů docker-compose obsažených ve složce testu řešení:

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=[PLACEHOLDER]
      - ACCEPT_EULA=Y
    ports:
      - "5433:1433"
  nosqldata:
    ports:
      - "27017:27017"

Důležité

Microsoft doporučuje používat nejbezpečnější dostupný tok ověřování. Pokud se připojujete k Azure SQL, spravované identity pro prostředky Azure se doporučují metodou ověřování.

Pokud tedy chcete spustit funkční/integrační testy, musíte nejprve spustit tento příkaz ze složky test řešení:

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

Jak vidíte, tyto soubory docker-compose spouštějí pouze mikroslužby Redis, RabbitMQ, SQL Server a MongoDB.

Další materiály