Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez az oktatóanyag bemutatja, hogyan lehet egyesíteni a szemcsék tesztelését annak érdekében, hogy helyesen viselkedjenek. A szemcsék tesztelésének két fő módja van, és a választott módszer a tesztelt funkciók típusától függ. Használja a Microsoft.Orleans.TestingHost NuGet-csomagot tesztsilók létrehozásához a komponenseihez, vagy használjon egy szimuláló keretrendszert, mint például a Moq, hogy a futtatókörnyezet azon részeit modellezze, amelyekkel a komponensei kölcsönhatásba lépnek.
Használja a InProcessTestCluster (javasolt)
Ez az InProcessTestCluster az ajánlott tesztelési infrastruktúra a Orleans számára. Egyszerűsített, delegáltalapú API-t biztosít a tesztfürtök konfigurálásához, így egyszerűbbé válik a szolgáltatások megosztása a tesztek és a fürt között.
Főbb előnyök
Az InProcessTestClusterTestCluster elsődleges előnye az ergonómia:
- Delegáltalapú konfiguráció: Silók és ügyfelek konfigurálása beágyazott meghatalmazottak használatával külön konfigurációs osztályok helyett
- Megosztott szolgáltatáspéldányok: Könnyen megoszthat szimulált szolgáltatásokat, tesztmásolatokat és más példányokat a tesztkód és a siló gazdagépek között
-
Kevesebb sablon: Nincs szükség külön
ISiloConfiguratorvagyIClientConfiguratorosztályok létrehozására - Egyszerűbb függőséginjektálás: Szolgáltatások regisztrálása közvetlenül a builder fluent API-ban
InProcessTestCluster és TestCluster alapértelmezés szerint ugyanazt a folyamaton belüli siló gazdagépet használja, így a memóriahasználat és az indítási idő megegyezik. Az TestCluster API úgy lett kialakítva, hogy többfolyamatos forgatókönyveket is támogatjon (éles szimulációhoz), amelyhez az osztályalapú konfigurációs megközelítés szükséges, de alapértelmezés szerint a folyamaton belül fut, ugyanúgy.InProcessTestCluster
Alapszintű használat
using Orleans.TestingHost;
using Xunit;
public class HelloGrainTests : IAsyncLifetime
{
private InProcessTestCluster _cluster = null!;
public async Task InitializeAsync()
{
var builder = new InProcessTestClusterBuilder();
_cluster = builder.Build();
await _cluster.DeployAsync();
}
public async Task DisposeAsync()
{
await _cluster.DisposeAsync();
}
[Fact]
public async Task SaysHello()
{
var grain = _cluster.Client.GetGrain<IHelloGrain>(0);
var result = await grain.SayHello("World");
Assert.Equal("Hello, World!", result);
}
}
A tesztfürt konfigurálása
Silók, ügyfelek és szolgáltatások konfigurálására használható InProcessTestClusterBuilder :
var builder = new InProcessTestClusterBuilder(initialSilosCount: 2);
// Configure silos
builder.ConfigureSilo((options, siloBuilder) =>
{
siloBuilder.AddMemoryGrainStorage("Default");
siloBuilder.AddMemoryGrainStorage("PubSubStore");
});
// Configure clients
builder.ConfigureClient(clientBuilder =>
{
// Client-specific configuration
});
// Configure both silos and clients (shared services)
builder.ConfigureHost(hostBuilder =>
{
hostBuilder.Services.AddSingleton<IMyService, MyService>();
});
var cluster = builder.Build();
await cluster.DeployAsync();
InProcessTestClusterOptions
| Lehetőség | Típus | Alapértelmezett | Description |
|---|---|---|---|
| ClusterId | string |
Automatikusan létrehozott | Fürtazonosító. |
| ServiceId | string |
Automatikusan létrehozott | Szolgáltatásazonosító. |
InitialSilosCount |
int |
1 | Kezdetben elindítandó silók száma. |
InitializeClientOnDeploy |
bool |
true |
Azt határozza meg, hogy az ügyfél automatikusan inicializálható-e az üzembe helyezéskor. |
ConfigureFileLogging |
bool |
true |
Engedélyezze a fájlnaplózást a hibakereséshez. |
UseRealEnvironmentStatistics |
bool |
false |
Szimulált értékek helyett valós memória-/CPU-statisztikákat használjon. |
GatewayPerSilo |
bool |
true |
Azt jelzi, hogy mindegyik siló rendelkezik-e átjáróval az ügyfélkapcsolatokhoz. |
Tesztfürt megosztása tesztek között
A tesztelési teljesítmény javítása érdekében az xUnit-szerelvényekkel egyetlen fürtöt oszthat meg több tesztesetben:
public class ClusterFixture : IAsyncLifetime
{
public InProcessTestCluster Cluster { get; private set; } = null!;
public async Task InitializeAsync()
{
var builder = new InProcessTestClusterBuilder();
builder.ConfigureSilo((options, siloBuilder) =>
{
siloBuilder.AddMemoryGrainStorageAsDefault();
});
Cluster = builder.Build();
await Cluster.DeployAsync();
}
public async Task DisposeAsync()
{
await Cluster.DisposeAsync();
}
}
[CollectionDefinition(nameof(ClusterCollection))]
public class ClusterCollection : ICollectionFixture<ClusterFixture>
{
}
[Collection(nameof(ClusterCollection))]
public class HelloGrainTests
{
private readonly ClusterFixture _fixture;
public HelloGrainTests(ClusterFixture fixture)
{
_fixture = fixture;
}
[Fact]
public async Task SaysHello()
{
var grain = _fixture.Cluster.Client.GetGrain<IHelloGrain>(0);
var result = await grain.SayHello("World");
Assert.Equal("Hello, World!", result);
}
}
Silók hozzáadása és eltávolítása tesztek során
A InProcessTestCluster támogatja a dinamikus silókezelést a fürt viselkedésének tesztelésére.
// Start with 2 silos
var builder = new InProcessTestClusterBuilder(initialSilosCount: 2);
var cluster = builder.Build();
await cluster.DeployAsync();
// Add a third silo
var newSilo = await cluster.StartSiloAsync();
// Stop a silo
await cluster.StopSiloAsync(newSilo);
// Restart all silos
await cluster.RestartAsync();
A TestCluster használata
A TestCluster egy osztályalapú konfigurációs megközelítést használ, amely megköveteli a ISiloConfigurator és IClientConfigurator interfészek implementálását. Ez a kialakítás támogatja a többfolyamatos tesztelési forgatókönyveket, ahol a silók külön folyamatokban futnak, ami az éles környezethez hasonló szimulációs teszteléshez hasznos. Alapértelmezés szerint azonban a TestCluster a folyamaton belül is fut, amelynek teljesítménye megegyezik a InProcessTestCluster-ével.
Válassza a TestCluster lehetőséget a InProcessTestCluster helyett, amikor:
- Többfolyamatú tesztelésre van szükség a gyártási szimulációhoz
- Meglévő tesztjei vannak, amelyek az
TestClusterAPI-t használják. - Kompatibilitásra van szüksége a 7.x vagy a 8.x verzióval Orleans
Az új tesztekhez InProcessTestCluster az egyszerűbb delegáltalapú konfiguráció miatt ajánlott.
A Microsoft.Orleans.TestingHost NuGet-csomag tartalmaz TestClusteregy memórián belüli fürtöt (alapértelmezés szerint két silóból áll) a szemcsék teszteléséhez.
using Orleans.TestingHost;
namespace Tests;
public class HelloGrainTests
{
[Fact]
public async Task SaysHelloCorrectly()
{
var builder = new TestClusterBuilder();
var cluster = builder.Build();
cluster.Deploy();
var hello = cluster.GrainFactory.GetGrain<IHelloGrain>(Guid.NewGuid());
var greeting = await hello.SayHello("World");
cluster.StopAllSilos();
Assert.Equal("Hello, World!", greeting);
}
}
Érdemes lehet létrehozni egy memóriabeli fürtöt és TestCluster újra felhasználni több teszteset között, a memóriabeli fürtök elindításának többletterhelése miatt. Ezt például xUnit osztály- vagy gyűjteményszerelvényekkel érheti el.
Ha több teszteset között szeretne megosztani egy TestCluster elemet, először hozzon létre egy fixture típust:
using Orleans.TestingHost;
public sealed class ClusterFixture : IDisposable
{
public TestCluster Cluster { get; } = new TestClusterBuilder().Build();
public ClusterFixture() => Cluster.Deploy();
void IDisposable.Dispose() => Cluster.StopAllSilos();
}
Ezután hozzon létre egy gyűjtemény készletet.
[CollectionDefinition(Name)]
public sealed class ClusterCollection : ICollectionFixture<ClusterFixture>
{
public const string Name = nameof(ClusterCollection);
}
Most már újra felhasználhatja a TestCluster elemet a tesztesetekben.
using Orleans.TestingHost;
namespace Tests;
[Collection(ClusterCollection.Name)]
public class HelloGrainTestsWithFixture(ClusterFixture fixture)
{
private readonly TestCluster _cluster = fixture.Cluster;
[Fact]
public async Task SaysHelloCorrectly()
{
var hello = _cluster.GrainFactory.GetGrain<IHelloGrain>(Guid.NewGuid());
var greeting = await hello.SayHello("World");
Assert.Equal("Hello, World!", greeting);
}
}
Ha minden teszt befejeződött, és a memóriában lévő fürt silók leállnak, az xUnit meghívja a Dispose()ClusterFixture típusú metódust.
TestCluster konstruktor TestClusterOptions is rendelkezik, amely a fürt silóinak konfigurálásához használható.
Ha a Grains számára szolgáltatások biztosítása érdekében függőséginjektálást használ a silóban, akkor ezt a mintát is alkalmazhatja.
using Microsoft.Extensions.DependencyInjection;
using Orleans.TestingHost;
namespace Tests;
public sealed class ClusterFixtureWithConfig : IDisposable
{
public TestCluster Cluster { get; } = new TestClusterBuilder()
.AddSiloBuilderConfigurator<TestSiloConfigurations>()
.Build();
public ClusterFixtureWithConfig() => Cluster.Deploy();
void IDisposable.Dispose() => Cluster.StopAllSilos();
}
file sealed class TestSiloConfigurations : ISiloConfigurator
{
public void Configure(ISiloBuilder siloBuilder)
{
// TODO: Call required service registrations here.
// siloBuilder.Services.AddSingleton<T, Impl>(/* ... */);
}
}
Mockok használata
Orleans lehetővé teszi a rendszer számos részének imitálását is. Sok esetben ez a legegyszerűbb módszer a szemcsék tesztelésére. Ez a megközelítés korlátozásokkal rendelkezik (például az újrabelépés és a szerializálás ütemezése körül), és előfordulhat, hogy a szemcséknek csak az egységtesztek által használt kódot kell tartalmazniuk. A Orleans TestKit egy alternatív megközelítést kínál, amely számos korlátozást átvesz.
Tegyük fel például, hogy a tesztelt gabona más szemekkel is kommunikál. Ahhoz, hogy a többi objektumot imitálhassa, szimulálni kell a vizsgált objektum GrainFactory tagját. Alapértelmezés szerint a GrainFactory egy normál protected tulajdonság, de a legtöbb mocking keretrendszerben a tulajdonságoknak public és virtual kell lenniük a mockolás engedélyezéséhez. Az első lépés tehát az, hogy GrainFactory mindkettőt public és virtual:
public new virtual IGrainFactory GrainFactory
{
get => base.GrainFactory;
}
Most már a futtatókörnyezeten kívül Orleans is létrehozhatja a grain objektumot, és a GrainFactory viselkedésének szabályozására használhatja a mockolást.
using Xunit;
using Moq;
namespace Tests;
public class WorkerGrainTests
{
[Fact]
public async Task RecordsMessageInJournal()
{
var data = "Hello, World";
var journal = new Mock<IJournalGrain>();
var worker = new Mock<WorkerGrain>();
worker
.Setup(x => x.GrainFactory.GetGrain<IJournalGrain>(It.IsAny<Guid>()))
.Returns(journal.Object);
await worker.DoWork(data)
journal.Verify(x => x.Record(data), Times.Once());
}
}
Itt, a Moq használatával hozza létre a vizsgált szemcsét, WorkerGrain. Ez lehetővé teszi a GrainFactory viselkedésének felülbírálását, így egy hasonmás IJournalGrain-t ad vissza. Ezután ellenőrizheti, hogy a WorkerGrain várt módon IJournalGrain működik-e.