Bővítmények létrehozása Microsoft. Testing.Platform (MTP)

Ez a cikk az MTP bővíthetőségi pontjait ismerteti a tesztelési keretrendszeren túl. A tesztelési keretrendszer létrehozásához tekintse meg a tesztelési keretrendszer létrehozását ismertető témakört.

A bővítménypont teljes összefoglalását és a folyamaton belüli/folyamaton kívüli fogalmakat az egyéni bővítmények létrehozása című témakörben talál.

Bővíthetőségi pontok

A tesztelési platform további bővíthetőségi pontokat biztosít, amelyek lehetővé teszik a platform és a tesztelési keretrendszer viselkedésének testreszabását. Ezek a bővíthetőségi pontok nem kötelezőek, és a tesztelési élmény fokozására használhatók.

Jótanács

A cikkben szereplő összes bővítmény tartalmaz egy manuális regisztrációs kódrészletet (például builder.TestHost.AddDataConsumer(...)). Ha a bővítményt NuGet-csomagként terjeszti, lehetővé teheti, hogy a felhasználók kihagyják a manuális hívást egy TestingPlatformBuilderHook és egy kis MSBuild props-fájl elérhetővé tételével. Az automatikusan létrehozott belépési pont ezután meghívja a hookot. A részletekért lásd: A bővítmény automatikus regisztrálása a(z) TestingPlatformBuilderHook használatával.

A ICommandLineOptionsProvider bővítmények

Jegyzet

Az API kiterjesztésekor az egyéni bővítmény a tesztgazdafolyamatban és azon kívül is létezik.

Az architektúra szakaszában leírtak szerint a kezdeti lépés a tesztelési keretrendszer és a bővítmények regisztrálásához szükséges ITestApplicationBuilder létrehozása.

var builder = await TestApplication.CreateBuilderAsync(args);

A CreateBuilderAsync metódus egy string[]nevű sztringtömböt (args) fogad el. Ezekkel az argumentumokkal parancssori beállításokat adhat át a tesztelési platform összes összetevőjének (beleértve a beépített összetevőket, a tesztelési keretrendszereket és a bővítményeket), lehetővé téve a viselkedés testreszabását.

Az átadott argumentumok általában a standard Main(string[] args) metódusban kapott argumentumok. Ha azonban az üzemeltetési környezet eltér, az argumentumok bármelyik listája megadható.

Az argumentumokat kell előtaggal rendelkezni. Például: --filter.

Ha egy összetevő, például egy tesztelési keretrendszer vagy egy bővítménypont egyéni parancssori lehetőségeket szeretne kínálni, ezt a ICommandLineOptionsProvider felület implementálásával teheti meg. Ez a megvalósítás ezután regisztrálható a ITestApplicationBuilder-nak a CommandLine tulajdonság regisztrációs gyárán keresztül, ahogy azt az alábbiakban láthatjuk:

builder.CommandLine.AddProvider(
    static () => new CustomCommandLineOptions());

A megadott példában CustomCommandLineOptions a ICommandLineOptionsProvider felület implementálása, ez az interfész a következő tagokból és adattípusokból áll:

public interface ICommandLineOptionsProvider : IExtension
{
    IReadOnlyCollection<CommandLineOption> GetCommandLineOptions();

    Task<ValidationResult> ValidateOptionArgumentsAsync(
        CommandLineOption commandOption,
        string[] arguments);

    Task<ValidationResult> ValidateCommandLineOptionsAsync(
        ICommandLineOptions commandLineOptions);
}

public sealed class CommandLineOption
{
    public string Name { get; }
    public string Description { get; }
    public ArgumentArity Arity { get; }
    public bool IsHidden { get; }

    // ...
}

public interface ICommandLineOptions
{
    bool IsOptionSet(string optionName);

    bool TryGetOptionArgumentList(
        string optionName,
        out string[]? arguments);
}

Mint látható, a ICommandLineOptionsProvider kibővíti a IExtension felületet. Ezért, mint minden más bővítmény, engedélyezheti vagy letilthatja a IExtension.IsEnabledAsync API-val.

A ICommandLineOptionsProvider végrehajtásának sorrendje a következő:

Az ICommandLineOptionsProvider felület végrehajtási sorrendjét ábrázoló diagram.

Vizsgáljuk meg az API-k és középértéküket:

ICommandLineOptionsProvider.GetCommandLineOptions(): Ez a módszer az összetevő által kínált összes lehetőség lekérésére használható. Minden CommandLineOption a következő tulajdonságokat kell megadni:

string name: Ez a lehetőség neve, kötőjel nélkül jelenik meg. A például szűrőt felhasználók használják --filter-ként.

string description: Ez a beállítás leírása. Akkor jelenik meg, ha a felhasználók argumentumként adják át --help az alkalmazásszerkesztőnek.

ArgumentArity arity: Egy beállítás aritása az adott beállítás vagy parancs megadása esetén átadható értékek száma. A jelenlegi elérhető lehetőségek a következők:

  • Zero: Nulla argumentum-aritást jelöl.
  • ZeroOrOne: Nulla vagy egy argumentum aritását jelöli.
  • ZeroOrMore: Nulla vagy több argumentum aritását jelöli.
  • OneOrMore: Egy vagy több argumentum aritását jelöli.
  • ExactlyOne: Pontosan egy argumentum aritását jelöli.

Példákért tekintse meg a System.CommandLine arity táblát.

bool isHidden: Ez a tulajdonság azt jelzi, hogy a beállítás használható, de --help meghívásakor nem jelenik meg a leírásban.

ICommandLineOptionsProvider.ValidateOptionArgumentsAsync: Ez a módszer a felhasználó által megadott argumentum ellenőrzésére szolgál.

Ha például --dop nevű paraméterrel rendelkezik, amely az egyéni tesztelési keretrendszer párhuzamossági fokát jelöli, a felhasználó --dop 0adhat meg. Ebben a forgatókönyvben a 0 érték érvénytelen lenne, mert a párhuzamossági fokának 1-nek vagy annál nagyobbnak kell lennie. A ValidateOptionArgumentsAsynchasználatával előzetes ellenőrzést végezhet, és szükség esetén hibaüzenetet adhat vissza.

A fenti minta lehetséges implementációja a következő lehet:

public Task<ValidationResult> ValidateOptionArgumentsAsync(
    CommandLineOption commandOption,
    string[] arguments)
{
    if (commandOption.Name == "dop")
    {
        if (!int.TryParse(arguments[0], out int dopValue) || dopValue <= 0)
        {
            return ValidationResult.InvalidTask("--dop must be a positive integer");
        }
    }

    return ValidationResult.ValidTask;
}

ICommandLineOptionsProvider.ValidateCommandLineOptionsAsync: Ez a metódus az utolsó, és lehetővé teszi a globális koherencia-ellenőrzést.

Tegyük fel például, hogy a tesztelési keretrendszer képes létrehozni egy teszteredmény-jelentést, és menteni egy fájlba. Ez a funkció a --generatereport beállítással érhető el, a fájlnév pedig a --reportfilename myfile.rep. Ebben az esetben, ha egy felhasználó csak a --generatereport lehetőséget adja meg fájlnév megadása nélkül, az érvényesítés sikertelen lesz, mert a jelentés nem hozható létre fájlnév nélkül. A fenti minta lehetséges implementációja a következő lehet:

public Task<ValidationResult> ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions)
{
    bool generateReportEnabled = commandLineOptions.IsOptionSet(GenerateReportOption);
    bool reportFileName = commandLineOptions.TryGetOptionArgumentList(ReportFilenameOption, out string[]? _);

    return (generateReportEnabled || reportFileName) && !(generateReportEnabled && reportFileName)
        ? ValidationResult.InvalidTask("Both `--generatereport` and `--reportfilename` need to be provided simultaneously.")
        : ValidationResult.ValidTask;
}

Vegye figyelembe, hogy a ValidateCommandLineOptionsAsync metódus biztosítja a ICommandLineOptions szolgáltatást, amely a platform által elemezett argumentumadatok lekérésére szolgál.

A ITestSessionLifetimeHandler bővítmények

A ITestSessionLifetimeHandler egy folyamatban lévő bővítmény, amely lehetővé teszi a kód végrehajtását előtt, és a tesztmunkamenet után.

Egyéni ITestSessionLifetimeHandlerregisztrációhoz használja a következő API-t:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

builder.TestHost.AddTestSessionLifetimeHandle(
    static serviceProvider => new CustomTestSessionLifetimeHandler());

A gyár az IServiceProvider használja a tesztelési platform által kínált szolgáltatásokhoz való hozzáféréshez.

Fontos

A regisztráció sorrendje jelentős, mivel az API-k a regisztráció sorrendjében vannak meghívva.

A ITestSessionLifetimeHandler felület a következő módszereket tartalmazza:

public interface ITestSessionLifetimeHandler : ITestHostExtension
{
    Task OnTestSessionStartingAsync(ITestSessionContext testSessionContext);

    Task OnTestSessionFinishingAsync(ITestSessionContext testSessionContext);
}

public interface ITestSessionContext
{
    SessionUid SessionUid { get; }

    CancellationToken CancellationToken { get; }
}

public readonly struct SessionUid(string value)
{
    public string Value { get; } = value;
}

public interface ITestHostExtension : IExtension
{
}

Fontos

Az MTP 2.0.0-ban mindkét módszer úgy változott meg, hogy egyetlen ITestSessionContext paramétert fogadjon, amely elérhetővé teszi a SessionUid és a CancellationToken elemet. Az MTP 1.x-ben minden metódus külön SessionUid és CancellationToken argumentumot vett igénybe. További információkért lásd: Migrálás a Microsoft.Testing.Platform (MTP) v1-ről v2-re.

A ITestSessionLifetimeHandler egy ITestHostExtensiontípusa, amely az összes tesztgazda bővítmény alapjaként szolgál. Az összes többi bővítményponthoz hasonlóan ez is örökli a IExtension-t. Ezért, mint minden más bővítmény, engedélyezheti vagy letilthatja a IExtension.IsEnabledAsync API-val.

Vegye figyelembe az API következő részleteit:

OnTestSessionStartingAsync: Ez a metódus a tesztmunkamenet megkezdése előtt kerül meghívásra, és megkapja a(z) ITestSessionContext elemet, amelynek SessionUid eleme egy átlátszatlan azonosítót biztosít az aktuális tesztmunkamenethez.

OnTestSessionFinishingAsync: Ezt a metódust a tesztmunkamenet befejezése után hívja meg a program, biztosítva, hogy a tesztelési keretrendszer végzett az összes teszt végrehajtásával, és minden releváns adatot jelentett a platformnak. Ebben a módszerben a bővítmény általában a IMessageBus használja az egyéni objektumok vagy adatok megosztott platformbuszba való továbbítására. Ez a módszer bármilyen egyéni folyamaton kívüli bővítménynek is jelezheti, hogy a tesztmunkamenet befejeződött.

Végül a ITestSessionContext elérhetővé tesz egy CancellationToken elemet, amelyet a bővítménynek be kell tartania.

Ha a bővítmény intenzív inicializálást igényel, és az aszinkron/várakozási mintát kell használnia, tekintse meg a Async extension initialization and cleanup. Ha meg kell osztania az állapot a bővítménypontok között, tekintse meg a CompositeExtensionFactory<T> szakaszt.

A ITestApplicationLifecycleCallbacks bővítmények

Fontos

ITestApplicationLifecycleCallbacks az MTP 2.0.0-s fájlban el lett távolítva. A ITestHostApplicationLifetime használható helyette. További információkért lásd: Migrálás a Microsoft.Testing.Platform (MTP) v1-ről v2-re.

Az ITestHostApplicationLifetime interfész lehetővé teszi, hogy a folyamaton belüli bővítmény kódokat futtasson a tesztgazda elején és végén.

Egyéni ITestHostApplicationLifetimeregisztrációhoz használja a következő API-t:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

builder.TestHost.AddTestHostApplicationLifetime(
    static serviceProvider
    => new CustomTestHostApplicationLifetime());

A gyár az IServiceProvider használatával éri el a tesztelési platform által kínált szolgáltatásokat.

Fontos

A regisztráció sorrendje jelentős, mivel az API-k a regisztráció sorrendjében vannak meghívva.

A ITestHostApplicationLifetime felület a következő módszereket tartalmazza:

public interface ITestHostApplicationLifetime : ITestHostExtension
{
    Task BeforeRunAsync(CancellationToken cancellationToken);

    Task AfterRunAsync(
        int exitCode,
        CancellationToken cancellationToken);
}

public interface ITestHostExtension : IExtension
{
}

Az ITestHostApplicationLifetime interfész kiterjeszti a(z) ITestHostExtension elemet, amely az összes tesztgazda-bővítmény alapjául szolgál. Az összes többi bővítményponthoz hasonlóan ez is örökli a IExtension-t. Ezért, mint minden más bővítmény, engedélyezheti vagy letilthatja a IExtension.IsEnabledAsync API-val.

BeforeRunAsync: Ez a módszer szolgál a tesztgazda kezdeti kapcsolattartó pontjaként, és ez az első lehetőség egy folyamatban lévő bővítmény számára egy funkció végrehajtására. Általában arra használják, hogy kapcsolatot létesítsen a megfelelő folyamaton kívüli bővítményekkel, ha egy szolgáltatás mindkét környezetben való működésre van tervezve.

A beépített lefagyási memóriakép funkció például folyamaton belüli és folyamaton kívüli bővítményekből áll, és ez a módszer a bővítmény folyamaton kívüli összetevőjével való információcserére szolgál.

AfterRunAsync: Ez a metódus az utolsó hívás, mielőtt kilép a int ITestApplication.RunAsync()-ből, és ellátja a exit code-t. Kizárólag tisztítási feladatokhoz használható, és a megfelelő folyamaton kívüli bővítmény értesítésére, hogy a tesztgazda hamarosan leáll.

Végül mindkét API fogad egy CancellationToken-t, amelyet a bővítmény várhatóan figyelembe vesz.

A IDataConsumer bővítmények

Ez IDataConsumer egy folyamatban lévő bővítmény, amely a IData és annak bővítményei által az IMessageBus számára közzétett információkra tud feliratkozni és fogadni.

Ez a bővítménypont kulcsfontosságú, mivel lehetővé teszi a fejlesztők számára, hogy összegyűjtsék és feldolgozzák a tesztelési munkamenet során létrehozott összes információt.

Egyéni IDataConsumerregisztrálásához használja a következő api-t:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

builder.TestHost.AddDataConsumer(
    static serviceProvider => new CustomDataConsumer());

A gyár az IServiceProvider használja a tesztelési platform által kínált szolgáltatásokhoz való hozzáféréshez.

Fontos

A regisztráció sorrendje jelentős, mivel az API-k a regisztráció sorrendjében vannak meghívva.

A IDataConsumer felület a következő módszereket tartalmazza:

public interface IDataConsumer : IExtension
{
    Type[] DataTypesConsumed { get; }

    Task ConsumeAsync(
        IDataProducer dataProducer,
        IData value,
        CancellationToken cancellationToken);
}

public interface IData
{
    string DisplayName { get; }
    string? Description { get; }
}

Fontos

Az MTP 2.0.0-ban a IDataConsumer átkerült a Microsoft.Testing.Platform.Extensions névtérbe, és most már közvetlenül a IExtension elemet terjeszti ki. Az MTP 1.x verzióban ez kiterjedt a következőre: ITestHostExtension. Továbbra is ezzel regisztrálja: builder.TestHost.AddDataConsumer(...). További információkért lásd: Migrálás a Microsoft.Testing.Platform (MTP) v1-ről v2-re.

A(z) IDataConsumer a(z) IExtension felületből öröklődik. Ezért, mint minden más bővítmény, engedélyezheti vagy letilthatja a IExtension.IsEnabledAsync API-val.

DataTypesConsumed: Ez a tulajdonság a bővítmény által használni kívánt Type listáját adja vissza. Ez a IDataProducer.DataTypesProducedfelel meg. Figyelemre méltó módon egy IDataConsumer probléma nélkül előfizethet több különböző IDataProducer-példányból származó típusra is.

ConsumeAsync: Ez a metódus akkor hívódik meg, amikor a IMessageBus olyan típusú adatokat tesznek közzé, amelyre az aktuális fogyasztó feliratkozott. Megkapja a IDataProducer-t, hogy részleteket nyújtson a hasznos adat gyártójáról, valamint magáról a IData hasznos adatról is. Mint látható, a IData egy általános helyőrző felület, amely általános informatív adatokat tartalmaz. A különböző típusú IData közzétételi képesség azt jelenti, hogy a fogyasztónak magát a típust kell bekapcsolnia ahhoz, hogy a megfelelő típusra váltson, és hozzáférjen a konkrét információkhoz.

Fontos

Az üzenetbusz nem hív meg IDataConsumer egy IDataProducer adataihoz, amelynek IExtension.Uid megegyezik a fogyasztó IExtension.Uid-jával. Ha egy bővítmény közzéteszi és feliratkozik az üzenetbusz adataira, rendeljen hozzá különböző felhasználói azonosítókat a gyártói és fogyasztói regisztrációkhoz. A bővítmény által előállított adatok feldolgozásához hívja meg közvetlenül a feldolgozási logikát az adatok üzenetsínen keresztüli átirányítása helyett.

Egy fogyasztó mintája, amely ki szeretné dolgozni a TestNodeUpdateMessage által előállított -t, a következő lehet:

internal class CustomDataConsumer : IDataConsumer, IOutputDeviceDataProducer
{
    public Type[] DataTypesConsumed => new[] { typeof(TestNodeUpdateMessage) };
    ...
    public Task ConsumeAsync(
        IDataProducer dataProducer,
        IData value,
        CancellationToken cancellationToken)
    {
        var testNodeUpdateMessage = (TestNodeUpdateMessage)value;

        switch (testNodeUpdateMessage.TestNode.Properties.Single<TestNodeStateProperty>())
        {
            case InProgressTestNodeStateProperty _:
                {
                    ...
                    break;
                }
            case PassedTestNodeStateProperty _:
                {
                    ...
                    break;
                }
            case FailedTestNodeStateProperty failedTestNodeStateProperty:
                {
                    ...
                    break;
                }
            case SkippedTestNodeStateProperty _:
                {
                    ...
                    break;
                }
            ...
        }

        return Task.CompletedTask;
    }
...
}

Végül az API egy CancellationToken paramétert vesz át, amit a bővítmény várhatóan betart.

Fontos

A hasznos adatokat közvetlenül a ConsumeAsync metóduson belül dolgozza fel. Egy hagyományos IDataConsumer aszinkron módon dolgozza fel az adatokat: az IMessageBus minden közzétett adatcsomagot várólistára tesz, és egy háttérben futó ciklusban dolgozza fel, így IMessageBus.PublishAsync nem akadályozza az előállítót, és nincs garancia arra, hogy ConsumeAsync mikor fut le ahhoz képest, hogy az előállító folytatja a munkáját. A platform szerializálja a kézbesítést, hogy fogyasztónként egyszerre csak egy hasznos adat legyen feldolgozva, ami szükségtelenné teszi az összetett szinkronizálást egyetlen fogyasztón belül.

Jegyzet

Az olyan forgatókönyvek esetében, amelyeknél garantálni kell, hogy a fogyasztás a gyártó folytatása előtt történik (például a teszt futtatása előtt), az MTP 2.3.0 bevezette a kísérleti IBlockingDataConsumer jelölőfelületet (a TPEXP diagnosztika mellőzését igényli). A IBlockingDataConsumer felületet szintén megvalósító fogyasztót az üzenetbusz inline hívja meg: a hívások szerializáltak, PublishAsync blokkol, amíg ConsumeAsync be nem fejeződik, és a ConsumeAsync által dobott bármely kivétel visszaterjed az adatokat közzétevő előállítóhoz. Az üzenetbusz nem kézbesíti vissza a közzétevő adatait ugyanannak a közzétevőnek (azonos UID esetén), így a saját UID alatt történő közzététel biztonságos. A blokkoló fogyasztónak azonban belülről ConsumeAsyncnem szabad olyan adatokat közzétennie, amelyeket egy másik gyártó UID-azonosítója alapján irányít vissza magára, mert az újraküldés holtpontot jelentene.

Figyelmeztetés

Ha az IDataConsumer együtt használ egy összetett bővítményponton belül, elengedhetetlen, hogy figyelmen kívül hagyja az ITestSessionLifetimeHandler.OnTestSessionFinishingAsync végrehajtása után kapott adatokat. A OnTestSessionFinishingAsync az utolsó lehetőség a felhalmozott adatok feldolgozására és új információk továbbítására az IMessageBus, ezért az ezen a ponton túl felhasznált adatok nem lesznek a bővítmény által használható.

Ha a bővítmény intenzív inicializálást igényel, és az aszinkron/várakozási mintát kell használnia, tekintse meg a Async extension initialization and cleanup. Ha meg kell osztania az állapot a bővítménypontok között, tekintse meg a CompositeExtensionFactory<T> szakaszt.

Üzenetbusz fájlösszetevői

Az egyéni IData adattartalomhoz nem tartozik automatikus felhasználói felület vagy parancssori kimenet. A platform csak azokat az adatokat jeleníti meg, amelyekhez egy megfelelő fogyasztó regisztrálva van, így ha saját IData típust tesz közzé, és semmit nem használ fel, semmit sem nyomtat vagy továbbít. Ha a bővítmény által létrehozott fájlokat láthatóvá szeretné tenni a felhasználók és az eszközök számára, tegye közzé az egyik beépített fájlösszetevő-üzenetet, amelyet a beépített terminál - és dotnet-tesztfelhasználók már felismernek.

Futtatásszintű vagy munkamenet-szintű fájlok esetén tegyen közzé egy FileArtifact vagy egy SessionFileArtifact fájlt. Mindkettő az MTP 1.0.0-s kiadásában lett bevezetve, és a Microsoft.Testing.Platform.Extensions.Messages névtérben él:

  • FileArtifact nincs hatóköre. Olyan fájlhoz használja, amely nincs egy adott teszt munkamenethez kötve.
  • SessionFileArtifact a SessionUid révén egy futtatásra/munkamenetre korlátozódik. Használja ezt a teljes futtatás során keletkezett elemekhez, például lefedettségi eredményekhez, jelentésekhez, kiíratásokhoz vagy rögzített videókhoz.

A beépített terminál és a dotnet test fogyasztói mindkét típust felismerik, és kinyomtatják vagy továbbítják a fájlok elérési útját, így a fájlok láthatóvá válnak a konzolkimenetben és a dotnet test pipe-on keresztül. Mivel a fogyasztók szabályozzák a végső megjelenítést, minden fájlt tartson a lemezen és elérhető állapotban addig, amíg azt még megjeleníthetik vagy továbbíthatják; ne törölje azt ugyanazon a PublishAsync híváson belül.

Maga az artifaktumobjektum nem tartalmazza a létrehozó kilétét. Az üzenetbusz minden fogyasztó számára a IDataProducerdataProducer argumentumán keresztül adja át a forrást létrehozó IDataConsumer.ConsumeAsync elemet, így a fogyasztók ebből az argumentumból tudják meg, ki állított elő egy fájlt, nem pedig a műtermékből. Az üzenetbusz nem veszi át a hivatkozott fájl tulajdonjogát, áthelyezését vagy törlését sem: a gyártó a fájl élettartamának tulajdonosa, a fogyasztók pedig csak a fájl elérési útját fogadják, olvassák vagy továbbítják.

Jegyzet

A harmadik fél IDataConsumer regisztrációja csak a builder.TestHost (a folyamaton belüli tesztgazdán) nyilvános. Nincs nyilvános builder.TestHostControllers.AddDataConsumer API a folyamaton kívüli felhasználók számára. Az összetevőket megjelenítő belső jelentésbővítmények olyan belső platformintegrációt használnak, amelyre az egyéni bővítmények nem támaszkodhatnak. A fájlok saját bővítményből való felszínre hozásához tegye közzé az itt ismertetett beépített összetevőüzeneteket, és engedje meg, hogy a beépített felhasználók bemutatják őket.

A munkamenet-artefaktumot közzétevő előállítónak implementálnia kell a IDataProducer elemet, és a DataTypesProduced elemben fel kell sorolnia az általa közzétett pontos futásidejű üzenettípusokat. Az alábbi példa egy lefedettségi jelentést tesz közzé a munkamenet befejezésekor:

internal sealed class CoverageReportProducer(IMessageBus messageBus)
    : IDataProducer, ITestSessionLifetimeHandler
{
    public string Uid => nameof(CoverageReportProducer);
    public string Version => "1.0.0";
    public string DisplayName => "Coverage report producer";
    public string Description => "Publishes the coverage report as a session artifact.";

    // List the exact runtime message types this producer publishes.
    public Type[] DataTypesProduced => new[] { typeof(SessionFileArtifact) };

    public Task<bool> IsEnabledAsync() => Task.FromResult(true);

    public Task OnTestSessionStartingAsync(ITestSessionContext context)
        => Task.CompletedTask;

    public Task OnTestSessionFinishingAsync(ITestSessionContext context)
    {
        var report = new FileInfo("coverage.cobertura.xml");
        return messageBus.PublishAsync(
            this,
            new SessionFileArtifact(
                context.SessionUid,
                report,
                "Code coverage",
                "Cobertura coverage report for the run."));
    }
}

Ha egy fájlt egy adott teszthez szeretne csatolni, hogy a terminál, dotnet test és az IDE-k az adott teszthez társítsák, és annál jelenítsék meg, ne tegyen közzé önálló fájl-artefaktumot. Ehelyett adjon hozzá egy vagy több FileArtifactProperty bejegyzést ahhoz a TestNode-hez, amelyet a tesztelési keretrendszer egy TestNodeUpdateMessage segítségével jelent. FileArtifactProperty az MTP 1.7.0-s kiadásában jelent meg:

var testNode = new TestNode
{
    Uid = testUid,
    DisplayName = testDisplayName,
    Properties = new PropertyBag(
        PassedTestNodeStateProperty.CachedInstance,
        new FileArtifactProperty(
            new FileInfo("screenshot.png"),
            "Failure screenshot",
            "Screenshot captured while the test ran.")),
};

await messageBus.PublishAsync(
    dataProducer,
    new TestNodeUpdateMessage(sessionUid, testNode));

Fontos

TestNodeFileArtifact elavult, és az MTP 2.0.0-s módban el lett távolítva. A tesztszintű fájlok csatolásához használja a(z) FileArtifactProperty elemet a(z) TestNode oldalon. További információkért lásd: Migrálás a Microsoft.Testing.Platform (MTP) v1-ről v2-re.

Jegyzet

Az MTP 2.4.0-s verziója (2026 augusztusáig még nem jelent meg) egy kísérleti kind konstruktor-túlterhelést és egy Kind tulajdonságot ad hozzá a(z) FileArtifact és SessionFileArtifact elemekhez (ehhez el kell nyomni a(z) TPEXP diagnosztikát). Kind a gyártó által érvényesített, fordított DNS-azonosító az összetevő formátumának (például microsoft.testing.trx, , microsoft.testing.junit, microsoft.testing.ctrfvagy microsoft.testing.html) az utófeldolgozás során használt, azonos formátumú összetevők csoportosítására. Hagyja így: null, vagy hagyja ki, ha a gyártó nem ad meg ismert típust.

#pragma warning disable TPEXP // Experimental API.
new SessionFileArtifact(
    context.SessionUid,
    trxFile,
    "TRX report",
    "Test results in TRX format.",
    kind: "microsoft.testing.trx");
#pragma warning restore TPEXP

A IArtifactPostProcessor bővítmények

Az MTP 2.4.0-tól kezdve a kísérleti IArtifactPostProcessor bővítménypont feldolgozza az összetevőket, miután egy dotnet test meghívás több tesztmodult futtat, vagy egy újrapróbálkozást követően több kísérletet futtat. Az ArtifactPostProcessingMode érték azt határozza meg, hogy a processzor kezeli-e TestModules vagy RetryAttemptsa .

A beépített TRX-, JUnit-, CTRF- és HTML-jelentésbővítmények ezt a bővítménypontot használják a kapcsolódó jelentésösszetevők összevonására egy merged címtárban. A HTML-összevonás egyesített összegzést hoz létre, és megőrzi az eredeti folyamatonkénti jelentéseket. Ha tudni szeretné, hogyan befolyásolja a jelentéskonszolidáció a tesztkimenetet, tekintse meg a jelentéskonszolidációt.

A ITestHostEnvironmentVariableProvider bővítmények

A ITestHostEnvironmentVariableProvider egy folyamaton kívüli bővítmény, amely lehetővé teszi egyéni környezeti változók létrehozását a tesztgazda számára. A bővítménypont használata biztosítja, hogy a tesztelési platform új hosztot indítson a megfelelő környezeti változókkal, ahogy az az architektúra szakaszban részletezve van.

Egyéni ITestHostEnvironmentVariableProviderregisztrálásához használja a következő API-t:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

builder.TestHostControllers.AddEnvironmentVariableProvider(
    static serviceProvider => new CustomEnvironmentVariableForTestHost());

A gyár az IServiceProvider használja a tesztelési platform által kínált szolgáltatásokhoz való hozzáféréshez.

Fontos

A regisztráció sorrendje jelentős, mivel az API-k a regisztráció sorrendjében vannak meghívva.

A ITestHostEnvironmentVariableProvider felület a következő módszereket és típusokat tartalmazza:

public interface ITestHostEnvironmentVariableProvider : ITestHostControllersExtension, IExtension
{
    Task UpdateAsync(IEnvironmentVariables environmentVariables);

    Task<ValidationResult> ValidateTestHostEnvironmentVariablesAsync(
        IReadOnlyEnvironmentVariables environmentVariables);
}

public interface IEnvironmentVariables : IReadOnlyEnvironmentVariables
{
    void SetVariable(EnvironmentVariable environmentVariable);
    void RemoveVariable(string variable);
}

public interface IReadOnlyEnvironmentVariables
{
    bool TryGetVariable(
        string variable,
        [NotNullWhen(true)] out OwnedEnvironmentVariable? environmentVariable);
}

public sealed class OwnedEnvironmentVariable : EnvironmentVariable
{
    public IExtension Owner { get; }

    public OwnedEnvironmentVariable(
        IExtension owner,
        string variable,
        string? value,
        bool isSecret,
        bool isLocked);
}

public class EnvironmentVariable
{
    public string Variable { get; }
    public string? Value { get; }
    public bool IsSecret { get; }
    public bool IsLocked { get; }
}

A ITestHostEnvironmentVariableProvider egy ITestHostControllersExtensiontípusa, amely az összes tesztgazdavezérlő bővítmény alapjaként szolgál. Az összes többi bővítményponthoz hasonlóan ez is örökli a IExtension-t. Ezért, mint minden más bővítmény, engedélyezheti vagy letilthatja a IExtension.IsEnabledAsync API-val.

Tekintse át az API részleteit:

UpdateAsync: Ez a frissítési API a IEnvironmentVariables objektum egy példányát biztosítja, amelyből meghívhatja a SetVariable vagy RemoveVariable metódusokat. A SetVariablehasználatakor egy EnvironmentVariabletípusú objektumot kell átadnia, amelyhez a következő specifikációk szükségesek:

  • Variable: A környezeti változó neve.
  • Value: A környezeti változó értéke.
  • IsSecret: Ez azt jelzi, hogy a környezeti változó olyan bizalmas információkat tartalmaz-e, amelyeket nem szabad naplózni vagy elérni a TryGetVariable.
  • IsLocked: Ez határozza meg, hogy más ITestHostEnvironmentVariableProvider bővítmények módosíthatják-e ezt az értéket.

ValidateTestHostEnvironmentVariablesAsync: Ezt a metódust a rendszer a regisztrált UpdateAsync példányok összes ITestHostEnvironmentVariableProvider metódusának meghívása után hívja meg. Lehetővé teszi, hogy ellenőrizze a környezeti változók helyes beállítását. Olyan objektumot használ, amely implementálja a IReadOnlyEnvironmentVariables, amely a TryGetVariable metódust biztosítja adott környezeti változók adatainak lekéréséhez az OwnedEnvironmentVariable objektumtípussal. Az ellenőrzés után visszaad egy ValidationResult-t, amely tartalmazza az esetleges hibák okait.

Jegyzet

A tesztelési platform alapértelmezés szerint implementálja és regisztrálja a SystemEnvironmentVariableProvider. Ez a szolgáltató betölti az összes jelenlegi környezeti változót. Első regisztrált szolgáltatóként először végrehajtja, és hozzáférést biztosít az összes többi ITestHostEnvironmentVariableProvider felhasználói bővítmény alapértelmezett környezeti változóihoz.

Ha a bővítmény intenzív inicializálást igényel, és az aszinkron/várakozási mintát kell használnia, tekintse meg a Async extension initialization and cleanup. Ha meg kell osztania az állapot a bővítménypontok között, tekintse meg a CompositeExtensionFactory<T> szakaszt.

A ITestHostProcessLifetimeHandler bővítmények

A ITestHostProcessLifetimeHandler egy folyamaton kívüli bővítmény, amely lehetővé teszi a tesztgazdafolyamat külső szempontból történő megfigyelését. Ez biztosítja, hogy a bővítményt ne érintik a tesztelés alatt álló kód által kiváltott esetleges összeomlások vagy lefagyások. Ha ezt a bővítménypontot használja, a tesztelési platform új gazdagépet indít el, ahogyan az a architektúra szakaszában részletezve van.

Egyéni ITestHostProcessLifetimeHandlerregisztrálásához használja a következő API-t:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

builder.TestHostControllers.AddProcessLifetimeHandler(
    static serviceProvider => new CustomMonitorTestHost());

A gyár az IServiceProvider használja a tesztelési platform által kínált szolgáltatásokhoz való hozzáféréshez.

Fontos

A regisztráció sorrendje jelentős, mivel az API-k a regisztráció sorrendjében vannak meghívva.

A ITestHostProcessLifetimeHandler felület a következő módszereket tartalmazza:

public interface ITestHostProcessLifetimeHandler : ITestHostControllersExtension
{
    Task BeforeTestHostProcessStartAsync(CancellationToken cancellationToken);

    Task OnTestHostProcessStartedAsync(
        ITestHostProcessInformation testHostProcessInformation,
        CancellationToken cancellation);

    Task OnTestHostProcessExitedAsync(
        ITestHostProcessInformation testHostProcessInformation,
        CancellationToken cancellation);
}

public interface ITestHostProcessInformation
{
    int PID { get; }
    int ExitCode { get; }
    bool HasExitedGracefully { get; }
}

A ITestHostProcessLifetimeHandler egy ITestHostControllersExtensiontípusa, amely az összes tesztgazdavezérlő bővítmény alapjaként szolgál. Az összes többi bővítményponthoz hasonlóan ez is örökli a IExtension-t. Ezért, mint minden más bővítmény, engedélyezheti vagy letilthatja a IExtension.IsEnabledAsync API-val.

Vegye figyelembe az API következő részleteit:

BeforeTestHostProcessStartAsync: Ezt a metódust a tesztelési platform a tesztgazdagépek elindítása előtt hívja meg.

OnTestHostProcessStartedAsync: Ezt a metódust közvetlenül a tesztgazda elindulása után hívják meg. Ez a metódus egy objektumot kínál, amely implementálja a ITestHostProcessInformation felületet, amely a tesztgazdafolyamat eredményének legfontosabb részleteit tartalmazza.

Fontos

A metódus meghívása nem akadályozza meg a tesztgazda végrehajtását. Ha szüneteltetnie kell, regisztrálnia kell egy folyamaton belüli bővítményt, például ITestHostApplicationLifetime, és szinkronizálnia kell azt a folyamaton kívüli bővítménnyel.

OnTestHostProcessExitedAsync: Ezt a metódust akkor hívja meg a program, ha a tesztcsomag végrehajtása befejeződött. Ez a módszer egy olyan objektumot biztosít, amely megfelel a ITestHostProcessInformation interfésznek, amely a tesztgazdafolyamat eredményével kapcsolatos fontos részleteket közvetít.

A ITestHostProcessInformation felület a következő részleteket tartalmazza:

  • PID: A tesztgazda folyamatazonosítója.
  • ExitCode: A folyamat kilépési kódja. Ez az érték csak a OnTestHostProcessExitedAsync metóduson belül érhető el. A OnTestHostProcessStartedAsync metóduson belüli elérésének megkísérlése kivételt eredményez.
  • HasExitedGracefully: Logikai érték, amely jelzi, hogy a tesztgazda összeomlott-e. Ha igaz, az azt jelzi, hogy a teszt gazdagép nem lépett ki zavartalanul.

Regisztrálja automatikusan a bővítményét a(z) TestingPlatformBuilderHook segítségével

Minden előző bővítményszakaszban manuális regisztrációs hívás látható (például builder.TestHost.AddDataConsumer(...)). A felhasználók felkérése arra, hogy szerkesszék a Main metódusukat, rossz bevezetési élményt nyújt. A Microsoft.Testing.Platform.MSBuild csomag ezt úgy oldja meg, hogy létrehoz egy SelfRegisteredExtensions.AddSelfRegisteredExtensions(builder, args) metódust, amely az automatikusan létrehozott belépési pontból fut. Ha a bővítményt a létrehozott metódushoz szeretné csatlakoztatni, szállítson két összetevőt a NuGet-csomagba:

  • Nyilvános statikus TestingPlatformBuilderHook osztály egy AddExtensions metódussal, amely regisztrálja a bővítményét.
  • Egy MSBuild props fájl, amely deklarál egy <TestingPlatformBuilderHook> elemet, amely az adott osztályra mutat.

Amikor egy felhasználó telepíti a csomagodat, az MSBuild-integráció felismeri ezt az elemet, és legenerálja a hookodhoz tartozó hívást, a bővítményed pedig a felhasználói oldalon szükséges kódmódosítás nélkül regisztrálódik.

Jegyzet

Az automatikus regisztráció csak akkor működik, ha a projekt tartalmazza a(z) Microsoft.Testing.Platform.MSBuild elemet (ezt az MSTest-, NUnit- és xUnit-futtatók tranzitívan tartalmazzák), és nem tiltotta le a(z) <GenerateTestingPlatformEntryPoint>false</GenerateTestingPlatformEntryPoint> beállításával. Az automatikusan létrehozott belépési pontot letiltó felhasználóknak továbbra is meg kell hívniuk a manuális regisztrációs API-t a módszerükből Main .

A hook osztály létrehozása

Adjon hozzá egy public static class TestingPlatformBuilderHook elemet a bővítmény-összeállításában, amely egy AddExtensions(ITestApplicationBuilder, string[]) metódust tartalmaz, és ugyanazt a regisztrációt végzi el, amelyet a felhasználóknak egyébként manuálisan kellene meghívniuk:

using Microsoft.Testing.Platform.Builder;

namespace Contoso.MyExtension;

public static class TestingPlatformBuilderHook
{
    public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] arguments)
        => testApplicationBuilder.AddMyExtension();
}

Az osztály nevének nem kell TestingPlatformBuilderHook-nak lennie – az MSBuild-elem a teljes típusnév alapján hivatkozik rá –, de ennek a névnek a használatával a kód egységes marad az olyan beépített bővítményekkel, mint a Microsoft.Testing.Extensions.Retry és a Microsoft.Testing.Extensions.HotReload.

A metódusnak a következőnek kell lennie:

  • Legyen public static.
  • Az első Microsoft.Testing.Platform.Builder.ITestApplicationBuilder típusú paraméterrel rendelkezik.
  • Legyen egy második típusú string[] paramétere (a tesztgazda számára átadott parancssori argumentumok). Figyelmen kívül hagyhatja, ha a bővítménynek nincs rá szüksége.
  • Vissza void.

Az MSBuild elem deklarálása

Helyezzen el egy props-fájlt a NuGet-csomagban a(z) buildMultiTargeting/<PackageId>.props alatt. Deklaráljon egy <TestingPlatformBuilderHook> elemet, amely az MSBuild-feladatot a hook osztályra irányítja:

<Project>
  <ItemGroup>
    <TestingPlatformBuilderHook Include="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx">
      <DisplayName>Contoso.MyExtension</DisplayName>
      <TypeFullName>Contoso.MyExtension.TestingPlatformBuilderHook</TypeFullName>
    </TestingPlatformBuilderHook>
  </ItemGroup>
</Project>

A metaadatok a következők:

  • Include: Egy GUID, amely egyedileg azonosítja a hookot. Lásd : A Include GUID egy véletlenszerű azonosító.
  • DisplayName: Az a felhasználóbarát név, amely az MSBuild diagnosztikai üzeneteiben jelenik meg a belépési pont létrehozásakor. Használja a csomag vagy a bővítmény nevét.
  • TypeFullName: A korábban létrehozott TestingPlatformBuilderHook osztály teljesen minősített neve. Az MSBuild-feladat ezt használja arra, hogy a(z) global::Contoso.MyExtension.TestingPlatformBuilderHook.AddExtensions(builder, args); elemet beillessze a létrehozott belépési pontba.

A Include GUID egy véletlenszerű azonosító

Az attribútum GUID Include azonosítója nem ugyanaz, mint a bővítményé IExtension.Uid. Ez egy regisztrációs azonosító, amelyet az MSBuild-feladat arra használ, hogy kiszűrje a hookok ismétlődéseit a NuGet-hivatkozások között, és néhány jól ismert esetben meghatározza a sorrendjüket.

Amikor új bővítményt készít, hozzon létre egy vadonatúj GUID-ot, és írja be fixen a props-fájlba. Néhány módszer a létrehozásra:

  • Powershell: [guid]::NewGuid()
  • Visual Studio: Eszközök>GUID létrehozása
  • uuidgen Linux és macOS rendszeren

Fontos

Soha ne másoljon GUID-t egy másik bővítmény kellékfájljából (függetlenül attól, hogy Microsoft vagy harmadik fél szállítja). Az azonos Include értékkel rendelkező két bővítményt a rendszer duplikátumnak tekinti: csak az egyik hook hívódik meg, ezért a bővítmény hibaüzenet nélkül nem regisztrálódik.

Jegyzet

Ha egyszer kiadott egy GUID-ot, tekintse véglegesnek. A későbbi kiadásban való módosítás önmagában ártalmatlan, de ha egy későbbi csomagverzióban egy másik horog régi értékét használja fel, az összezavarhatja azokat a felhasználókat, akik mindkét verziót a függőségi gráfjukban használják a frissítés során.

Ellenőrizze, hogy a horog be van-e kötve

Miután telepítette a csomagot egy Microsoft.Testing.Platform.MSBuild használó tesztprojektben, hozza létre a projektet, és vizsgálja meg a létrehozott SelfRegisteredExtensions.g.cs fájlt a obj/<Configuration>/<TargetFramework>/ alatt. Látnod kell a hookod meghívását, például:

public static void AddSelfRegisteredExtensions(this global::Microsoft.Testing.Platform.Builder.ITestApplicationBuilder builder, string[] args)
{
    global::Contoso.MyExtension.TestingPlatformBuilderHook.AddExtensions(builder, args);
}

Ha a hívás hiányzik, ellenőrizze újra, hogy a props-fájl a buildMultiTargeting/ belsejében a build/ alatt van-e csomagolva (nem a .nupkg alatt), hogy a DisplayName és TypeFullName metaadatok jelen vannak-e, és hogy a felhasználó nem állította-e be a <GenerateTestingPlatformEntryPoint>false</GenerateTestingPlatformEntryPoint> beállítást.

Bővítmények dinamikus betöltése

Az MTP 2.4.0-s verziójától kezdve a tesztalkalmazás mellett található *.testingplatformextensions.json manifestfájlokban deklarált bővítmények betöltéséhez adja át a(z) --enable-dynamic-extensions paramétert. Az MTP nem keres tetszőleges szerelvényeket, és a dinamikus betöltés letiltva marad, kivéve, ha minden futtatás kifejezetten engedélyezi azt.

A jegyzék minden bejegyzése egy szerelvényegységet és egy meghívandó TestingPlatformBuilderHook típust azonosít. Az MTP a terminálkimenetben felsorolja az összes betöltött bővítményt, és meghiúsítja a futtatást, ha egy manifesztfájl, szerelvény, típus vagy hook érvénytelen. Állítsa egy bejegyzés enabled tulajdonságát false értékre, hogy letiltsa azt a manifestum törlése nélkül.

Figyelmeztetés

A dinamikusan betöltött bővítmények teljes megbízhatósággal futnak a tesztelési folyamaton belül. Csak megbízható könyvtárakból és forrásokból származó jegyzékfájlokat és szerelvényeket használjon.

A teljes jegyzékszerződéshez tekintse meg a bővítményjegyzék JSON-sémáját és a dinamikus bővítménybetöltési tervet.

Bővítmények végrehajtási sorrendje

A tesztelési platform egy tesztelési keretrendszerből áll, és tetszőleges számú, folyamaton belül vagy folyamaton kívülműködő bővítményből. Ez a dokumentum a hívássorozatot ismerteti az összes lehetséges bővíthetőségi pont számára annak érdekében, hogy világos legyen, mikor várható egy funkció meghívása.

  1. ITestHostEnvironmentVariableProvider.UpdateAsync: Folyamaton kívüli
  2. ITestHostEnvironmentVariableProvider.ValidateTestHostEnvironmentVariablesAsync: Folyamaton kívüli
  3. ITestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync: Folyamaton kívüli
  4. A tesztgazdagép folyamatának indítása
  5. ITestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync: A folyamaton kívüli esemény a versenyfeltételek függvényében összefonhatja bővítmények műveleteit.
  6. ITestHostApplicationLifetime.BeforeRunAsync: Folyamatban
  7. ITestSessionLifetimeHandler.OnTestSessionStartingAsync: Folyamatban van
  8. ITestFramework.CreateTestSessionAsync: Folyamatban van.
  9. ITestFramework.ExecuteRequestAsync: A folyamatban lévő metódus egy vagy több alkalommal hívható meg. Ezen a ponton a tesztelési keretrendszer adatokat továbbít a IMessageBus, amelyeket az IDataConsumerhasználhat fel.
  10. ITestFramework.CloseTestSessionAsync: Folyamatban lévő folyamat
  11. ITestSessionLifetimeHandler.OnTestSessionFinishingAsync: Folyamatban
  12. ITestHostApplicationLifetime.AfterRunAsync: Folyamatban
  13. A folyamaton belüli törlés magában foglalja a törlés meghívását és az IAsyncCleanableExtension az összes bővítményponton.
  14. ITestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync: Folyamaton kívüli
  15. A folyamaton kívüli törlés magában foglalja a dispose meghívását és az IAsyncCleanableExtension függvényt minden bővítményponton.

Kiterjesztések segítői

A tesztelési platform számos segédosztályt és felületet biztosít a bővítmények implementálásának egyszerűsítése érdekében. Ezek a segítők úgy lettek kialakítva, hogy egyszerűsítsék a fejlesztési folyamatot, és biztosítsák, hogy a bővítmény megfeleljen a platform szabványainak.

Bővítmények aszinkron inicializálása és törlése

A tesztelési keretrendszer és a bővítmények gyárakon keresztüli létrehozása megfelel a szabványos .NET objektumlétrehozási mechanizmusnak, amely szinkron konstruktorokat használ. Ha egy bővítmény intenzív inicializálást igényel (például a fájlrendszerhez vagy a hálózathoz való hozzáférést), akkor nem tudja alkalmazni a aszinkron/várakozási mintát a konstruktorban, mert a konstruktorok üresek, nem Task.

Ezért a tesztelési platform egy módszert biztosít egy bővítmény inicializálására az aszinkron/várakozási mintával egy egyszerű felületen keresztül. A szimmetria érdekében aszinkron felületet is kínál a tisztításhoz, amelyet a bővítmények zökkenőmentesen implementálhatnak.

public interface IAsyncInitializableExtension
{
    Task InitializeAsync();
}

public interface IAsyncCleanableExtension
{
    Task CleanupAsync();
}

IAsyncInitializableExtension.InitializeAsync: Ez a metódus biztosan meg lesz hívva a gyári létrehozás után.

IAsyncCleanableExtension.CleanupAsync: Ez a módszer a tesztelési munkamenet befejezésekor legalább egyszer az alapértelmezett DisposeAsync vagy Disposeelőtt hívható meg.

Fontos

A standard Dispose metódushoz hasonlóan a CleanupAsync többször is meghívható. Ha egy objektum CleanupAsync metódusa többször van meghívva, az objektumnak figyelmen kívül kell hagynia az első utáni összes hívást. Az objektum nem hozhat kivételt, ha a CleanupAsync metódust többször is meghívják.

Jegyzet

Alapértelmezés szerint a tesztelési platform meghívja DisposeAsync, ha elérhető, vagy Dispose, ha implementálva van. Fontos megjegyezni, hogy a tesztelési platform nem hívja meg mindkét megsemmisítési metódust, de a implementáláskor rangsorolja az aszinkront.

A CompositeExtensionFactory<T>

A bővítmények szakaszban leírtaknak megfelelően a tesztelési platform lehetővé teszi, hogy olyan interfészeket implementáljon, amelyek egyéni bővítményeket tartalmaznak mind folyamaton belül, mind azon kívül.

Minden felület egy adott funkcióval foglalkozik, és .NET kialakításnak megfelelően ezt az interfészt egy adott objektumban valósítja meg. A bővítményt az adott regisztrációs API-AddXXX használatával regisztrálhatja a TestHost vagy TestHostController objektumból származó ITestApplicationBuilder-ból a megfelelő szakaszokban részletezett módon.

Ha azonban meg kell osztania az állapot két bővítmény között, az a tény, hogy különböző interfészeket implementáló különböző objektumokat implementálhat és regisztrálhat, kihívást jelentő feladattá teszi a megosztást. Segítség nélkül szüksége lenne arra, hogy az egyik bővítményt átadhassa a másiknak az információk megosztásához, ami bonyolítja a kialakítást.

Ezért a tesztelési platform kifinomult módszert kínál több bővítménypont azonos típusú implementálásához, így az adatmegosztás egyszerű feladat. Mindössze annyit kell tennie, hogy a CompositeExtensionFactory<T>-t használja, amelyet aztán ugyanazzal az API-val lehet regisztrálni, mint egy felület implementációjához.

Vegyük például azt a típust, amely ITestSessionLifetimeHandler és IDataConsumeris implementál. Ez egy gyakori forgatókönyv, mert gyakran szeretne adatokat gyűjteni a tesztelési keretrendszerből, majd amikor a tesztelési munkamenet befejeződik, az összetevőt a IMessageBusITestSessionLifetimeHandler.OnTestSessionFinishingAsync használatával küldi el.

A felületeket általában a következő módon kell implementálni:

internal class CustomExtension : ITestSessionLifetimeHandler, IDataConsumer, ...
{
   ...
}

Miután létrehozta a típusához tartozó CompositeExtensionFactory<CustomExtension>-t, regisztrálhatja azt a IDataConsumer- és ITestSessionLifetimeHandler-API-kkal is, amelyek túlterhelési lehetőséget kínálnak a CompositeExtensionFactory<T>számára.

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

var factory = new CompositeExtensionFactory<CustomExtension>(serviceProvider => new CustomExtension());

builder.TestHost.AddTestSessionLifetimeHandle(factory);
builder.TestHost.AddDataConsumer(factory);

A gyári konstruktor az IServiceProvider használja a tesztelési platform által biztosított szolgáltatások elérésére.

Az összetett bővítmény életciklusának kezeléséért a tesztelési platform felel.

Fontos megjegyezni, hogy mivel a tesztelési platform támogatja a folyamatban lévő és folyamaton kívüli bővítményeket, nem kombinálhat tetszőlegesen egy bővítménypontot sem. A bővítmények létrehozása és használata a gazdagép típusán múlik, ami azt jelenti, hogy csak folyamaton belüli (TestHost) és folyamaton kívüli (TestHostController) bővítményeket lehet együtt csoportosítani.

A következő kombinációk lehetségesek:

  • A ITestApplicationBuilder.TestHostesetében a IDataConsumer és ITestSessionLifetimeHandlerkombinálhatók össze.
  • A ITestApplicationBuilder.TestHostControllersesetében a ITestHostEnvironmentVariableProvider és ITestHostProcessLifetimeHandlerkombinálhatók össze.

Jegyzet

IDataConsumer egy folyamaton belüli bővítmény, így az egyéni fogyasztók csak builder.TestHost útján regisztrálhatók (beleértve a CompositeExtensionFactory<T> használatát is). Nincs nyilvános API egy IDataConsumer regisztrálására a(z) builder.TestHostControllers-on.