Microsoft.Testing.Platform (MTP) için uzantılar oluşturun.

Bu makale, test çerçevesinin ötesinde MTP için genişletilebilirlik noktalarını kapsar. Test çerçevesi oluşturmak için bkz. Test çerçevesi oluşturma.

Tam uzantı noktası özeti ve işlem içi/işlem dışı kavramlar için bkz. Özel uzantılar oluşturma.

Genişletilebilirlik noktaları

Test platformu, platformun ve test çerçevesinin davranışını özelleştirmenize olanak sağlayan ek genişletilebilirlik noktaları sağlar. Bu genişletilebilirlik noktaları isteğe bağlıdır ve test deneyimini geliştirmek için kullanılabilir.

Tip

Bu makalede gösterilen her uzantı, el ile kayıt için bir kod parçacığı (örneğin, builder.TestHost.AddDataConsumer(...)) içerir. Uzantınızı bir NuGet paketi olarak dağıtıyorsanız, bir TestingPlatformBuilderHook ve küçük bir MSBuild props dosyası sağlayarak kullanıcıların manuel çağrıyı atlamasına izin verebilirsiniz. Otomatik olarak oluşturulan giriş noktası, kancanızı otomatik olarak çağırır. Ayrıntılar için TestingPlatformBuilderHook ile uzantınızı otomatik olarak kaydetme konusuna bakın.

ICommandLineOptionsProvider uzantılar

Uyarı

Bu API genişletildiğinde, özel uzantı test konağı işleminin hem içinde hem de dışında bulunur.

Mimari bölümünde açıklandığı gibi, ilk adım, test çerçevesi ve uzantılarını kaydetmek amacıyla ITestApplicationBuilder bileşenini yaratmaktır.

var builder = await TestApplication.CreateBuilderAsync(args);

CreateBuilderAsync yöntemi adlı string[]bir dize dizisini (args) kabul eder. Bu bağımsız değişkenler, komut satırı seçeneklerini test platformunun tüm bileşenlerine (yerleşik bileşenler, test çerçeveleri ve uzantılar dahil) geçirmek ve davranışlarını özelleştirmek için kullanılabilir.

Genellikle, geçirilen bağımsız değişkenler standart Main(string[] args) yönteminde alınanlardır. Ancak, barındırma ortamı farklıysa, bağımsız değişkenlerin herhangi bir listesi sağlanabilir.

Bağımsız değişkenlerin başına çift tire eklenmelidir . Örneğin, --filter.

Test çerçevesi veya uzantı noktası gibi bir bileşen özel komut satırı seçenekleri sunmak isterse, arabirimini ICommandLineOptionsProvider uygulayarak bunu yapabilir. Bu uygulama daha sonra özelliğinin kayıt fabrikası aracılığıyla ile kaydedilebilir, aşağıda gösterildiği gibi:

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

Sağlanan örnekte, CustomCommandLineOptions arabiriminin ICommandLineOptionsProvider bir uygulamasıdır, Bu arabirim aşağıdaki üyeleri ve veri türlerini içerir:

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

Gözlemlendiği gibi, ICommandLineOptionsProvider arabirimi, IExtension genişletir. Bu nedenle, diğer tüm uzantılarda olduğu gibi API'yi kullanarak etkinleştirmeyi veya devre dışı bırakmayı IExtension.IsEnabledAsync seçebilirsiniz.

ICommandLineOptionsProvider'nin yürütme sırası şöyledir:

'ICommandLineOptionsProvider' arabiriminin yürütme sırasını temsil eden diyagram.

Şimdi api'leri ve bunların ortalamasını inceleyelim:

ICommandLineOptionsProvider.GetCommandLineOptions(): Bu yöntem, bileşen tarafından sunulan tüm seçenekleri almak için kullanılır. Her CommandLineOption biri aşağıdaki özelliklerin belirtilmesi gerekir:

string name: Bu, kısa çizgi olmadan sunulan seçeneğin adıdır. Örneğin, filtre kullanıcılar tarafından --filter olarak kullanılabilir.

string description: Bu seçeneğin açıklamasıdır. Kullanıcılar --help öğesini uygulama oluşturucusuna bağımsız değişken olarak geçirdiğinde görüntülenecek.

ArgumentArity arity: Bir seçeneğin arity'si, bu seçenek veya komut belirtilirse geçirilebilen değerlerin sayısıdır. Mevcut kullanılabilir arilikler şunlardır:

  • Zero: Sıfır bağımsız değişken arity değerini temsil eder.
  • ZeroOrOne: Sıfır veya bir bağımsız değişken sayısını temsil eder.
  • ZeroOrMore: Sıfır veya daha fazla bağımsız değişken aritesini temsil eder.
  • OneOrMore: Bir veya daha fazla bağımsız değişkenin arity'sini temsil eder.
  • ExactlyOne: Tam olarak bir argüman arity'sini temsil eder.

Örnekler için System.CommandLine arity tablosuna bakın.

bool isHidden: Bu özellik, seçeneğin kullanılabilir olduğunu ancak çağrıldığında --help açıklamada görüntülenmeyeceğini bildirir.

ICommandLineOptionsProvider.ValidateOptionArgumentsAsync: Bu yöntem, kullanıcı tarafından sağlanan bağımsız değişkeni doğrulamak için kullanılır.

Örneğin, özel test çerçevemiz için paralellik derecesini temsil eden adlı --dop bir parametreniz varsa, kullanıcı girdisi --dop 0olabilir. Bu senaryoda, 0 değeri, 1 veya daha fazla paralellik derecesine sahip olması beklendiğinden geçersiz olacaktır. kullanarak ValidateOptionArgumentsAsync, ön doğrulama gerçekleştirebilir ve gerekirse bir hata iletisi döndürebilirsiniz.

Yukarıdaki örnek için olası bir uygulama olabilir:

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: Bu yöntem son yöntem olarak çağrılır ve genel tutarlılık denetimi yapılmasına izin verir.

Örneğin, test çerçevemizin bir test sonucu raporu oluşturup bir dosyaya kaydetme özelliğine sahip olduğunu varsayalım. Bu özelliğe --generatereport seçeneği kullanılarak erişilir ve dosya adı --reportfilename myfile.rep ile belirtilir. Bu senaryoda, bir kullanıcı yalnızca dosya adı belirtmeden seçeneği sağlıyorsa --generatereport , rapor dosya adı olmadan oluşturulamadığından doğrulama başarısız olmalıdır. Yukarıdaki örnek için olası bir uygulama olabilir:

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

ValidateCommandLineOptionsAsync yöntemi, platformun kendisi tarafından ayrıştırılan bağımsız değişken bilgilerini almak için kullanılan ICommandLineOptions hizmetini sağladığını lütfen unutmayın.

ITestSessionLifetimeHandler uzantılar

ITestSessionLifetimeHandler, test oturumundan önce ve sonra kodun yürütülmesini sağlayan bir işlem içi uzantıdır.

Özel bir ITestSessionLifetimeHandler kaydetmek için aşağıdaki API'yi kullanın:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Fabrika, test platformu tarafından sunulan hizmet paketine erişim elde etmek için IServiceProvider kullanır.

Önemli

API'ler kaydedildikleri sırayla çağrıldıklarından kayıt sırası önemlidir.

Arabirim ITestSessionLifetimeHandler aşağıdaki yöntemleri içerir:

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

Önemli

MTP 2.0.0'da her iki yöntem de, SessionUid ile CancellationToken'yi sunan tek bir ITestSessionContext parametresi alacak şekilde değiştirildi. MTP 1.x'te her yöntem, ayrı birer SessionUid ve CancellationToken bağımsız değişkeni alıyordu. Daha fazla bilgi için bkz: Microsoft.Testing.Platform (MTP) v1’den v2’ye geçiş.

ITestSessionLifetimeHandler bir tür ITestHostExtension olup, tüm test host uzantıları için temel görevi görür. Diğer tüm uzantı noktaları gibi IExtension'dan da miras alır. Bu nedenle, diğer tüm uzantılarda olduğu gibi API'yi kullanarak etkinleştirmeyi veya devre dışı bırakmayı IExtension.IsEnabledAsync seçebilirsiniz.

Bu API için aşağıdaki ayrıntıları göz önünde bulundurun:

OnTestSessionStartingAsync: Bu yöntem, test oturumu başlamadan önce çağrılır ve SessionUid geçerli test oturumu için opak bir tanımlayıcı sağlayan ITestSessionContext öğesini alır.

OnTestSessionFinishingAsync: Bu yöntem, test oturumu tamamlandıktan sonra çağrılır ve test çerçevesinin tüm testleri yürütmeyi tamamladığından ve tüm ilgili verileri platforma bildirdiğinden emin olur. Genellikle bu yöntemde uzantı, paylaşılan platform veri yolu'na özel varlıkları veya verileri iletmek için öğesini kullanır IMessageBus . Bu yöntem, test oturumunun tamamlandığını belirten herhangi bir özel işlem dışı uzantıya da işaret edebilir.

Son olarak, ITestSessionContext, uzantının uyması beklenen bir CancellationToken sunar.

Uzantınız yoğun bir başlatma gerektiriyorsa ve async/await desenini kullanmanız gerekiyorsa, Async extension initialization and cleanup öğesine başvurabilirsiniz. Uzantı noktaları arasında durum paylaşmanız gerekiyorsa, bölümüne başvurabilirsiniz.

ITestApplicationLifecycleCallbacks uzantılar

Önemli

ITestApplicationLifecycleCallbacks MTP 2.0.0'da kaldırıldı. Bunun yerine ITestHostApplicationLifetime kullanın. Daha fazla bilgi için bkz: Microsoft.Testing.Platform (MTP) v1’den v2’ye geçiş.

Arabirim, ITestHostApplicationLifetimebir işlem içi uzantının test konağı başında ve sonunda kod çalıştırmasına olanak tanır.

Özel bir ITestHostApplicationLifetime kaydetmek için aşağıdaki API'yi kullanın:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Fabrika, test platformu tarafından sunulan hizmetlere erişmek için IServiceProvider'ı kullanır.

Önemli

API'ler kaydedildikleri sırayla çağrıldıklarından kayıt sırası önemlidir.

Arabirim ITestHostApplicationLifetime aşağıdaki yöntemleri içerir:

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

    Task AfterRunAsync(
        int exitCode,
        CancellationToken cancellationToken);
}

public interface ITestHostExtension : IExtension
{
}

ITestHostApplicationLifetime arabirimi, tüm ITestHostExtension uzantıları için temel görevi gören öğesini genişletir. Diğer tüm uzantı noktaları gibi IExtension'dan da miras alır. Bu nedenle, diğer tüm uzantılarda olduğu gibi API'yi kullanarak etkinleştirmeyi veya devre dışı bırakmayı IExtension.IsEnabledAsync seçebilirsiniz.

BeforeRunAsync: Bu yöntem, test konağı için ilk iletişim noktası görevi görür ve işlem içi uzantının bir özelliği yürütmesi için ilk fırsattır. Bir özellik her iki ortamda çalışacak şekilde tasarlandıysa genellikle ilgili işlem dışı uzantılarla bağlantı kurmak için kullanılır.

Örneğin, yerleşik kilitlenme dökümü özelliği hem işlem içi hem de işlemdışı uzantılardan oluşur ve bu yöntem uzantının işlem dışı bileşeniyle bilgi alışverişinde bulunmak için kullanılır.

AfterRunAsync: Bu yöntem, int ITestApplication.RunAsync()'den çıkmadan önceki son çağrıdır ve exit code sağlar. Yalnızca temizleme görevleri için ve ilgili işlem dışı uzantılara test ana bilgisayarının sonlandırılacağı bildirilmesi için kullanılmalıdır.

Son olarak, her iki API de uzantının uyması beklenen bir CancellationToken alır.

IDataConsumer uzantılar

IDataConsumer, test çerçevesi ve uzantıları tarafından IData yayımlanan bilgilere abone olup bilgi alabilen bir işlem içi uzantıdır.

Bu uzantı noktası, geliştiricilerin bir test oturumu sırasında oluşturulan tüm bilgileri toplamasına ve işlemesine olanak sağladığından çok önemlidir.

Özel bir IDataConsumer kaydetmek için aşağıdaki API'yi kullanın.

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Fabrika, test platformu tarafından sunulan hizmet paketine erişim elde etmek için IServiceProvider kullanır.

Önemli

API'ler kaydedildikleri sırayla çağrıldıklarından kayıt sırası önemlidir.

Arabirim IDataConsumer aşağıdaki yöntemleri içerir:

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

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

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

Önemli

MTP 2.0.0'da, IDataConsumer, Microsoft.Testing.Platform.Extensions ad alanına taşındı ve artık doğrudan IExtension'yi genişletiyor. MTP 1.x'te ITestHostExtension genişletildi. Bunu yine builder.TestHost.AddDataConsumer(...) ile kaydedersiniz. Daha fazla bilgi için bkz: Microsoft.Testing.Platform (MTP) v1’den v2’ye geçiş.

IDataConsumer, IExtension öğesinden devralır. Bu nedenle, diğer tüm uzantılarda olduğu gibi API'yi kullanarak etkinleştirmeyi veya devre dışı bırakmayı IExtension.IsEnabledAsync seçebilirsiniz.

DataTypesConsumed: Bu özellik, bu uzantının kullanmayı planladığı listenin Type bir listesini döndürür. öğesine karşılık gelir IDataProducer.DataTypesProduced. Özellikle, bir IDataConsumer, sorun olmadan farklı IDataProducer örneklerden kaynaklanan birden çok türe abone olabilir.

ConsumeAsync: Bu yöntem, geçerli tüketicinin abone olduğu türdeki veriler IMessageBus'de yayımlandığında tetiklenir. Veri yükünün IDataProducer üreticisi IData ve yükün kendisi hakkındaki ayrıntıları sağlamak için alır. Gördüğünüz gibi, IData genel bilgilendirici veriler içeren genel bir yer tutucu arabirimidir. Farklı IData türlerinin yayımlanabilmesi, istemcinin onu doğru türe dönüştürmek ve ilgili özel bilgilere erişmek için doğrudan türün kendisine göre ayrım yapması gerektiği anlamına gelir.

Bir test çerçevesi tarafından üretilenleri ayrıntılandırmak isteyen bir tüketicinin TestNodeUpdateMessage örnek uygulaması şöyle olabilir:

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

Son olarak API, uzantının yerine getirmesi beklenen bir CancellationToken alır.

Önemli

Yükü doğrudan ConsumeAsync yöntemi içinde işleyin. Normal bir IDataConsumer, verileri zaman uyumsuz olarak tüketir: IMessageBus, yayınlanan her yükü kuyruğa alır ve bunu bir arka plan döngüsünde işler; bu nedenle IMessageBus.PublishAsync, üreticiyi engellemez ve üretici işine devam ederken ConsumeAsync öğesinin ne zaman çalışacağına dair hiçbir garanti yoktur. Platform, her tüketici için aynı anda yalnızca bir veri yükünün işlenmesini sağlayacak şekilde teslimatı sıralı hale getirir; bu da tek bir tüketici tarafında karmaşık eşitleme gereksinimini ortadan kaldırır.

Uyarı

Üretici devam etmeden önce tüketimin gerçekleşeceğini garanti etmesi gereken senaryolar için (örneğin, bir test çalışmaya başlamadan önce), MTP 2.3.0 deneysel IBlockingDataConsumer işaretleyici arabirimini tanıttı (TPEXP tanılamasının bastırılmasını gerektirir). IBlockingDataConsumer öğesini de uygulayan bir tüketici, mesaj veri yolu tarafından doğrudan çağrılır: çağrılar serileştirilir, PublishAsyncConsumeAsync tamamlanana kadar engellenir ve ConsumeAsync tarafından oluşturulan herhangi bir özel durum, verileri yayımlayan üreticiye geri iletilir. Mesaj veri yolu, bir üreticinin verilerini aynı üreticiye (aynı UID'ye) geri iletmez; bu nedenle kendi UID'nizle yayımlama yapmak güvenlidir. Ancak bloklayan bir tüketici, ConsumeAsync içinden, farklı bir üretici UID’si altında kendisine geri yönlendirilen verileri yayımlamamalıdır; çünkü bu tür bir yeniden giriş kilitlenmeye yol açar.

Uyarı

IDataConsumer içinde ITestSessionLifetimeHandler ile birlikte kullanıldığında, ITestSessionLifetimeHandler.OnTestSessionFinishingAsync yürütülme sonrasında alınan tüm verileri göz ardı etmek çok önemlidir. OnTestSessionFinishingAsync birikmiş verileri işlemek ve yeni bilgileri IMessageBus'a iletmek için son fırsattır, bu nedenle bu noktanın ötesinde tüketilen veriler uzantı tarafından kullanılamaz.

Uzantınız yoğun bir başlatma gerektiriyorsa ve async/await desenini kullanmanız gerekiyorsa, Async extension initialization and cleanup öğesine başvurabilirsiniz. Uzantı noktaları arasında durum paylaşmanız gerekiyorsa, bölümüne başvurabilirsiniz.

Mesaj veri yolu artefaktları

Özel IData yükte otomatik kullanıcı arabirimi veya komut satırı çıkışı yoktur. Platform, yalnızca kayıtlı eşleşen bir tüketicisi olan verileri gösterir; bu nedenle kendi IData türünüzü yayımlarsanız ve onu tüketen hiçbir şey yoksa, hiçbir şey yazdırılmaz veya iletilmez. Uzantınızın ürettiği dosyaları kullanıcılara ve araçlara görünür hale getirmek için yerleşik terminal ve dotnet test tüketicilerinin zaten tanıdığı yerleşik dosya yapıt iletilerinden birini yayımlayın.

Çalışma düzeyi veya oturum düzeyi dosyaları için FileArtifact veya SessionFileArtifact yayımlayın. Her ikisi de MTP 1.0.0'da kullanıma sunuldu ve Microsoft.Testing.Platform.Extensions.Messages ad alanında bulunur:

  • FileArtifact kapsam dışı. Belirli bir test oturumuna bağlı olmayan bir dosya için kullanın.
  • SessionFileArtifact, SessionUid aracılığıyla bir çalıştırma/oturumla sınırlandırılır. Bunu, kapsama sonuçları, raporlar, dökümler veya kaydedilmiş videolar gibi çalıştırmanın tamamı için üretilen artefaktlar için kullanın.

Yerleşik terminal ve dotnet test tüketicileri her iki türü de yakalar ve dosya yollarını yazdırır veya iletir; böylece dosyalar konsol çıktısında ve dotnet test işlem hattı boyunca bulunabilir hâle gelir. Tüketiciler nihai sunuyu denetlediğinden, tüketilebileceği veya iletilebileceği sürece her dosyayı diskte ve kullanılabilir durumda tutun; aynı PublishAsync çağrının içinde silmeyin.

Yapıt nesnesinin kendisi üretici kimliği taşımaz. İleti yolu, kaynak IDataProducer öğesini IDataConsumer.ConsumeAsync içindeki dataProducer bağımsız değişkeni aracılığıyla her tüketiciye sağlar; böylece tüketiciler bir dosyanın kim tarafından üretildiğini artefaktan değil, bu bağımsız değişkenden öğrenir. Mesaj veri yolu ayrıca referans verilen dosyanın sahipliğini ne devralır ne taşır ne de siler: dosyanın yaşam döngüsünden üretici sorumludur ve tüketiciler yalnızca dosya yolunu alır, okur veya bu yolu iletir.

Uyarı

Üçüncü taraf IDataConsumer kaydı yalnızca builder.TestHost üzerinde public’tir (işlem içi test ana bilgisayarı). builder.TestHostControllers.AddDataConsumer tüketiciler için genel API yoktur. Artefaktları görüntüleyen birinci taraflı rapor uzantıları, özel uzantıların güvenemeyeceği platformun dahili entegrasyonunu kullanır. Dosyaları kendi uzantınızdan ortaya çıkarabilmek için, burada açıklanan yerleşik yapıt iletilerini yayımlayın ve yerleşik tüketicilerin bunları sunmasına izin verin.

Bir oturum yapıtı yayımlayan üretici, IDataProducer öğesini uygulamalı ve yayımladığı tam çalışma zamanı ileti türlerini DataTypesProduced içinde listelemelidir. Aşağıdaki örnek, oturum tamamlandığında bir kapsam raporu yayımlar:

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

Terminalin, dotnet test ve IDE'lerin bunu belirli bir testle ilişkilendirip görüntülemesi için, o teste bir dosya eklerken bağımsız bir dosya yapıtı yayımlamayın. Bunun yerine, test çerçevenizin bir TestNodeUpdateMessage aracılığıyla raporladığı TestNode öğesine bir veya daha fazla FileArtifactProperty girdisi ekleyin. FileArtifactProperty MTP 1.7.0 ile kullanıma sunulmuştur:

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

Önemli

TestNodeFileArtifact eskidir ve MTP 2.0.0'da kaldırılmıştır. Test düzeyindeki dosyaları eklemek için, TestNode üzerinde FileArtifactProperty kullanın. Daha fazla bilgi için bkz: Microsoft.Testing.Platform (MTP) v1’den v2’ye geçiş.

Uyarı

MTP 2.4.0 (Temmuz 2026 itibarıyla yayımlanmamış sürüm), FileArtifact ve SessionFileArtifact öğelerine deneysel bir kind oluşturucu aşırı yüklemesi ile Kind özelliği ekler (TPEXP tanılamasının bastırılmasını gerektirir). Kind , son işlemenin birleştirme için aynı biçimdeki yapıtları gruplandırmak için kullanabileceği yapıt biçiminin (örneğin, microsoft.testing.trx, microsoft.testing.junit, microsoft.testing.ctrfveya microsoft.testing.html) üretici tarafından onaylanan, ters DNS tanımlayıcısıdır. Onu null olduğu gibi bırakın veya üretici bilinen bir türü belirtmediğinde çıkarın. Şu anda yalnızca Kind bir meta veri sözleşmesidir; bunun ötesinde kapsamlı birleştirme düzenlemesi varsaymayın.

#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

ITestHostEnvironmentVariableProvider uzantılar

ITestHostEnvironmentVariableProvider, test konağı için özel ortam değişkenleri oluşturmanıza olanak tanıyan işlem dışı bir uzantıdır. Bu tür bir genişletme noktasını kullanmak, mimari bölümünde ayrıntılı olarak açıklandığı gibi, test platformunun uygun ortam değişkenleriyle yeni bir konak başlatmasını sağlar.

Özel bir ITestHostEnvironmentVariableProvider kaydetmek için aşağıdaki API'yi kullanın.

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Fabrika, test platformu tarafından sunulan hizmet paketine erişim elde etmek için IServiceProvider kullanır.

Önemli

API'ler kaydedildikleri sırayla çağrıldıklarından kayıt sırası önemlidir.

Arabirim ITestHostEnvironmentVariableProvider aşağıdaki yöntemleri ve türleri içerir:

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, tüm ITestHostControllersExtension uzantıları için temel olarak hizmet veren bir türüdür. Diğer tüm uzantı noktaları gibi IExtension'dan da miras alır. Bu nedenle, diğer tüm uzantılarda olduğu gibi API'yi kullanarak etkinleştirmeyi veya devre dışı bırakmayı IExtension.IsEnabledAsync seçebilirsiniz.

Bu API'nin ayrıntılarını göz önünde bulundurun:

UpdateAsync: Bu güncelleme API'si, IEnvironmentVariables nesnesinin bir örneğini sağlar; bu nesne üzerinden SetVariable veya RemoveVariable yöntemlerini çağırabilirsiniz. SetVariable kullanırken, aşağıdaki belirtimleri gerektiren EnvironmentVariable türünde bir nesne geçirmeniz gerektiğini unutmayın.

  • Variable: Ortam değişkeninin adı.
  • Value: Ortam değişkeninin değeri.
  • IsSecret: Bu, ortam değişkeninin hassas bilgiler içerip içermediğini ve bu bilgilerin günlüğe kaydedilmemesi veya TryGetVariable aracılığıyla erişilebilir olmaması gerektiğini gösterir.
  • IsLocked: Bu, diğer ITestHostEnvironmentVariableProvider uzantıların bu değeri değiştirip değiştiremeyeceğini belirler.

ValidateTestHostEnvironmentVariablesAsync: Bu yöntem, kayıtlı UpdateAsync örneklerin ITestHostEnvironmentVariableProvider tüm yöntemleri çağrıldıktan sonra çağrılır. Ortam değişkenlerinin doğru kurulumunu doğrulamanıza olanak tanır. IReadOnlyEnvironmentVariables'yü implement eden ve TryGetVariable nesne türü ile belirli ortam değişkeni bilgilerini almak için OwnedEnvironmentVariable yöntemini sağlayan bir nesne alır. Doğrulamadan sonra, hata nedenlerini içeren bir ValidationResult döndürür.

Uyarı

Test platformu varsayılan olarak SystemEnvironmentVariableProvider öğesini uygular ve kaydeder. Bu sağlayıcı tüm geçerli ortam değişkenlerini yükler. İlk kayıtlı sağlayıcı olarak, ilk olarak yürütülür ve diğer ITestHostEnvironmentVariableProvider tüm kullanıcı uzantıları için varsayılan ortam değişkenlerine erişim verir.

Uzantınız yoğun bir başlatma gerektiriyorsa ve async/await desenini kullanmanız gerekiyorsa, Async extension initialization and cleanup öğesine başvurabilirsiniz. Uzantı noktaları arasında durum paylaşmanız gerekiyorsa, bölümüne başvurabilirsiniz.

ITestHostProcessLifetimeHandler uzantılar

ITestHostProcessLifetimeHandler, test konağı işlemini dış açıdan gözlemlemenizi sağlayan işlem dışı bir uzantıdır. Bu, uzantınızın test altındaki kod tarafından kaynaklanabilecek olası kilitlenmelerden veya donmalardan etkilenmemesini sağlar. Bu uzantı noktasını kullanmak, mimari bölümünde ayrıntılı olarak açıklandığı gibi test platformunun yeni bir konak başlatmasını tetikler.

Özel bir ITestHostProcessLifetimeHandler kaydetmek için aşağıdaki API'yi kullanın.

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Fabrika, test platformu tarafından sunulan hizmet paketine erişim elde etmek için IServiceProvider kullanır.

Önemli

API'ler kaydedildikleri sırayla çağrıldıklarından kayıt sırası önemlidir.

Arabirim ITestHostProcessLifetimeHandler aşağıdaki yöntemleri içerir:

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, tüm ITestHostControllersExtension uzantıları için temel olarak hizmet veren bir türüdür. Diğer tüm uzantı noktaları gibi IExtension'dan da miras alır. Bu nedenle, diğer tüm uzantılarda olduğu gibi API'yi kullanarak etkinleştirmeyi veya devre dışı bırakmayı IExtension.IsEnabledAsync seçebilirsiniz.

Bu API için aşağıdaki ayrıntıları göz önünde bulundurun:

BeforeTestHostProcessStartAsync: Bu yöntem, test konaklarını başlatan test platformundan önce çağrılır.

OnTestHostProcessStartedAsync: Bu yöntem, test konağı başlatıldıktan hemen sonra çağrılır. Bu yöntem, test konağı işlem sonucuyla ilgili temel ayrıntıları sağlayan arabirimini uygulayan ITestHostProcessInformation bir nesne sunar.

Önemli

Bu yöntemin çağrılması test konağı yürütmesini durdurmaz. Duraklatmanız gerekiyorsa, gibi bir uzantı kaydetmeniz ve bunu ITestHostApplicationLifetime ile eşitlemeniz gerekir.

OnTestHostProcessExitedAsync: Test paketi yürütmesi tamamlandığında bu yöntem çağrılır. Bu yöntem, test konağı işleminin ITestHostProcessInformation sonucuyla ilgili önemli ayrıntıları aktaran arabirime bağlı bir nesne sağlar.

ITestHostProcessInformation Arabirim aşağıdaki ayrıntıları sağlar:

  • PID: Test ana bilgisayarının işlem kimliği.
  • ExitCode: İşlemin çıkış kodu. Bu değer yalnızca yönteminde OnTestHostProcessExitedAsync kullanılabilir. OnTestHostProcessStartedAsync yönteminin içinde erişilmeye çalışılması bir hatayla sonuçlanır.
  • HasExitedGracefully: Test ana bilgisayarının çöküp çökmediğini gösteren bir boole değeri. True ise, test ana bilgisayarının düzgün bir şekilde çıkmadığını gösterir.

Uzantınızı TestingPlatformBuilderHook ile otomatik olarak kaydedin

Önceki her uzantı bölümünde el ile yapılan bir kayıt çağrısı gösterilir (örneğin, builder.TestHost.AddDataConsumer(...)). Kullanıcılardan Main yöntemlerini düzenlemelerini istemek, kötü bir ilk kullanım deneyimidir. Microsoft.Testing.Platform.MSBuild paketi, otomatik oluşturulan giriş noktasından çalışan bir SelfRegisteredExtensions.AddSelfRegisteredExtensions(builder, args) yöntemi oluşturarak bunu çözer. Uzantınızı bu oluşturulan yönteme bağlamak için NuGet paketinize iki öğe ekleyin:

  • Uzantınızı kaydeden bir TestingPlatformBuilderHook yöntemine sahip public static AddExtensions sınıf.
  • O sınıfa işaret eden bir <TestingPlatformBuilderHook> öğesi bildiren bir MSBuild props dosyası.

Birisi paketinizi yüklediğinde, MSBuild tümleştirmesi öğeyi algılar ve hook’unuza yönelik çağrıyı oluşturur; böylece uzantınız, kullanan tarafında herhangi bir kod değişikliği gerektirmeden kaydedilmiş olur.

Uyarı

Otomatik kayıt yalnızca kullanıcının projesinde Microsoft.Testing.Platform.MSBuild bulunduğunda (MSTest, NUnit ve xUnit çalıştırıcıları tarafından geçişli olarak eklenir) ve <GenerateTestingPlatformEntryPoint>false</GenerateTestingPlatformEntryPoint> ayarlanarak devre dışı bırakılmadığında çalışır. Otomatik olarak oluşturulan giriş noktasını devre dışı bırakmak isteyen tüketicilerin yine de kendi yöntemlerinden el ile kayıt API'nizi çağırmaları Main gerekir.

Hook sınıfını oluşturun

Uzantı derlemenize, kullanıcıların normalde manuel olarak çağıracağı aynı kaydı yapan bir public static class TestingPlatformBuilderHook yöntemi ile bir AddExtensions(ITestApplicationBuilder, string[]) ekleyin:

using Microsoft.Testing.Platform.Builder;

namespace Contoso.MyExtension;

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

Sınıf adının TestingPlatformBuilderHook olması gerekmez( MSBuild öğesi tam tür adıyla işaret eder) ancak bu adı kullanmak kodunuzun Microsoft.Testing.Extensions.Retry ve Microsoft.Testing.Extensions.HotReload gibi yerleşik uzantılarla tutarlı olmasını sağlar.

Yöntemin şu şekilde olması gerekir:

  • public static olun.
  • Microsoft.Testing.Platform.Builder.ITestApplicationBuilder türünde ilk parametreye sahip olun.
  • string[] türünde ikinci bir parametreye sahip olun (test ana bilgisayarına geçirilen komut satırı bağımsız değişkenleri). Uzantınızın buna ihtiyacı yoksa bunu yok sayabilirsiniz.
  • değerini döndürür void.

MSBuild öğesini bildirme

NuGet paketinizde buildMultiTargeting/<PackageId>.props altında bir props dosyası ekleyin. MSBuild görevini kanca sınıfınıza yönlendiren bir <TestingPlatformBuilderHook> öğesi bildirin:

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

Meta veriler aşağıdaki gibidir:

  • Include: Webhook’unuzu benzersiz şekilde tanımlayan bir GUID. Bkz. GUID rastgele bir tanımlayıcıdır.Include
  • DisplayName: Giriş noktası oluşturulduğunda MSBuild tanılama iletilerinde gösterilen kolay anlaşılır ad. Paket veya uzantı adınızı kullanın.
  • TypeFullName: Daha önce oluşturduğunuz sınıfın TestingPlatformBuilderHook tam adı. MSBuild görevi, global::Contoso.MyExtension.TestingPlatformBuilderHook.AddExtensions(builder, args); öğesini oluşturulan giriş noktasına eklemek için bunu kullanır.

Include GUID rastgele bir tanımlayıcıdır

Özniteliğindeki Include GUID, uzantınızın ile aynı IExtension.Uid. Bu, MSBuild görevinin NuGet başvuruları genelinde kancaları tekilleştirmek ve (iyi bilinen birkaç durumda) bunlara sıra vermek için kullandığı bir kayıt tanımlayıcısıdır.

Yeni bir uzantı yazarken, yepyeni bir GUID oluşturun ve bunu props dosyanızda sabit kodlayın. Bir tane oluşturmanın bazı yolları:

  • Powershell: [guid]::NewGuid()
  • Visual Studio: Tools> GUID oluştur
  • uuidgen Linux ve macOS'ta

Önemli

Guid'i hiçbir zaman başka bir uzantının props dosyasından (Microsoft veya üçüncü taraf tarafından gönderilir) kopyalamayın. Aynı Include değerine sahip olan iki uzantı yinelenen olarak değerlendirilir: yalnızca bir hook çağrılır, bu nedenle uzantınız sessizce kayıt olmaz.

Uyarı

Bir GUID’yi yayınladıktan sonra, onu kalıcı kabul edin. Sonraki bir sürümde değiştirmek kendi başına zararsızdır, ancak gelecekteki bir paket sürümünde farklı bir kanca için eski değerin yeniden kullanılabilir olması, yükseltme sırasında her iki sürümü de bağımlılık grafiğinde olan tüketicilerin kafasını karıştırabilir.

Kancanın bağlı olduğunu doğrulayın

Paketinizi Microsoft.Testing.Platform.MSBuild kullanan bir test projesine yükledikten sonra projeyi derleyin ve SelfRegisteredExtensions.g.cs altında oluşturulan obj/<Configuration>/<TargetFramework>/ dosyasını inceleyin. Örneğin, hook’unuza yapılan bir çağrı görmelisiniz:

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

Çağrı eksikse, props dosyasının buildMultiTargeting/ içinde build/ altında paketlendiğini (.nupkg değil), DisplayName ve TypeFullName meta verilerinin mevcut olduğunu ve tüketicinin <GenerateTestingPlatformEntryPoint>false</GenerateTestingPlatformEntryPoint> ayarlamadığını bir kez daha denetleyin.

Eklentiler yürütme sırası

Test platformu, bir test çerçevesi ve işlem içinde veya işlem dışı çalışabilen herhangi bir sayıda uzantıdan oluşur. Bu belge, bir özelliğin çağrılacağı zaman netlik sağlamak için tüm olası genişletilebilirlik noktalarına yapılan çağrıların sırasını özetler:

  1. ITestHostEnvironmentVariableProvider.UpdateAsync : İşlem dışı
  2. ITestHostEnvironmentVariableProvider.ValidateTestHostEnvironmentVariablesAsync : İşlem dışı
  3. ITestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync : İşlem dışı
  4. Test ana bilgisayar süreci başlangıcı
  5. ITestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync : İşlem dışındaki süreçte, bu olay yarış koşullarına bağlı olarak işlem içi uzantıların eylemlerini iç içe geçirebilir.
  6. ITestHostApplicationLifetime.BeforeRunAsync: İşlem içi
  7. ITestSessionLifetimeHandler.OnTestSessionStartingAsync: İşlemde
  8. ITestFramework.CreateTestSessionAsync: İşlem içi
  9. ITestFramework.ExecuteRequestAsync: İşlem sırasında bu yöntem bir veya daha fazla kez çağrılabilir. Bu noktada, test çerçevesi IDataConsumer tarafından kullanılabilecek bilgileri IMessageBus'a iletecektir.
  10. ITestFramework.CloseTestSessionAsync: İşlem içi
  11. ITestSessionLifetimeHandler.OnTestSessionFinishingAsync: İşlemde
  12. ITestHostApplicationLifetime.AfterRunAsync: İşlem içi
  13. İşlem içi temizleme, tüm uzantı noktalarında dispose ve IAsyncCleanableExtension çağrılarını içerir.
  14. ITestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync : Süreç dışı
  15. İşlem dışı temizleme, tüm uzantı noktalarında dispose ve IAsyncCleanableExtension çağrılarını içerir.

Uzantı yardımcıları

Test platformu, uzantıların uygulanmasını basitleştirmek için bir dizi yardımcı sınıf ve arabirim sağlar. Bu yardımcılar geliştirme sürecini kolaylaştırmak ve uzantının platformun standartlarına uygun olmasını sağlamak için tasarlanmıştır.

Eşzamansız eklenti başlatma ve temizleme

Test çerçevesinin ve uzantıların fabrikalar aracılığıyla oluşturulması, zaman uyumlu oluşturucuları kullanan standart .NET nesne oluşturma mekanizmasına bağlıdır. Bir uzantı yoğun bir başlatma gerektiriyorsa (dosya sistemine veya ağa erişim gibi), oluşturucuların yerine void döndürmesi nedeniyle async/await desenini oluşturucuda kullanamaz.

Bu nedenle, test platformu basit bir arabirim aracılığıyla async/await desenini kullanarak bir uzantı başlatmak için bir yöntem sağlar. Simetri için, uzantıların kolayca kullanabileceği temizleme için asenkron bir arabirim de sunar.

public interface IAsyncInitializableExtension
{
    Task InitializeAsync();
}

public interface IAsyncCleanableExtension
{
    Task CleanupAsync();
}

IAsyncInitializableExtension.InitializeAsync: Bu yöntemin oluşturma fabrikasından sonra çağrılacağı garanti edilir.

IAsyncCleanableExtension.CleanupAsync: Bu yöntemin, test oturumunun sonlandırılması sırasında varsayılan veya DisposeAsync öncesinde en az bir kez çağrılacağı garanti edilir.

Önemli

Standart Dispose yönteme benzer şekilde, CleanupAsync birden çok kez çağrılabilir. Bir nesnenin CleanupAsync yöntemi birden fazla kez çağrılırsa, nesne ilk çağrıdan sonrakileri görmezden gelmelidir. Yöntemi birden çok kez çağrılırsa CleanupAsync nesne özel durum oluşturmamalıdır.

Uyarı

Varsayılan olarak, test platformu kullanılabilirse veya DisposeAsync uygulandıysa çağırırDispose. Test platformu her iki dispose yöntemini de çağırmayacak, ancak eğer uygulanmışsa async olanına öncelik verecektir.

CompositeExtensionFactory<T>

Uzantılar bölümünde açıklandığı gibi test platformu, işlem içinde ve dışında özel uzantıları dahil etmek için arabirimler uygulamanıza olanak tanır.

Her arabirim belirli bir özelliği ele alır ve .NET tasarıma göre bu arabirimi belirli bir nesneye uygularsınız. Uzantıyı, ilgili bölümlerde ayrıntılı olarak açıklandığı üzere AddXXX, TestHost veya TestHostController objesinden ITestApplicationBuilder belirli kayıt API’sini kullanarak kaydedebilirsiniz.

Ancak, iki uzantı arasında durum paylaşmanız gerekiyorsa, farklı arabirimler uygulayan farklı nesneleri uygulayıp kaydedebilmeniz, paylaşımı zor bir görev haline getirir. Herhangi bir yardım olmadan, bilgileri paylaşmak için bir uzantıyı diğerine geçirmenin bir yolu olması gerekir ve bu da tasarımı karmaşıklaştırır.

Bu nedenle, test platformu aynı türü kullanarak birden çok uzantı noktası uygulamak için gelişmiş bir yöntem sağlar ve bu da veri paylaşımını basit bir görev haline getirir. Tek yapmanız gereken, tek bir arabirim uygulaması için yaptığınız gibi aynı API kullanılarak kaydedilebilen komutunu kullanmaktır CompositeExtensionFactory<T>.

Örneğin, hem ITestSessionLifetimeHandlerhem de IDataConsumer uygulayan bir tür düşünün. Bu yaygın bir senaryodur çünkü genellikle test çerçevesinden bilgi toplamak istersiniz ve ardından test oturumu sona erdiğinde, ve IMessageBus kullanarak eserinizi gönderirsiniz.

Yapmanız gereken, normal olarak arabirimleri uygulamaktır:

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

Türünüz için CompositeExtensionFactory<CustomExtension> öğesini oluşturduktan sonra, hem IDataConsumer hem de ITestSessionLifetimeHandler API'lerine kaydedebilirsiniz, bu da CompositeExtensionFactory<T> için bir aşırı yükleme işlevi sunar.

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

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

Fabrika oluşturucu, test platformu tarafından sağlanan hizmetlere erişmek için IServiceProvider kullanır.

Test platformu, bileşik uzantının yaşam döngüsünü yönetmekten sorumlu olacaktır.

Test platformunun, hem işlem içi hem de işlem dışı uzantılar için desteği nedeniyle, herhangi bir uzantı noktasını kendi istediğiniz şekilde birleştirmenin mümkün olmadığını belirtmek önemlidir. Uzantıların oluşturulması ve kullanılması konak türüne bağlıdır, yani yalnızca işlem içi (TestHost) ve işlem dışı (TestHostController) uzantıları birlikte gruplandırabilirsiniz.

Aşağıdaki birleşimler olasıdır:

  • ITestApplicationBuilder.TestHost için IDataConsumer ve ITestSessionLifetimeHandler öğelerini birleştirebilirsiniz.
  • ITestApplicationBuilder.TestHostControllers için ITestHostEnvironmentVariableProvider ve ITestHostProcessLifetimeHandler öğelerini birleştirebilirsiniz.

Uyarı

IDataConsumer, işlem içi bir uzantıdır; bu nedenle özel tüketiciler yalnızca builder.TestHost aracılığıyla ( CompositeExtensionFactory<T> aracılığıyla olanlar dahil) kaydedilir. builder.TestHostControllers üzerinde bir IDataConsumer kaydetmek için genel kullanıma açık bir API yok.