Bagikan melalui


Membangun ekstensi untuk Microsoft.Testing.Platform

Artikel ini membahas poin ekstensibilitas untuk Microsoft.Testing.Platform di luar kerangka kerja pengujian itu sendiri. Untuk pembuatan kerangka kerja pengujian, lihat Membangun kerangka kerja pengujian.

Untuk ringkasan titik ekstensi lengkap dan konsep dalam proses/di luar proses, lihat Membuat ekstensi kustom.

Poin perluasan

Platform pengujian menyediakan titik ekstensibilitas tambahan yang memungkinkan Anda menyesuaikan perilaku platform dan kerangka kerja pengujian. Titik ekstensibilitas ini bersifat opsional dan dapat digunakan untuk meningkatkan pengalaman pengujian.

Ekstensi ICommandLineOptionsProvider

Nota

Saat memperluas API ini, ekstensi kustom akan ada baik masuk maupun keluar dari proses host pengujian.

Seperti yang dibahas di bagian arsitektur , langkah awal melibatkan pembuatan ITestApplicationBuilder untuk mendaftarkan kerangka kerja pengujian dan ekstensi dengannya.

var builder = await TestApplication.CreateBuilderAsync(args);

Metode CreateBuilderAsync menerima array string (string[]) bernama args. Argumen ini dapat digunakan untuk meneruskan opsi baris perintah ke semua komponen platform pengujian (termasuk komponen bawaan, kerangka kerja pengujian, dan ekstensi), memungkinkan penyesuaian perilaku mereka.

Biasanya, argumen yang diteruskan adalah argumen yang diterima dalam metode standar Main(string[] args) . Namun, jika lingkungan hosting berbeda, daftar argumen apa pun dapat disediakan.

Argumen harus diawali dengan dua garis miring --. Contohnya, --filter.

Jika komponen seperti kerangka kerja pengujian atau titik ekstensi ingin menawarkan opsi baris perintah kustom, komponen tersebut dapat melakukannya dengan mengimplementasikan ICommandLineOptionsProvider antarmuka. Implementasi ini kemudian dapat didaftarkan dengan ITestApplicationBuilder melalui fasilitas pendaftaran properti CommandLine, seperti yang ditunjukkan.

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

Dalam contoh yang disediakan, CustomCommandLineOptions adalah implementasi ICommandLineOptionsProvider antarmuka, Antarmuka ini terdiri dari anggota dan jenis data berikut:

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

Seperti yang diamati, ICommandLineOptionsProvider memperluas IExtension antarmuka. Oleh karena itu, seperti ekstensi lainnya, Anda dapat memilih untuk mengaktifkan atau menonaktifkannya menggunakan IExtension.IsEnabledAsync API.

Urutan eksekusi ICommandLineOptionsProvider adalah:

Diagram yang mewakili urutan eksekusi antarmuka 'ICommandLineOptionsProvider'.

Mari kita periksa API dan maksudnya.

ICommandLineOptionsProvider.GetCommandLineOptions(): Metode ini digunakan untuk mengambil semua opsi yang ditawarkan oleh komponen. Masing-masing CommandLineOption memerlukan properti berikut untuk ditentukan:

string name: Ini adalah nama opsi, disajikan tanpa tanda hubung. Misalnya, filter akan digunakan sebagai --filter oleh pengguna.

string description: Ini adalah deskripsi opsi. Ini akan ditampilkan ketika pengguna meneruskan --help sebagai argumen ke pembuat aplikasi.

ArgumentArity arity: Aritas opsi adalah jumlah nilai yang dapat diteruskan jika opsi atau perintah tersebut ditentukan. Aritas yang tersedia saat ini adalah:

  • Zero: Mewakili aritas argumen nol.
  • ZeroOrOne: Mewakili aritas argumen nol atau satu.
  • ZeroOrMore: Mewakili aritas argumen nol atau lebih.
  • OneOrMore: Mewakili aritas argumen dari satu atau beberapa.
  • ExactlyOne: Mewakili aritas dari argumen yang hanya satu.

Untuk contoh-contoh, lihat tabel aritas System.CommandLine.

bool isHidden: Properti ini menandakan bahwa opsi tersedia untuk digunakan tetapi tidak akan ditampilkan dalam deskripsi saat --help dipanggil.

ICommandLineOptionsProvider.ValidateOptionArgumentsAsync: Metode ini digunakan untuk memvalidasi argumen yang disediakan oleh pengguna.

Misalnya, jika Anda memiliki parameter bernama --dop yang mewakili tingkat paralelisme untuk kerangka kerja pengujian kustom kami, pengguna mungkin memasukkan --dop 0. Dalam skenario ini, nilai 0 akan tidak valid karena diharapkan memiliki tingkat paralelisme 1 atau lebih. Dengan menggunakan ValidateOptionArgumentsAsync, Anda dapat melakukan validasi di muka dan mengembalikan pesan kesalahan jika perlu.

Implementasi yang mungkin untuk sampel di atas dapat berupa:

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: Metode ini disebut sebagai yang terakhir dan memungkinkan untuk melakukan pemeriksaan koherensi global.

Misalnya, kerangka kerja pengujian kami memiliki kemampuan untuk menghasilkan laporan hasil pengujian dan menyimpannya ke file. Fitur ini diakses menggunakan --generatereport opsi , dan nama file ditentukan dengan --reportfilename myfile.rep. Dalam skenario ini, jika pengguna hanya menyediakan --generatereport opsi tanpa menentukan nama file, validasi harus gagal karena laporan tidak dapat dihasilkan tanpa nama file. Implementasi yang mungkin untuk sampel di atas dapat berupa:

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

Harap dicatat bahwa metode ValidateCommandLineOptionsAsync ini menyediakan layanan ICommandLineOptions, yang digunakan untuk mengambil informasi argumen yang diurai oleh platform itu sendiri.

Ekstensi ITestSessionLifetimeHandler

ITestSessionLifeTimeHandler adalah ekstensi dalam proses yang memungkinkan eksekusi kode sebelum dan sesudah sesi pengujian.

Untuk mendaftarkan kustom ITestSessionLifeTimeHandler, gunakan API berikut:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Pabrik ini menggunakan IServiceProvider untuk mendapatkan akses ke rangkaian layanan yang ditawarkan oleh platform pengujian.

Penting

Urutan pendaftaran signifikan, karena API dipanggil dalam urutan pendaftaran.

Antarmuka ITestSessionLifeTimeHandler mencakup metode berikut:

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 adalah jenis ITestHostExtension, yang berfungsi sebagai dasar untuk semua ekstensi test host pengujian. Seperti semua titik ekstensi lainnya, ia juga mewarisi dari IExtension. Oleh karena itu, seperti ekstensi lainnya, Anda dapat memilih untuk mengaktifkan atau menonaktifkannya menggunakan IExtension.IsEnabledAsync API.

Pertimbangkan detail berikut untuk API ini:

OnTestSessionStartingAsync: Metode ini dipanggil sebelum dimulainya sesi pengujian dan menerima SessionUid objek, yang menyediakan pengidentifikasi buram untuk sesi pengujian saat ini.

OnTestSessionFinishingAsync: Metode ini dipanggil setelah selesainya sesi pengujian, memastikan bahwa kerangka kerja pengujian telah selesai menjalankan semua pengujian dan telah melaporkan semua data yang relevan ke platform. Biasanya, dalam metode ini, ekstensi menggunakan IMessageBus untuk mengirimkan aset atau data kustom ke bus platform bersama. Metode ini juga dapat memberi sinyal ke ekstensi kustom di luar proses bahwa sesi pengujian telah ditutup.

Akhirnya, kedua API mengambil CancellationToken yang ekstensinya diharapkan untuk mematuhi.

Jika ekstensi Anda memerlukan inisialisasi intensif dan Anda perlu menggunakan pola asinkron/tunggu, Anda dapat merujuk ke Async extension initialization and cleanup. Jika Anda perlu berbagi status di antara titik ekstensi, Anda dapat merujuk ke bagian tersebut CompositeExtensionFactory<T> .

Ekstensi ITestApplicationLifecycleCallbacks

ITestApplicationLifecycleCallbacks merupakan ekstensi dalam proses yang memungkinkan eksekusi kode sebelum semuanya, ibarat memiliki akses ke baris pertama dari hipotetis utama dari pengujian host.

Untuk mendaftarkan kustom ITestApplicationLifecycleCallbacks, gunakan api berikut:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Pabrik ini menggunakan IServiceProvider untuk mendapatkan akses ke rangkaian layanan yang ditawarkan oleh platform pengujian.

Penting

Urutan pendaftaran signifikan, karena API dipanggil dalam urutan pendaftaran.

Antarmuka ITestApplicationLifecycleCallbacks mencakup metode berikut:

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

    Task AfterRunAsync(
        int exitCode,
        CancellationToken cancellation);
}

public interface ITestHostExtension : IExtension
{
}

ITestApplicationLifecycleCallbacks adalah jenis ITestHostExtension, yang berfungsi sebagai dasar untuk semua ekstensi test host pengujian. Seperti semua titik ekstensi lainnya, ia juga mewarisi dari IExtension. Oleh karena itu, seperti ekstensi lainnya, Anda dapat memilih untuk mengaktifkan atau menonaktifkannya menggunakan IExtension.IsEnabledAsync API.

BeforeRunAsync: Metode ini berfungsi sebagai titik awal kontak untuk host pengujian dan merupakan kesempatan pertama bagi ekstensi dalam proses untuk menjalankan fitur. Ini biasanya digunakan untuk membangun koneksi dengan ekstensi yang sesuai di luar proses jika fitur dirancang untuk beroperasi di kedua lingkungan.

Misalnya, fitur hang dump bawaan terdiri dari ekstensi dalam proses dan di luar proses , dan metode ini digunakan untuk bertukar informasi dengan komponen ekstensi yang tidak diproses .

AfterRunAsync: Metode ini adalah panggilan akhir sebelum keluar int ITestApplication.RunAsync() dan menyediakan exit code. Ini harus digunakan hanya untuk tugas pembersihan dan untuk memberi tahu ekstensi di luar proses yang sesuai bahwa host pengujian akan dihentikan.

Akhirnya, kedua API mengambil CancellationToken yang ekstensinya diharapkan untuk mematuhi.

Ekstensi IDataConsumer

IDataConsumer adalah ekstensi dalam-proses yang mampu berlangganan dan menerima informasi yang didorong ke IData oleh kerangka pengujian dan ekstensinya.

Titik ekstensi ini sangat penting karena memungkinkan pengembang untuk mengumpulkan dan memproses semua informasi yang dihasilkan selama sesi pengujian.

Untuk mendaftarkan kustom IDataConsumer, gunakan api berikut:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Pabrik ini menggunakan IServiceProvider untuk mendapatkan akses ke rangkaian layanan yang ditawarkan oleh platform pengujian.

Penting

Urutan pendaftaran signifikan, karena API dipanggil dalam urutan pendaftaran.

Antarmuka IDataConsumer mencakup metode berikut:

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 adalah jenis ITestHostExtension, yang berfungsi sebagai dasar untuk semua ekstensi test host pengujian. Seperti semua titik ekstensi lainnya, ia juga mewarisi dari IExtension. Oleh karena itu, seperti ekstensi lainnya, Anda dapat memilih untuk mengaktifkan atau menonaktifkannya menggunakan IExtension.IsEnabledAsync API.

DataTypesConsumed: Properti ini mengembalikan daftar Type yang akan digunakan oleh ekstensi ini. Ini sesuai dengan IDataProducer.DataTypesProduced. Secara khusus, sebuah IDataConsumer dapat berlangganan berbagai jenis yang berasal dari instans IDataProducer yang berbeda tanpa masalah apa pun.

ConsumeAsync: Metode ini dipicu setiap kali data jenis tempat konsumen saat ini berlangganan didorong ke IMessageBus. Ini menerima IDataProducer untuk memberikan detail tentang produsen payload data, serta payloadnya IData sendiri. Seperti yang Anda lihat, IData adalah antarmuka tempat penampung generik yang berisi data informatif umum. Kemampuan untuk mengelola berbagai tipeIData menyiratkan bahwa konsumen perlu beralih pada tipe tersebut untuk mengonversinya ke tipe yang benar dan mengakses informasi spesifik.

Contoh implementasi konsumen yang ingin menguraikan TestNodeUpdateMessage yang dihasilkan oleh kerangka kerja pengujian dapat berupa:

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

Akhirnya, API menerima CancellationToken yang harus dipatuhi oleh ekstensi tersebut.

Penting

Sangat penting untuk memproses payload langsung dalam metode ConsumeAsync. IMessageBus dapat mengelola pemrosesan sinkron dan asinkron, mengoordinasikan eksekusi dengan kerangka kerja pengujian. Meskipun proses konsumsi sepenuhnya asinkron dan tidak memblokir IMessageBus.Push pada saat penulisan, ini adalah detail implementasi yang dapat berubah di masa depan karena persyaratan di masa mendatang. Namun, platform memastikan bahwa metode ini selalu dipanggil sekali, menghilangkan kebutuhan akan sinkronisasi yang kompleks, serta mengelola skalabilitas konsumen.

Peringatan

Saat menggunakan IDataConsumer bersama dengan ITestHostProcessLifetimeHandler dalam poin ekstensi komposit, sangat penting untuk mengabaikan data apa pun yang diterima setelah eksekusi ITestSessionLifetimeHandler.OnTestSessionFinishingAsync. OnTestSessionFinishingAsync adalah kesempatan terakhir untuk memproses akumulasi data dan mengirimkan informasi baru ke IMessageBus, oleh karena itu, data apa pun yang digunakan di luar titik ini tidak akan dapat digunakan oleh ekstensi.

Jika ekstensi Anda memerlukan inisialisasi intensif dan Anda perlu menggunakan pola asinkron/tunggu, Anda dapat merujuk ke Async extension initialization and cleanup. Jika Anda perlu berbagi status di antara titik ekstensi, Anda dapat merujuk ke bagian tersebut CompositeExtensionFactory<T> .

Ekstensi ITestHostEnvironmentVariableProvider

ITestHostEnvironmentVariableProvider adalah ekstensi di luar proses yang memungkinkan Anda membuat variabel lingkungan kustom untuk host pengujian. Menggunakan titik ekstensi ini memastikan bahwa platform pengujian akan memulai host baru dengan variabel lingkungan yang sesuai, seperti yang dirinci di bagian arsitektur .

Untuk mendaftarkan kustom ITestHostEnvironmentVariableProvider, gunakan API berikut:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Pabrik ini menggunakan IServiceProvider untuk mendapatkan akses ke rangkaian layanan yang ditawarkan oleh platform pengujian.

Penting

Urutan pendaftaran signifikan, karena API dipanggil dalam urutan pendaftaran.

Antarmuka ITestHostEnvironmentVariableProvider mencakup metode dan jenis berikut:

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 adalah jenis ITestHostControllersExtension, yang berfungsi sebagai dasar untuk semua ekstensi pengontrol host pengujian. Seperti semua titik ekstensi lainnya, ia juga mewarisi dari IExtension. Oleh karena itu, seperti ekstensi lainnya, Anda dapat memilih untuk mengaktifkan atau menonaktifkannya menggunakan IExtension.IsEnabledAsync API.

Pertimbangkan detail untuk API ini:

UpdateAsync: API pembaruan ini menyediakan instans objek IEnvironmentVariables, tempat Anda dapat memanggil metode SetVariable atau RemoveVariable metode. Saat menggunakan SetVariable, Anda harus meneruskan objek jenis EnvironmentVariable, yang memerlukan spesifikasi berikut:

  • Variable: Nama variabel lingkungan.
  • Value: Nilai variabel lingkungan.
  • IsSecret: Ini menunjukkan apakah variabel lingkungan berisi informasi sensitif yang tidak boleh dicatat atau dapat diakses melalui TryGetVariable.
  • IsLocked: Ini menentukan apakah ekstensi lain ITestHostEnvironmentVariableProvider dapat memodifikasi nilai ini.

ValidateTestHostEnvironmentVariablesAsync: Metode ini dipanggil setelah semua metode UpdateAsync dari instans ITestHostEnvironmentVariableProvider yang terdaftar telah dipanggil. Ini memungkinkan Anda untuk memverifikasi pengaturan variabel lingkungan yang benar. Dibutuhkan objek yang mengimplementasikan IReadOnlyEnvironmentVariables, yang menyediakan TryGetVariable sebagai metode untuk mendapatkan informasi tentang variabel lingkungan tertentu dengan jenis objek OwnedEnvironmentVariable. Setelah validasi, Anda mengembalikan sebuah ValidationResult yang berisi alasan kegagalan apa pun.

Nota

Platform pengujian, secara default, mengimplementasikan dan mendaftarkan SystemEnvironmentVariableProvider. Penyedia ini memuat semua variabel lingkungan saat ini . Sebagai penyedia terdaftar pertama, ia menjalankan terlebih dahulu, memberikan akses ke variabel lingkungan default untuk semua ekstensi pengguna lainnya ITestHostEnvironmentVariableProvider .

Jika ekstensi Anda memerlukan inisialisasi intensif dan Anda perlu menggunakan pola asinkron/tunggu, Anda dapat merujuk ke Async extension initialization and cleanup. Jika Anda perlu berbagi status di antara titik ekstensi, Anda dapat merujuk ke bagian tersebut CompositeExtensionFactory<T> .

Ekstensi ITestHostProcessLifetimeHandler

ITestHostProcessLifetimeHandler adalah ekstensi di luar proses yang memungkinkan Anda mengamati proses host pengujian dari sudut pandang eksternal. Ini memastikan bahwa ekstensi Anda tetap tidak terpengaruh oleh potensi crash atau hang yang dapat diinduksi oleh kode yang sedang diuji. Menggunakan titik ekstensi ini akan menginstruksikan platform pengujian untuk memulai host yang baru, sebagaimana dirincikan dalam bagian arsitektur.

Untuk mendaftarkan kustom ITestHostProcessLifetimeHandler, gunakan API berikut:

var builder = await TestApplication.CreateBuilderAsync(args);

// ...

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

Pabrik ini menggunakan IServiceProvider untuk mendapatkan akses ke rangkaian layanan yang ditawarkan oleh platform pengujian.

Penting

Urutan pendaftaran signifikan, karena API dipanggil dalam urutan pendaftaran.

Antarmuka ITestHostProcessLifetimeHandler mencakup metode berikut:

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 adalah jenis ITestHostControllersExtension, yang berfungsi sebagai dasar untuk semua ekstensi pengontrol host pengujian. Seperti semua titik ekstensi lainnya, ia juga mewarisi dari IExtension. Oleh karena itu, seperti ekstensi lainnya, Anda dapat memilih untuk mengaktifkan atau menonaktifkannya menggunakan IExtension.IsEnabledAsync API.

Pertimbangkan detail berikut untuk API ini:

BeforeTestHostProcessStartAsync: Metode ini dipanggil sebelum platform pengujian memulai host pengujian.

OnTestHostProcessStartedAsync: Metode ini dipanggil segera setelah host pengujian dimulai. Metode ini menawarkan objek yang mengimplementasikan ITestHostProcessInformation antarmuka, yang menyediakan detail utama tentang hasil proses host pengujian.

Penting

Pemanggilan metode ini tidak menghentikan eksekusi host pengujian. Jika Anda perlu menjeda, Anda harus mendaftarkan ekstensi dalam proses seperti dan menyinkronkannya dengan ekstensi luar proses.

OnTestHostProcessExitedAsync: Metode ini dipanggil ketika eksekusi rangkaian pengujian selesai. Metode ini menyediakan objek yang mematuhi ITestHostProcessInformation antarmuka, yang menyampaikan detail penting tentang hasil proses host pengujian.

Antarmuka ITestHostProcessInformation menyediakan detail berikut:

  • PID: ID host proses pengujian.
  • ExitCode: Kode keluar dari proses. Nilai ini hanya tersedia dalam OnTestHostProcessExitedAsync metode . Mencoba mengaksesnya dalam OnTestHostProcessStartedAsync metode akan menghasilkan pengecualian.
  • HasExitedGracefully: Nilai boolean yang menunjukkan apakah host pengujian mengalami crash. Jika true, itu menandakan bahwa host pengujian tidak keluar dengan anggun.

Urutan eksekusi ekstensi

Platform pengujian terdiri dari kerangka kerja pengujian dan sejumlah ekstensi yang dapat beroperasi dalam proses atau di luar proses. Dokumen ini menguraikan urutan panggilan ke semua titik ekstensibilitas potensial untuk memberikan kejelasan tentang kapan fitur diantisipasi untuk dipanggil:

  1. ITestHostEnvironmentVariableProvider.UpdateAsync : Di luar proses
  2. ITestHostEnvironmentVariableProvider.ValidateTestHostEnvironmentVariablesAsync : Di luar proses
  3. ITestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync : Di luar proses
  4. Proses host pengujian dimulai
  5. ITestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync : Di luar proses, peristiwa ini dapat menghubungkan tindakan ekstensi dalam proses , tergantung pada kondisi balapan.
  6. ITestApplicationLifecycleCallbacks.BeforeRunAsync: Dalam proses
  7. ITestSessionLifetimeHandler.OnTestSessionStartingAsync: Dalam proses
  8. ITestFramework.CreateTestSessionAsync: Dalam proses
  9. ITestFramework.ExecuteRequestAsync: Dalam proses, metode ini dapat dipanggil satu atau beberapa kali. Pada titik ini, kerangka kerja pengujian akan mengirimkan informasi ke IMessageBus yang dapat digunakan oleh IDataConsumer.
  10. ITestFramework.CloseTestSessionAsync: Dalam proses
  11. ITestSessionLifetimeHandler.OnTestSessionFinishingAsync: Dalam proses
  12. ITestApplicationLifecycleCallbacks.AfterRunAsync: Dalam proses
  13. Pembersihan dalam proses melibatkan pemanggilan metode dispose dan IAsyncCleanableExtension pada semua titik ekstensi.
  14. ITestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync : Di luar proses
  15. Pembersihan di luar proses melibatkan pemanggilan dispose dan IAsyncCleanableExtension pada semua titik ekstensi.

Pembantu ekstensi

Platform pengujian menyediakan serangkaian kelas dan antarmuka pembantu untuk menyederhanakan implementasi ekstensi. Pembantu ini dirancang untuk menyederhanakan proses pengembangan dan memastikan bahwa ekstensi mematuhi standar platform.

Inisialisasi asinkron dan pembersihan ekstensi

Pembuatan kerangka kerja pengujian dan ekstensi melalui pabrik mematuhi mekanisme pembuatan objek .NET standar, yang menggunakan konstruktor sinkron. Jika ekstensi memerlukan inisialisasi intensif (seperti mengakses sistem file atau jaringan), ekstensi tidak dapat menggunakan pola asinkron/menunggu di konstruktor karena konstruktor mengembalikan kekosongan, bukan Task.

Oleh karena itu, platform pengujian menyediakan metode untuk menginisialisasi ekstensi menggunakan pola asinkron/tunggu melalui antarmuka sederhana. Agar simetri tetap terjaga, antarmuka asinkron juga ditawarkan untuk pembersihan yang dapat diimplementasikan oleh ekstensi dengan mulus.

public interface IAsyncInitializableExtension
{
    Task InitializeAsync();
}

public interface IAsyncCleanableExtension
{
    Task CleanupAsync();
}

IAsyncInitializableExtension.InitializeAsync: Metode ini dipastikan untuk dijalankan setelah pabrik pembuatan selesai.

IAsyncCleanableExtension.CleanupAsync: Metode ini dipastikan akan dipanggil setidaknya satu kali selama penghentian sesi pengujian, sebelum default DisposeAsync atau Dispose.

Penting

Mirip dengan metode standar Dispose , CleanupAsync dapat dipanggil beberapa kali. Jika metode objek CleanupAsync dipanggil lebih dari sekali, objek harus mengabaikan semua panggilan setelah yang pertama. Objek tidak boleh melemparkan pengecualian jika metodenya CleanupAsync dipanggil beberapa kali.

Nota

Secara default, platform pengujian akan memanggil DisposeAsync jika tersedia, atau Dispose jika diimplementasikan. Penting untuk dicatat bahwa platform pengujian tidak akan memanggil kedua metode pelepasan tetapi akan memprioritaskan metode yang bersifat asinkron jika diimplementasikan.

CompositeExtensionFactory<T>

Seperti yang diuraikan di bagian ekstensi , platform pengujian memungkinkan Anda menerapkan antarmuka untuk menggabungkan ekstensi kustom baik masuk maupun di luar proses.

Setiap antarmuka membahas fitur tertentu, dan sesuai dengan desain .NET, Anda mengimplementasikan antarmuka ini dalam objek tertentu. Anda dapat mendaftarkan ekstensi menggunakan API AddXXX pendaftaran dari objek TestHost atau TestHostController dari ITestApplicationBuilder, seperti yang dijelaskan di bagian terkait.

Namun, jika Anda perlu berbagi status antara dua ekstensi, fakta bahwa Anda dapat menerapkan dan mendaftarkan objek yang berbeda yang menerapkan antarmuka yang berbeda membuat berbagi tugas yang menantang. Tanpa bantuan apa pun, Anda memerlukan cara untuk meneruskan satu ekstensi ke ekstensi lainnya untuk berbagi informasi, yang mempersulit desain.

Oleh karena itu, platform pengujian menyediakan metode canggih untuk mengimplementasikan beberapa titik ekstensi menggunakan jenis yang sama, membuat berbagi data menjadi tugas yang mudah. Yang perlu Anda lakukan adalah menggunakan CompositeExtensionFactory<T>, yang kemudian dapat didaftarkan menggunakan API yang sama seperti yang Anda lakukan untuk implementasi antarmuka tunggal.

Misalnya, pertimbangkan jenis yang mengimplementasikan baik ITestSessionLifetimeHandler maupun IDataConsumer. Ini adalah skenario umum karena Anda sering ingin mengumpulkan informasi dari kerangka kerja pengujian dan kemudian ketika sesi pengujian selesai, Anda akan mengirimkan artefak Anda menggunakan dalam IMessageBus.

Apa yang harus Anda lakukan adalah mengimplementasikan antarmuka secara normal:

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

Setelah Anda membuat CompositeExtensionFactory<CustomExtension> untuk jenis Anda, Anda dapat mendaftarkannya dengan IDataConsumer dan ITestSessionLifetimeHandler API, yang menawarkan overload untuk 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 pabrik menggunakan IServiceProvider untuk mengakses layanan yang disediakan oleh platform pengujian.

Platform pengujian akan bertanggung jawab untuk mengelola siklus hidup ekstensi komposit.

Penting untuk dicatat bahwa karena dukungan platform pengujian untuk ekstensi dalam proses dan di luar proses , Anda tidak dapat menggabungkan titik ekstensi apa pun secara segan-segan. Pembuatan dan pemanfaatan ekstensi bersifat kontingen pada jenis host, yang berarti Anda hanya dapat mengelompokkan ekstensi dalam proses (TestHost) dan di luar proses (TestHostController) bersama-sama.

Kombinasi berikut dimungkinkan:

  • Untuk ITestApplicationBuilder.TestHost, Anda dapat menggabungkan IDataConsumer dan ITestSessionLifetimeHandler.
  • Untuk ITestApplicationBuilder.TestHostControllers, Anda dapat menggabungkan ITestHostEnvironmentVariableProvider dan ITestHostProcessLifetimeHandler.