Sdílet prostřednictvím


Vytvářet rozšíření pro Microsoft.Testing.Platform

Tento článek popisuje body rozšiřitelnosti pro Microsoft.Testing.Platform nad rámec samotné testovací architektury. Vytvoření testovací architektury najdete v tématu Sestavení testovací architektury.

Úplný souhrn bodů rozšíření a koncepty in-process/out-of-process najdete v tématu Vytváření vlastních rozšíření.

Konkrétní body rozšiřitelnosti

Testovací platforma poskytuje další body rozšiřitelnosti, které umožňují přizpůsobit chování platformy a testovací architektury. Tyto body rozšiřitelnosti jsou volitelné a lze je použít k vylepšení prostředí testování.

Rozšíření ICommandLineOptionsProvider

Poznámka

Při rozšíření tohoto rozhraní API bude vlastní rozšíření existovat jak v procesu testovacího hostitele, tak i mimo proces testovacího hostitele.

Jak je popsáno v části architektury, počáteční krok zahrnuje vytvoření ITestApplicationBuilder pro registraci testovací architektury a rozšíření.

var builder = await TestApplication.CreateBuilderAsync(args);

Metoda CreateBuilderAsync přijímá pole řetězců (string[]) s názvem args. Tyto argumenty lze použít k předání možností příkazového řádku všem komponentám testovací platformy (včetně integrovaných komponent, testovacích architektur a rozšíření), což umožňuje přizpůsobení jejich chování.

Předané argumenty jsou obvykle přijaté ve standardní Main(string[] args) metodě. Pokud se však hostitelské prostředí liší, je možné zadat libovolný seznam argumentů.

Argumenty musí mít předponu dvojitou pomlčkou --. Například: --filter.

Pokud komponenta, jako je testovací architektura nebo bod rozšíření, chce nabídnout vlastní možnosti příkazového řádku, může to udělat implementací rozhraní ICommandLineOptionsProvider. Tuto implementaci pak můžete zaregistrovat pomocí ITestApplicationBuilder prostřednictvím registrační továrny vlastnosti CommandLine, jak je znázorněno.

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

V uvedeném příkladu CustomCommandLineOptions je implementace rozhraní ICommandLineOptionsProvider, toto rozhraní se skládá z následujících členů a datových typů:

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

Jak je uvedeno, ICommandLineOptionsProvider rozšiřuje IExtension rozhraní. Podobně jako jakékoli jiné rozšíření se tedy můžete rozhodnout, že ho povolíte nebo zakážete pomocí rozhraní IExtension.IsEnabledAsync API.

Pořadí provádění ICommandLineOptionsProvider je:

diagramU představující pořadí provádění rozhraní ICommandLineOptionsProvider.

Pojďme se podívat na apis a jejich význam:

ICommandLineOptionsProvider.GetCommandLineOptions(): Tato metoda se využívá k načtení všech možností nabízených komponentou. Každá CommandLineOption vyžaduje zadání následujících vlastností:

string name: Toto je název možnosti, který se zobrazí bez pomlčky. Například filtr budou uživatelé používat jako --filter.

string description: Toto je popis možnosti. Zobrazí se, když uživatelé předávají --help jako argument tvůrci aplikací.

ArgumentArity arity: Arita možnosti je počet hodnot, které lze předat, pokud je specifikována tato možnost nebo příkaz. Aktuální dostupné arity jsou:

  • Zero: Představuje argument s nulovou aritou.
  • ZeroOrOne: Představuje počet argumentů, který je nula nebo jeden.
  • ZeroOrMore: Představuje argument s aritou od nuly výše.
  • OneOrMore: Představuje argument arity jednoho nebo více.
  • ExactlyOne: Představuje operační aritu přesně jednoho.

Příklady najdete v tabulce arity System.CommandLine.

bool isHidden: Tato vlastnost označuje, že je tato možnost k dispozici pro použití, ale při vyvolání --help se nezobrazí v popisu.

ICommandLineOptionsProvider.ValidateOptionArgumentsAsync: Tato metoda se používá k ověření argumentu poskytnutém uživatelem.

Pokud máte například parametr s názvem --dop, který představuje stupeň paralelismu pro naši vlastní testovací architekturu, může uživatel zadat --dop 0. V tomto scénáři by hodnota 0 byla neplatná, protože se očekává, že bude mít stupeň paralelismu 1 nebo více. Pomocí ValidateOptionArgumentsAsyncmůžete provést předběžné ověření a v případě potřeby vrátit chybovou zprávu.

Možnou implementací výše uvedeného vzorku může být:

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: Tato metoda je volána jako poslední a umožňuje provádět globální kontrolu koherence.

Řekněme například, že naše testovací architektura má možnost vygenerovat sestavu výsledků testu a uložit ji do souboru. Tato funkce je přístupná pomocí možnosti --generatereport a název souboru je zadán pomocí --reportfilename myfile.rep. Pokud uživatel v tomto scénáři poskytuje pouze možnost --generatereport bez zadání názvu souboru, ověření by mělo selhat, protože sestavu nelze vygenerovat bez názvu souboru. Možnou implementací výše uvedeného vzorku může být:

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

Upozorňujeme, že metoda ValidateCommandLineOptionsAsync poskytuje službu ICommandLineOptions, která se používá k načtení informací o argumentech analyzovaných samotnou platformou.

Rozšíření ITestSessionLifetimeHandler

ITestSessionLifeTimeHandler je rozšíření v procesu, které umožňuje spuštění kódu před a po testovací relace.

Pokud chcete zaregistrovat vlastní ITestSessionLifeTimeHandler, použijte následující rozhraní API:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Továrna využívá IServiceProvider k získání přístupu k sadě služeb nabízených testovací platformou.

Důležitý

Posloupnost registrace je významná, protože API rozhraní se volají v pořadí, v jakém byla zaregistrována.

Rozhraní ITestSessionLifeTimeHandler zahrnuje následující metody:

public interface ITestSessionLifetimeHandler : ITestHostExtension
{
    Task OnTestSessionStartingAsync(
        SessionUid sessionUid,
        CancellationToken cancellationToken);

    Task OnTestSessionFinishingAsync(
        SessionUid sessionUid,
        CancellationToken cancellationToken);
}

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

public interface ITestHostExtension : IExtension
{
}

ITestSessionLifetimeHandler je typ ITestHostExtension, který slouží jako základ pro všechna rozšíření testovacího hostitele. Stejně jako všechny ostatní body rozšíření, i tento dědí z IExtension. Podobně jako jakékoli jiné rozšíření se tedy můžete rozhodnout, že ho povolíte nebo zakážete pomocí rozhraní IExtension.IsEnabledAsync API.

Pro toto rozhraní API zvažte následující podrobnosti:

OnTestSessionStartingAsync: Tato metoda je vyvolána před zahájením zkušební relace a obdrží objekt SessionUid, který poskytuje neprůzný identifikátor pro aktuální testovací relaci.

OnTestSessionFinishingAsync: Tato metoda se vyvolá po dokončení testovací relace a zajistí, aby testovací architektura dokončila provádění všech testů a oznámila všechna relevantní data na platformě. Obvykle se v této metodě používá rozšíření IMessageBus k přenosu specifických prostředků nebo dat do sběrnice sdílené platformy. Tato metoda může také signalizovat jakékoli vlastní mimo proces rozšíření, které testovací relace ukončila.

Obě rozhraní API nakonec berou CancellationToken, které má rozšíření respektovat.

Pokud vaše rozšíření vyžaduje intenzivní inicializaci a potřebujete použít vzor async/await, můžete se podívat na Async extension initialization and cleanup. Pokud potřebujete sdílet stav mezi body rozšíření, můžete se podívat na část CompositeExtensionFactory<T>.

Rozšíření ITestApplicationLifecycleCallbacks

ITestApplicationLifecycleCallbacks je rozšíření v procesu, které umožňuje provádění kódu před vším, je jako mít přístup k prvnímu řádku hypotetického hlavníhotestovacího hostitele.

Pokud chcete zaregistrovat vlastní ITestApplicationLifecycleCallbacks, použijte následující rozhraní API:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

builder.TestHost.AddTestApplicationLifecycleCallbacks(
    static serviceProvider
    => new CustomTestApplicationLifecycleCallbacks());

Továrna využívá IServiceProvider k získání přístupu k sadě služeb nabízených testovací platformou.

Důležitý

Posloupnost registrace je významná, protože API rozhraní se volají v pořadí, v jakém byla zaregistrována.

Rozhraní ITestApplicationLifecycleCallbacks zahrnuje následující metody:

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

    Task AfterRunAsync(
        int exitCode,
        CancellationToken cancellation);
}

public interface ITestHostExtension : IExtension
{
}

ITestApplicationLifecycleCallbacks je typ ITestHostExtension, který slouží jako základ pro všechna rozšíření testovacího hostitele. Stejně jako všechny ostatní body rozšíření, i tento dědí z IExtension. Podobně jako jakékoli jiné rozšíření se tedy můžete rozhodnout, že ho povolíte nebo zakážete pomocí rozhraní IExtension.IsEnabledAsync API.

BeforeRunAsync: Tato metoda slouží jako počáteční kontaktní bod pro testovacího hostitele a je první příležitostí k provedení funkce v procesu rozšíření. Obvykle se používá k navázání připojení s jakýmikoli odpovídajícími mimoprocesními rozšířeními, pokud je funkce navržena tak, aby fungovala v obou prostředích.

Například integrovaná funkce výpisu stavu systému systému se skládá z v procesu i rozšíření mimo proces a tato metoda se používá k výměně informací s komponentou mimo proces rozšíření.

AfterRunAsync: Tato metoda je posledním voláním před opuštěním int ITestApplication.RunAsync() a poskytuje exit code. Měla by se používat výhradně k úklidu úloh a k oznámení jakéhokoli odpovídajícího rozšíření mimo proces, že testovací hostitel se chystá ukončit.

Obě rozhraní API nakonec berou CancellationToken, které má rozšíření respektovat.

Rozšíření IDataConsumer

IDataConsumer je rozšíření v procesu schopné přihlásit se k odběru a přijímat IData informace, které jsou posílány do IMessageBus testovacím frameworkem a jeho rozšířeními.

Tento bod rozšíření je zásadní, protože vývojářům umožňuje shromažďovat a zpracovávat všechny informace vygenerované během testovací relace.

Pokud chcete zaregistrovat vlastní IDataConsumer, použijte následující rozhraní API:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Továrna využívá IServiceProvider k získání přístupu k sadě služeb nabízených testovací platformou.

Důležitý

Posloupnost registrace je významná, protože API rozhraní se volají v pořadí, v jakém byla zaregistrována.

Rozhraní IDataConsumer zahrnuje následující metody:

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

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

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

IDataConsumer je typ ITestHostExtension, který slouží jako základ pro všechna rozšíření testovacího hostitele. Stejně jako všechny ostatní body rozšíření, i tento dědí z IExtension. Podobně jako jakékoli jiné rozšíření se tedy můžete rozhodnout, že ho povolíte nebo zakážete pomocí rozhraní IExtension.IsEnabledAsync API.

DataTypesConsumed: Tato vlastnost vrátí seznam Type, které toto rozšíření hodlá využít. Odpovídá číslu IDataProducer.DataTypesProduced. Zejména IDataConsumer se může přihlásit k odběru různých typů pocházejících z různých instancí IDataProducer bez jakýchkoli problémů.

ConsumeAsync: Tato metoda se aktivuje vždy, když jsou do IMessageBusvložena data typu, ke kterému je aktuální příjemce přihlášen. Obdrží IDataProducer, aby poskytl podrobnosti o producentovi datového obsahu, a také o samotném datovém obsahu IData. Jak vidíte, IData je obecné zástupné rozhraní, které obsahuje obecná informativní data. Schopnost nasdílit různé typy IData znamená, že uživatel musí přepnout na samotný typ, aby ho přetypovala na správný typ a přistupovala ke konkrétním informacím.

Ukázkovou implementací příjemce, který chce propracovaný TestNodeUpdateMessage vytvořený testovací architekturou, může být následující:

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

Nakonec rozhraní API přebírá CancellationToken, které by rozšíření mělo dodržet.

Důležitý

Zátěž je nezbytné zpracovat přímo v rámci metody ConsumeAsync. IMessageBus může spravovat synchronní i asynchronní zpracování a koordinovat provádění s testovací architekturou. I když je proces spotřeby zcela asynchronní a neblokuje IMessageBus.Push v době psaní, jedná se o podrobnosti implementace, které se mohou v budoucnu změnit kvůli budoucím požadavkům. Platforma však zajišťuje, že se tato metoda vždy volá jednou, eliminuje potřebu složité synchronizace a také správu škálovatelnosti příjemců.

Varování

Při použití IDataConsumer ve spojení s ITestHostProcessLifetimeHandler v rámci složeného bodu rozšíření, je nezbytné ignorovat všechna přijatá data po spuštění ITestSessionLifetimeHandler.OnTestSessionFinishingAsync. OnTestSessionFinishingAsync je poslední příležitostí ke zpracování kumulovaných dat a přenosu nových informací do IMessageBus , a proto nebudou využitelná rozšířením.

Pokud vaše rozšíření vyžaduje intenzivní inicializaci a potřebujete použít vzor async/await, můžete se podívat na Async extension initialization and cleanup. Pokud potřebujete sdílet stav mezi body rozšíření, můžete se podívat na část CompositeExtensionFactory<T>.

Rozšíření ITestHostEnvironmentVariableProvider

ITestHostEnvironmentVariableProvider je rozšíření mimo proces, které umožňuje vytvořit vlastní proměnné prostředí pro testovacího hostitele. S využitím tohoto rozšiřujícího bodu zajistíte, že testovací platforma zahájí nový hostitel s příslušnými proměnnými prostředí, jak je podrobně popsáno v části architektury .

Pokud chcete zaregistrovat vlastní ITestHostEnvironmentVariableProvider, použijte následující rozhraní API:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Továrna využívá IServiceProvider k získání přístupu k sadě služeb nabízených testovací platformou.

Důležitý

Posloupnost registrace je významná, protože API rozhraní se volají v pořadí, v jakém byla zaregistrována.

Rozhraní ITestHostEnvironmentVariableProvider zahrnuje následující metody a typy:

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

ITestHostEnvironmentVariableProvider je typ ITestHostControllersExtension, který slouží jako základ pro všechna rozšíření hostitelského kontroleru pro testování. Stejně jako všechny ostatní body rozšíření, i tento dědí z IExtension. Podobně jako jakékoli jiné rozšíření se tedy můžete rozhodnout, že ho povolíte nebo zakážete pomocí rozhraní IExtension.IsEnabledAsync API.

Zvažte podrobnosti pro toto rozhraní API:

UpdateAsync: Toto rozhraní API aktualizace poskytuje instanci objektu IEnvironmentVariables, ze kterého můžete volat SetVariable nebo RemoveVariable metody. Při použití SetVariablemusíte předat objekt typu EnvironmentVariable, který vyžaduje následující specifikace:

  • Variable: Název proměnné prostředí.
  • Value: Hodnota proměnné prostředí.
  • IsSecret: Označuje, zda proměnná prostředí obsahuje citlivé informace, které by neměly být protokolovány nebo přístupné prostřednictvím TryGetVariable.
  • IsLocked: Určuje, zda ostatní rozšíření ITestHostEnvironmentVariableProvider mohou tuto hodnotu upravit.

ValidateTestHostEnvironmentVariablesAsync: Tato metoda je vyvolána po zavolání všech metod UpdateAsync u registrovaných instancí ITestHostEnvironmentVariableProvider. Umožňuje ověřit správné nastavení proměnných prostředí. Přebírá objekt, který implementuje IReadOnlyEnvironmentVariablesa poskytuje metodu TryGetVariable pro načtení konkrétních informací o proměnné prostředí s typem objektu OwnedEnvironmentVariable. Po ověření vrátíte ValidationResult obsahující všechny důvody selhání.

Poznámka

Testovací platforma ve výchozím nastavení implementuje a zaregistruje SystemEnvironmentVariableProvider. Tento zprostředkovatel načte všechny proměnné aktuálního prostředí. Jako první registrovaný zprostředkovatel se spustí jako první a udělí přístup k výchozím proměnným prostředí pro všechna ostatní uživatelská rozšíření ITestHostEnvironmentVariableProvider.

Pokud vaše rozšíření vyžaduje intenzivní inicializaci a potřebujete použít vzor async/await, můžete se podívat na Async extension initialization and cleanup. Pokud potřebujete sdílet stav mezi body rozšíření, můžete se podívat na část CompositeExtensionFactory<T>.

Rozšíření ITestHostProcessLifetimeHandler

ITestHostProcessLifetimeHandler je rozšíření běžící vně procesu, které umožňuje sledovat proces testovacího hostitele z externího hlediska. Tím zajistíte, že vaše rozšíření zůstane nedotčené možnými chybovými ukončeními nebo zablokováními, které by mohl vyvolat testovaný kód. Při použití tohoto bodu rozšíření obdrží testovací platforma pokyn k spuštění nového hostitele, jak je uvedeno v části architektury.

Pokud chcete zaregistrovat vlastní ITestHostProcessLifetimeHandler, použijte následující rozhraní API:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Továrna využívá IServiceProvider k získání přístupu k sadě služeb nabízených testovací platformou.

Důležitý

Posloupnost registrace je významná, protože API rozhraní se volají v pořadí, v jakém byla zaregistrována.

Rozhraní ITestHostProcessLifetimeHandler zahrnuje následující metody:

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

ITestHostProcessLifetimeHandler je typ ITestHostControllersExtension, který slouží jako základ pro všechna rozšíření hostitelského kontroleru pro testování. Stejně jako všechny ostatní body rozšíření, i tento dědí z IExtension. Podobně jako jakékoli jiné rozšíření se tedy můžete rozhodnout, že ho povolíte nebo zakážete pomocí rozhraní IExtension.IsEnabledAsync API.

Pro toto rozhraní API zvažte následující podrobnosti:

BeforeTestHostProcessStartAsync: Tato metoda je volána před tím, než testovací platforma začne spouštět testovací hostitele.

OnTestHostProcessStartedAsync: Tato metoda se vyvolá okamžitě po spuštění testovacího hostitele. Tato metoda nabízí objekt, který implementuje ITestHostProcessInformation rozhraní, které poskytuje klíčové podrobnosti o výsledku procesu hostitele testu.

Důležitý

Vyvolání této metody nezastaví spuštění testovacího hostitele. Pokud ho potřebujete pozastavit, měli byste zaregistrovat rozšíření v rámci procesu, jako je ITestApplicationLifecycleCallbacks, a synchronizovat ho s rozšířením mimo proces .

OnTestHostProcessExitedAsync: Tato metoda se vyvolá při dokončení provádění sady testů. Tato metoda poskytuje objekt, který dodržuje rozhraní ITestHostProcessInformation, který vyjadřuje zásadní podrobnosti o výsledku hostitelského procesu testu.

Rozhraní ITestHostProcessInformation poskytuje následující podrobnosti:

  • PID: ID procesu testovacího hostitele.
  • ExitCode: Ukončovací kód procesu. Tato hodnota je k dispozici pouze v rámci metody OnTestHostProcessExitedAsync. Při pokusu o přístup v rámci metody OnTestHostProcessStartedAsync dojde k výjimce.
  • HasExitedGracefully: Logická hodnota označující, jestli došlo k selhání testovacího hostitele. Pokud je pravda, znamená to, že testovací hostitel neodejde elegantně.

Pořadí provádění rozšíření

Testovací platforma se skládá z testovací architektury a libovolného počtu rozšíření, která můžou fungovat procesu nebo mimo proces . Tento dokument popisuje sekvenci volání ke všem potenciálním bodům rozšíření, aby bylo jasné, kdy se očekává vyvolání funkce:

  1. ITestHostEnvironmentVariableProvider.UpdateAsync: Mimo proces
  2. ITestHostEnvironmentVariableProvider.ValidateTestHostEnvironmentVariablesAsync: Mimo proces
  3. ITestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync: Mimo proces
  4. Spuštění testovacího hostitelského procesu
  5. ITestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync: Mimo proces může tato událost propojit akce v rámci procesu rozšíření podle podmínek soutěživosti.
  6. ITestApplicationLifecycleCallbacks.BeforeRunAsync: V procesu
  7. ITestSessionLifetimeHandler.OnTestsessionStartingAsync: In-process
  8. ITestFramework.CreateTestSessionAsync: V procesu
  9. ITestFramework.ExecuteRequestAsync: V procesu lze tuto metodu volat jednou nebo vícekrát. V tuto chvíli bude testovací rámec přenášet informace do IMessageBus, které může využít IDataConsumer.
  10. ITestFramework.CloseTestSessionAsync: Proces probíhá
  11. ITestSessionLifetimeHandler.OnTestSessionFinishingAsync: V procesu
  12. ITestApplicationLifecycleCallbacks.AfterRunAsync: V procesu
  13. Čištění v procesu zahrnuje volání metod dispose a IAsyncCleanableExtension na všech bodech rozšíření.
  14. ITestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync: Mimo proces
  15. Vyčištění mimo proces zahrnuje volání dispose a IAsyncCleanableExtension na všech bodech rozšíření.

Pomocníci pro rozšíření

Testovací platforma poskytuje sadu pomocných tříd a rozhraní pro zjednodušení implementace rozšíření. Tyto pomocné rutiny jsou navrženy tak, aby zjednodušily proces vývoje a zajistily, že rozšíření dodržuje standardy platformy.

Asynchronní inicializace a vyčištění rozšíření

Vytvoření testovací architektury a rozšíření prostřednictvím továren dodržuje standardní mechanismus vytváření objektů .NET, který používá synchronní konstruktory. Pokud rozšíření vyžaduje intenzivní inicializaci (například přístup k systému souborů nebo síti), nemůže použít async/await vzoru v konstruktoru, protože konstruktory vrací void, nikoli Task.

Testovací platforma proto poskytuje metodu inicializace rozšíření pomocí vzoru async/await prostřednictvím jednoduchého rozhraní. Pro symetrii nabízí také asynchronní rozhraní pro vyčištění, které rozšíření mohou bez problémů implementovat.

public interface IAsyncInitializableExtension
{
    Task InitializeAsync();
}

public interface IAsyncCleanableExtension
{
    Task CleanupAsync();
}

IAsyncInitializableExtension.InitializeAsync: Tato metoda je zaručeno, že se vyvolá po vytvoření továrny.

IAsyncCleanableExtension.CleanupAsync: Tato metoda je zaručena, že bude vyvolána alespoň jednou během ukončení testovací relace před výchozím nastavením DisposeAsync nebo Dispose.

Důležitý

Podobně jako u standardní metody Dispose může být CleanupAsync vyvolána vícekrát. Pokud je metoda CleanupAsync objektu volána více než jednou, musí objekt ignorovat všechna volání po prvním. Objekt nesmí vyvolat výjimku, pokud je jeho CleanupAsync metoda volána vícekrát.

Poznámka

Testovací platforma bude ve výchozím nastavení volat DisposeAsync, pokud je dostupná, nebo Dispose, pokud je implementovaná. Je důležité si uvědomit, že testovací platforma nebude volat obě metody Dispose, ale bude upřednostňovat asynchronní metodu, pokud je implementovaná.

Továrna na CompositeExtension<T>

Jak je uvedeno v části rozšíření, testovací platforma umožňuje implementovat rozhraní pro začlenění vlastních rozšíření do procesu i mimo proces.

Každé rozhraní řeší určitou funkci a podle .NET návrhu implementujete toto rozhraní do konkrétního objektu. Samotné rozšíření můžete zaregistrovat pomocí konkrétního registračního rozhraní API AddXXX z TestHost nebo TestHostController objektu z ITestApplicationBuilder, jak je podrobně popsáno v příslušných částech.

Pokud ale potřebujete sdílet stav mezi dvěma rozšířeními, fakt, že můžete implementovat a zaregistrovat různé objekty, které implementují různá rozhraní, činí sdílení náročným úkolem. Bez jakékoli pomoci byste potřebovali způsob, jak předat jedno rozšíření druhému ke sdílení informací, což komplikuje návrh.

Testovací platforma proto poskytuje sofistikovanou metodu implementace více bodů rozšíření pomocí stejného typu, což usnadňuje sdílení dat. Stačí použít CompositeExtensionFactory<T>, které pak můžete zaregistrovat pomocí stejného rozhraní API, jako byste použili pro implementaci jediného rozhraní.

Zvažte například typ, který implementuje ITestSessionLifetimeHandler i IDataConsumer. Jedná se o běžný scénář, protože často chcete shromáždit informace z testovacího frameworku a poté, co se testovací relace ukončí, odešlete svůj artefakt pomocí IMessageBus v rámci ITestSessionLifetimeHandler.OnTestSessionFinishingAsync.

Co byste měli udělat, je normálně implementovat rozhraní:

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

Jakmile vytvoříte CompositeExtensionFactory<CustomExtension> pro váš typ, můžete ho zaregistrovat v rozhraních API IDataConsumer i ITestSessionLifetimeHandler, které nabízejí možnost přetížení CompositeExtensionFactory<T>:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

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

Konstruktor továrny využívá IServiceProvider pro přístup ke službám poskytovaným testovací platformou.

Testovací platforma bude zodpovědná za správu životního cyklu složeného rozšíření.

Je důležité si uvědomit, že vzhledem k podpoře testovací platformy pro v procesu i rozšíření mimo proces, nemůžete libovolně kombinovat žádný bod rozšíření. Vytváření a využití rozšíření závisí na typu hostitele, což znamená, že můžete seskupit pouze v procesu (TestHost) a rozšíření mimo proces (TestHostController).

Možné jsou následující kombinace:

  • Pro ITestApplicationBuilder.TestHostmůžete kombinovat IDataConsumer a ITestSessionLifetimeHandler.
  • Pro ITestApplicationBuilder.TestHostControllersmůžete kombinovat ITestHostEnvironmentVariableProvider a ITestHostProcessLifetimeHandler.