Aracılığıyla paylaş


İlk .NET.NET Aspire testinizi yazma

Bu makalede, bir test projesi oluşturmayı, testleri yazmayı ve bunları .NET.NET Aspire çözümleriniz için çalıştırmayı öğreneceksiniz. Bu makaledeki testler birim testleri değil, işlevsel veya tümleştirme testleridir. .NET .NET Aspire, .NET.NET Aspire kaynak bağımlılıklarınızı ve bunların iletişimlerini test etmek için kullanabileceğiniz çeşitli test proje şablonları içerir. Test projesi şablonları MSTest, NUnit ve xUnit test çerçeveleri için kullanılabilir ve testleriniz için başlangıç noktası olarak kullanabileceğiniz bir örnek test içerir.

.NET .NET Aspire test projesi şablonları, 📦Aspire.Hosting.Testing NuGet paketine dayanır. Bu paket, dağıtılmış uygulamanız için bir test konağı oluşturmak için kullanılan DistributedApplicationTestingBuilder sınıfını kullanıma sunar. Dağıtılmış uygulama testi oluşturucusu, uygulama konağıoluşturmak ve başlatmak için DistributedApplication sınıfını kullanır.

Test projesi oluşturma

.NET .NET Aspire test projesi oluşturmanın en kolay yolu test projesi şablonunu kullanmaktır. Yeni bir .NET.NET Aspire projesi başlatıyorsanız ve test projelerini eklemek istiyorsanız, Visual Studio araçları bu seçeneğidestekler. Mevcut bir .NET.NET Aspire projesine test projesi ekliyorsanız, test projesi oluşturmak için dotnet new komutunu kullanabilirsiniz:

dotnet new aspire-xunit
dotnet new aspire-mstest
dotnet new aspire-nunit

Daha fazla bilgi için .NET CLI dotnet new komut belgelerine bakın.

Test projesini keşfetme

Aşağıdaki örnek test projesi, .NET.NET Aspire Starter Uygulaması şablonunun bir parçası olarak oluşturulmuştur. Bunu bilmiyorsanız bkz. Hızlı Başlangıç: İlk .NET.NET Aspire projenizioluşturma. .NET .NET Aspire test projesi, hedef uygulama sunucusuna bir proje referansı bağımlılığı alır. Şablon projesini göz önünde bulundurun:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
    <PackageReference Include="coverlet.collector" Version="6.0.4" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
    <PackageReference Include="xunit" Version="2.9.3" />
    <PackageReference Include="xunit.runner.visualstudio" Version="3.0.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\AspireApp.AppHost\AspireApp.AppHost.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Using Include="System.Net" />
    <Using Include="Microsoft.Extensions.DependencyInjection" />
    <Using Include="Aspire.Hosting.ApplicationModel" />
    <Using Include="Aspire.Hosting.Testing" />
    <Using Include="Xunit" />
  </ItemGroup>

</Project>
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>

  <PropertyGroup>
    <EnableMSTestRunner>true</EnableMSTestRunner>
    <OutputType>Exe</OutputType>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
    <PackageReference Include="MSTest" Version="3.8.2" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\AspireApp.AppHost\AspireApp.AppHost.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Using Include="System.Net" />
    <Using Include="Microsoft.Extensions.DependencyInjection" />
    <Using Include="Aspire.Hosting.ApplicationModel" />
    <Using Include="Aspire.Hosting.Testing" />
    <Using Include="Microsoft.VisualStudio.TestTools.UnitTesting" />
  </ItemGroup>

</Project>
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsPackable>false</IsPackable>
    <IsTestProject>true</IsTestProject>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.Testing" Version="9.0.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
    <PackageReference Include="NUnit" Version="4.3.2" />
    <PackageReference Include="NUnit.Analyzers" Version="4.6.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\AspireApp.AppHost\AspireApp.AppHost.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Using Include="System.Net" />
    <Using Include="Microsoft.Extensions.DependencyInjection" />
    <Using Include="Aspire.Hosting.ApplicationModel" />
    <Using Include="Aspire.Hosting.Testing" />
    <Using Include="NUnit.Framework" />
  </ItemGroup>

</Project>

Yukarıdaki proje dosyası oldukça standarttır. PackageReference, 📦Aspireile ilişkili olarak mevcut. Hosting.Testing NuGet paketi, .NET.NET Aspire projeleri için test yazmak için gerekli türleri içerir.

Şablon testi projesi, tek bir teste sahip bir IntegrationTest1 sınıfı içerir. Test aşağıdaki senaryoyu doğrular:

  • Uygulama konağı başarıyla oluşturulur ve başlatılır.
  • webfrontend kaynağı kullanılabilir ve çalışır durumdadır.
  • webfrontend kaynağına bir HTTP isteği gönderilebilir ve başarılı bir yanıt döndürür (HTTP 200 Tamam).

Aşağıdaki test sınıfını göz önünde bulundurun:

namespace AspireApp.Tests;

public class IntegrationTest1
{
    [Fact]
    public async Task GetWebResourceRootReturnsOkStatusCode()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
        {
            clientBuilder.AddStandardResilienceHandler();
        });

        // To output logs to the xUnit.net ITestOutputHelper, 
        // consider adding a package from https://www.nuget.org/packages?q=xunit+logging

        await using var app = await appHost.BuildAsync();

        var resourceNotificationService = app.Services
            .GetRequiredService<ResourceNotificationService>();

        await app.StartAsync();

        // Act
        var httpClient = app.CreateHttpClient("webfrontend");

        await resourceNotificationService.WaitForResourceAsync(
            "webfrontend",
            KnownResourceStates.Running
            )
            .WaitAsync(TimeSpan.FromSeconds(30));

        var response = await httpClient.GetAsync("/");

        // Assert
        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
    }
}
namespace AspireApp.Tests;

[TestClass]
public class IntegrationTest1
{
    [TestMethod]
    public async Task GetWebResourceRootReturnsOkStatusCode()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
        {
            clientBuilder.AddStandardResilienceHandler();
        });

        await using var app = await appHost.BuildAsync();

        var resourceNotificationService = app.Services
            .GetRequiredService<ResourceNotificationService>();

        await app.StartAsync();

        // Act
        var httpClient = app.CreateHttpClient("webfrontend");

        await resourceNotificationService.WaitForResourceAsync(
                "webfrontend",
                KnownResourceStates.Running
            )
            .WaitAsync(TimeSpan.FromSeconds(30));
        
        var response = await httpClient.GetAsync("/");

        // Assert
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
    }
}
namespace AspireApp.Tests;

public class IntegrationTest1
{
    [Test]
    public async Task GetWebResourceRootReturnsOkStatusCode()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        appHost.Services.ConfigureHttpClientDefaults(clientBuilder =>
        {
            clientBuilder.AddStandardResilienceHandler();
        });

        await using var app = await appHost.BuildAsync();

        var resourceNotificationService = app.Services
            .GetRequiredService<ResourceNotificationService>();

        await app.StartAsync();

        // Act
        var httpClient = app.CreateHttpClient("webfrontend");

        await resourceNotificationService.WaitForResourceAsync(
                "webfrontend",
                KnownResourceStates.Running
            )
            .WaitAsync(TimeSpan.FromSeconds(30));
        
        var response = await httpClient.GetAsync("/");

        // Assert
        Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
    }
}

Önceki kod:

Kaynak ortamı değişkenlerini test edin

kaynakları ve bunların ifade edilen bağımlılıklarını .NET.NET Aspire çözümünüzde daha fazla test etmek için ortam değişkenlerinin doğru şekilde eklendiğini onaylayabilirsiniz. Aşağıdaki örnek, webfrontend kaynağının apiservice kaynağına çözümleyen bir HTTPS ortam değişkenine sahip olduğunu test etme işlemini gösterir:

using Aspire.Hosting;

namespace AspireApp.Tests;

public class EnvVarTests
{
    [Fact]
    public async Task WebResourceEnvVarsResolveToApiService()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        var frontend = (IResourceWithEnvironment)appHost.Resources
            .Single(static r => r.Name == "webfrontend");

        // Act
        var envVars = await frontend.GetEnvironmentVariableValuesAsync(
            DistributedApplicationOperation.Publish);

        // Assert
        Assert.Contains(envVars, static (kvp) =>
        {
            var (key, value) = kvp;

            return key is "services__apiservice__https__0"
                && value is "{apiservice.bindings.https.url}";
        });
    }
}
using Aspire.Hosting;

namespace AspireApp.Tests;

[TestClass]
public class EnvVarTests
{
    [TestMethod]
    public async Task WebResourceEnvVarsResolveToApiService()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        var frontend = (IResourceWithEnvironment)appHost.Resources
            .Single(static r => r.Name == "webfrontend");

        // Act
        var envVars = await frontend.GetEnvironmentVariableValuesAsync(
            DistributedApplicationOperation.Publish);

        // Assert
        CollectionAssert.Contains(envVars,
            new KeyValuePair<string, string>(
                key: "services__apiservice__https__0",
                value: "{apiservice.bindings.https.url}"));
    }
}
using Aspire.Hosting;

namespace AspireApp.Tests;

public class EnvVarTests
{
    [Test]
    public async Task WebResourceEnvVarsResolveToApiService()
    {
        // Arrange
        var appHost = await DistributedApplicationTestingBuilder
            .CreateAsync<Projects.AspireApp_AppHost>();

        var frontend = (IResourceWithEnvironment)appHost.Resources
            .Single(static r => r.Name == "webfrontend");

        // Act
        var envVars = await frontend.GetEnvironmentVariableValuesAsync(
            DistributedApplicationOperation.Publish);

        // Assert
        Assert.That(envVars, Does.Contain(
            new KeyValuePair<string, string>(
                key: "services__apiservice__https__0",
                value: "{apiservice.bindings.https.url}")));
    }
}

Önceki kod:

Özet

.NET Aspire test projesi şablonu, .NET Aspire çözümler için test projeleri oluşturmayı kolaylaştırır. Şablon projesi, testleriniz için başlangıç noktası olarak kullanabileceğiniz bir örnek test içerir. DistributedApplicationTestingBuilder, WebApplicationFactory<TEntryPoint>içindeki ASP.NET Core'e tanıdık bir desen izler gibidir. Dağıtılmış uygulamanız için bir test konağı oluşturmanıza ve buna karşı testler çalıştırmanıza olanak tanır.

Son olarak, DistributedApplicationTestingBuilder kullanıldığında tüm kaynak günlükleri varsayılan olarak DistributedApplication yönlendirilir. Kaynak günlüklerinin yeniden yönlendirilmesi, kaynağın doğru günlüğe kaydedildiğini onaylamanızı istediğiniz senaryoları etkinleştirir.

Ayrıca bkz.

  • 'de dotnet test ve xUnit kullanarak C# birim testi
  • MSTest'e genel bakış
  • NUnit ve Core ile C# Birim testi