Menulis tes .NET.NET Aspire pertama Anda
Dalam artikel ini, Anda mempelajari cara membuat proyek pengujian, menulis pengujian, dan menjalankannya untuk solusi .NET.NET Aspire Anda. Pengujian dalam artikel ini bukan pengujian unit, melainkan pengujian fungsional atau integrasi. .NET .NET Aspire menyertakan beberapa variasi templat proyek pengujian yang dapat Anda gunakan untuk menguji dependensi sumber daya .NET.NET Aspire Anda—dan komunikasinya. Templat proyek pengujian tersedia untuk kerangka kerja pengujian MSTest, NUnit, dan xUnit dan menyertakan pengujian sampel yang dapat Anda gunakan sebagai titik awal untuk pengujian Anda.
Templat proyek pengujian .NET.NET Aspire mengandalkan 📦Aspire. Hosting.Testing paket NuGet. Paket ini mengekspos kelas DistributedApplicationTestingBuilder, yang digunakan untuk membuat host pengujian untuk aplikasi terdistribusi Anda. Penyusun pengujian aplikasi terdistribusi bergantung pada kelas DistributedApplication untuk membuat dan memulai host aplikasi .
Membuat proyek pengujian
Cara term mudah untuk membuat proyek pengujian .NET.NET Aspire adalah dengan menggunakan templat proyek pengujian. Jika Anda memulai proyek .NET.NET Aspire baru dan ingin menyertakan proyek pengujian, alat Visual Studio mendukung opsi tersebut. Jika Anda menambahkan proyek pengujian ke proyek .NET.NET Aspire yang sudah ada, Anda dapat menggunakan perintah dotnet new
untuk membuat proyek pengujian:
dotnet new aspire-xunit
dotnet new aspire-mstest
dotnet new aspire-nunit
Untuk informasi selengkapnya, lihat dokumentasi perintah baru
Menjelajahi proyek pengujian
Contoh proyek pengujian berikut dibuat sebagai bagian dari templat Aplikasi Pemula
<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>
File proyek sebelumnya cukup standar. Ada PackageReference
untuk 📦Aspire. paket NuGet Hosting.Testing, yang mencakup jenis yang diperlukan untuk menulis pengujian pada proyek .NET.NET Aspire.
Proyek pengujian templat mencakup kelas IntegrationTest1
dengan satu pengujian. Pengujian memverifikasi skenario berikut:
- Hosting aplikasi berhasil dibuat dan dimulai.
- Sumber daya
webfrontend
tersedia dan beroperasi. - Permintaan HTTP dapat dibuat ke sumber daya
webfrontend
dan mengembalikan respons yang berhasil (HTTP 200 OK).
Pertimbangkan kelas pengujian berikut:
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));
}
}
Kode sebelumnya:
- Bergantung pada API DistributedApplicationTestingBuilder.CreateAsync untuk membuat host aplikasi secara asinkron.
-
appHost
adalah instansIDistributedApplicationTestingBuilder
yang mewakili host aplikasi. - Instans
appHost
memiliki koleksi layanan yang dikonfigurasi dengan handler ketahanan HTTP standar. Untuk informasi selengkapnya, lihat Membangun aplikasi HTTP tangguh: Pola pengembangan utama.
-
-
appHost
memiliki metode IDistributedApplicationTestingBuilder.BuildAsync(CancellationToken) yang dipanggil, yang mengembalikan instansDistributedApplication
sebagaiapp
.-
app
memiliki penyedia layanannya mendapatkan instans ResourceNotificationService. -
app
dijalankan secara asinkron.
-
-
HttpClient dibuat untuk sumber daya
webfrontend
dengan memanggilapp.CreateHttpClient
. -
resourceNotificationService
digunakan untuk menunggu sumber dayawebfrontend
tersedia dan berjalan. - Permintaan HTTP GET sederhana dibuat ke akar sumber daya
webfrontend
. - Pengujian menegaskan bahwa kode status respons
OK
.
Menguji variabel lingkungan sumber daya
Untuk menguji sumber daya lebih lanjut dan dependensi yang dinyatakan dalam solusi .NET.NET Aspire Anda, Anda dapat menegaskan bahwa variabel lingkungan disuntikkan dengan benar. Contoh berikut menunjukkan cara menguji bahwa sumber daya webfrontend
memiliki variabel lingkungan HTTPS yang mengarah ke sumber daya apiservice
:
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}")));
}
}
Kode sebelumnya:
- Bergantung pada API DistributedApplicationTestingBuilder.CreateAsync untuk membuat host aplikasi secara asinkron.
- Instans
builder
digunakan untuk mengambil instans IResourceWithEnvironment bernama "webfrontend" dari IDistributedApplicationTestingBuilder.Resources. - Sumber daya
webfrontend
digunakan untuk memanggil GetEnvironmentVariableValuesAsync untuk mengambil variabel lingkungan yang dikonfigurasi. - Argumen DistributedApplicationOperation.Publish diteruskan saat memanggil
GetEnvironmentVariableValuesAsync
untuk menentukan variabel lingkungan yang diterbitkan ke sumber daya sebagai ekspresi pengikatan. - Dengan variabel lingkungan yang telah dikembalikan, pengujian memastikan bahwa sumber daya
webfrontend
memiliki variabel lingkungan HTTPS yang merujuk pada sumber dayaapiservice
.
Ringkasan
Templat proyek pengujian .NET Aspire memudahkan untuk membuat proyek pengujian untuk solusi .NET Aspire. Proyek templat menyertakan pengujian sampel yang dapat Anda gunakan sebagai titik awal untuk pengujian Anda.
DistributedApplicationTestingBuilder
mengikuti pola yang akrab dengan WebApplicationFactory<TEntryPoint> di ASP.NET Core. Ini memungkinkan Anda untuk membuat host pengujian untuk aplikasi terdistribusi Anda dan menjalankan pengujian terhadapnya.
Terakhir, saat menggunakan DistributedApplicationTestingBuilder
semua log sumber daya dialihkan ke DistributedApplication
secara default. Pengalihan log sumber daya memungkinkan skenario di mana Anda ingin memastikan bahwa sumber daya tersebut mencatat dengan benar.
Lihat juga
.NET Aspire