Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V kontextu MTP funkce odkazuje na potenciál provést konkrétní akci nebo poskytnout konkrétní informace. Je to způsob, jak testovací architektura a rozšíření deklarovat jejich schopnostpracovat určitým způsobem nebo poskytovat konkrétní informace žadatelům .
žadatelé mohou být libovolnou komponentou zapojenou do testovací relace, jako je platforma, rozšíření nebo samotný testovací rámec.
Hlavním cílem systému schopností je usnadnit efektivní komunikaci mezi komponentami zapojenými do testovací relace, která jim umožní exchange informace a přesně splnit jejich potřeby.
Příklad s návodem
Představme si hypotetický příklad, který demonstruje nutnost systému schopností.
Poznámka
Tento příklad je čistě pro ilustrativní účely a v současné době není implementován v rámci MTP ani žádné testovací architektury.
Představte si situaci, kdy máte rozšíření, které vyžaduje, aby testovací architektura najednou nespustí více než jeden test. Kromě toho po každém testu musí rozšíření znát využití procesoru pro tento konkrétní test.
Pokud chcete vyhovět předchozímu scénáři, je potřeba se zeptat testovacího rámce, jestli:
- Má možnost provést najednou pouze jeden test.
- Může poskytnout informace týkající se množství procesoru spotřebovaného jednotlivými testy.
Jak může rozšíření určit, jestli testovací architektura má schopnost pracovat v tomto režimu a poskytovat informace o využití procesoru pro testovací relaci? V MTP je tato funkce reprezentována implementací rozhraní Microsoft.Testing.Platform.Capabilities.ICapability:
// Base capabilities contracts
public interface ICapability
{
}
public interface ICapabilities<TCapability>
where TCapability : ICapability
{
IReadOnlyCollection<TCapability> Capabilities { get; }
}
// Specific testing framework capabilities
public interface ITestFrameworkCapabilities : ICapabilities<ITestFrameworkCapability>
{
}
public interface ITestFrameworkCapability : ICapability
{
}
Jak vidíte, rozhraní ICapability je značkou rozhraní, protože může představovat jakékoli schopnostia skutečná implementace bude závislá na kontextu. Uvidíte také ITestFrameworkCapability, který dědí z ICapability ke klasifikaci schopností. Obecná povaha systému schopností umožňuje pohodlné seskupení podle kontextu.
ITestFrameworkCapability seskupí všechny možnosti implementované testovací architekturou. Rozhraní ICapabilities<TCapability> odhalí sadu všech funkcí implementovaných rozšířením. Podobně pro základ existuje kontextová testovací architektura s názvem ITestFrameworkCapabilities.
ITestFrameworkCapabilities se poskytuje platformě během procesu registrace testovacího frameworku.
Pokud chcete vytvořit funkci, která řeší výše uvedený scénář, definujete ji následujícím způsobem:
public interface IDisableParallelismCapability : ITestFrameworkCapability
{
bool CanDisableParallelism { get; }
bool CanProvidePerTestCpuConsumption { get; }
void Enable();
}
Pokud testovací architektura implementuje toto rozhraní za běhu, může být dotazováno následující:
- Ověřte, jestli testovací architektura má možnost vypnout paralelismus
CanDisableParallelism = true. - Zjistěte, jestli testovací architektura může poskytovat data o využití procesoru
CanProvidePerTestCPUConsumption = true. - Požádejte testovací adaptér o aktivaci tohoto režimu vyvoláním metody
Enable()před zahájením testovací relace.
Hypotetický fragment kódu uvnitř rozšíření by mohl vypadat přibližně takto:
IServiceProvider serviceProvider = null; // TODO: Get IServiceProvider.
var capabilities = serviceProvider.GetRequiredService<ITestFrameworkCapabilities>();
// Utilize the `GetCapability` API to search for the specific capability to query.
var capability = capabilities.GetCapability<IDisableParallelismCapability>();
if (capability is null)
{
// Capability not supported...
}
else
{
capability.Enable();
if (capability.CanDisableParallelism)
{
// Do something...
}
if (capability.CanProvidePerTestCpuConsumption)
{
// Do something...
}
}
Předchozí příklad ukazuje, jak infrastruktura schopností umožňuje výkonný mechanismus pro komunikaci schopností mezi komponentami zapojenými do testovací relace. I když ukázka demonstruje schopnost speciálně navrženou pro testovací architekturu, každá komponenta může vystavit a implementovat rozšíření, která dědí z ICapability.
Je zřejmé, že ne všechny podrobnosti lze komunikovat prostřednictvím rozhraní. Vzhledem k předchozímu příkladu, co by mělo rozšíření očekávat, jestliže je podpora CanProvidePerTestCpuConsumption zahrnuta? Jaký druh vlastních informací se očekává, že se budou přenášet prostřednictvím testovací architektury IMessageBus? Řešením je dokumentace schopnosti pro. Je odpovědností za schopnost vlastníka navrhnout, odeslat a zdokumentovat co nejjasněji implementátory, kteří chtějí efektivně spolupracovat s rozšířením, které vyžaduje konkrétní schopnost.
Rozšíření TRX reportu například umožňuje testovacímu rámci implementovat nezbytnou schopnost k přesnému generování TRX reportu. Rozšíření určené k registraci je součástí balíčku NuGet https://www.nuget.org/packages/Microsoft.Testing.Extensions.TrxReport, ale možnost jej implementovat se nachází v balíčku obsahujícím pouze kontrakt.
Na závěr si shrneme hlavní aspekty systému schopností:
- Je nezbytné usnadnit jasnou a stabilní komunikaci mezi součástmi.
- Všechny schopnosti by měly dědit z
ICapabilitynebo z rozhraní, které z něj dědí, a měly by být zpřístupněny prostřednictvím kolekce s rozhranímICapabilities. - Pomáhá při vývoji funkcí, aniž by způsobovala zásadní změny. Pokud určitá funkce není podporovaná, je možné provést příslušnou akci.
- Odpovědnost za návrh, expedici a dokumentaci použití funkce náleží vlastníku schopnosti . MTP může také vlastnit funkci stejným způsobem jako jakékoli jiné rozšíření.
Možnosti rámce
Platforma zveřejňuje specializované rozhraní s názvem ITestFrameworkCapability, které je základem všech funkcí vystavených pro testovací architektury. Tyto funkce jsou k dispozici při registraci testovacího frameworku na platformě.
IBannerMessageOwnerCapability
Volitelná funkce testovací architektury umožňuje testovacímu rozhraní poskytnout bannerovou zprávu platformě. Pokud je zpráva null nebo daná funkce není k dispozici, platforma použije výchozí zprávu v banneru.
Tato implementace schopností umožňuje abstrahovat různé podmínky, které může testovací architektura zvážit při rozhodování, zda by se měla zobrazit bannerová zpráva nebo ne.
Platforma zpřístupňuje službu IPlatformInformation, aby poskytla některé informace o platformě, které by mohly být užitečné při vytváření vlastní bannerové zprávy.
ITrxReportCapability
Pokud chcete poskytnout metadata specifická pro framework rozšíření sestav TRX, implementujte Microsoft.Testing.Extensions.TrxReport.Abstractions.ITrxReportCapability. Přidejte odkaz na balíček Microsoft.Testing.Extensions.TrxReport.Abstractions ze svého frameworku. Testovací aplikace také potřebuje balíček Microsoft.Testing.Extensions.TrxReport pro vytváření sestav.
Tato funkce odděluje podporu od aktivace:
- Vraťte
truezIsSupported, když váš framework může poskytovat metadata TRX. - V
Enable()zaznamenejte, že reportér TRX požadoval metadata. Reporter volá tuto metodu na začátku testovací relace, pokud jsou povoleny sestavy TRX. - Po aktivaci přidejte vlastnosti TRX do testovacích uzlů, které váš framework publikuje.
Následující funkce ukládá stav aktivace. Ukázkové projekty cílí na .NET 10 a odkazují na MTP 2.5.1:
internal sealed class TrxCapability : ITrxReportCapability
{
public bool IsSupported => true;
public bool IsEnabled { get; private set; }
public void Enable() => IsEnabled = true;
}
Friend NotInheritable Class TrxCapability
Implements ITrxReportCapability
Public ReadOnly Property IsSupported As Boolean Implements ITrxReportCapability.IsSupported
Get
Return True
End Get
End Property
Public Property IsEnabled As Boolean
Get
Return _isEnabled
End Get
Private Set(value As Boolean)
_isEnabled = value
End Set
End Property
Private _isEnabled As Boolean
Public Sub Enable() Implements ITrxReportCapability.Enable
IsEnabled = True
End Sub
End Class
Vraťte schopnost z capabilitiesFactory, kterou předáte do RegisterTestFramework. Dejte frameworku stejnou instanci capability, aby mohl sledovat Enable(). Pro ručně složenou testovací aplikaci zaregistrujte poskytovatele TRX za svým frameworkem a dalšími rozšířeními:
var trxCapability = new TrxCapability();
var builder = await TestApplication.CreateBuilderAsync(args);
builder.RegisterTestFramework(
_ => new TestFrameworkCapabilities(trxCapability),
(_, _) => new ReportFramework(trxCapability));
builder.AddTrxReportProvider();
Dim trxCapability As New TrxCapability()
Dim builder = Await TestApplication.CreateBuilderAsync(args)
builder.RegisterTestFramework(
Function(services) New TestFrameworkCapabilities(trxCapability),
Function(capabilities, services) New ReportFramework(trxCapability))
builder.AddTrxReportProvider()
Balíček abstrakce poskytuje typované vlastnosti pro TestNode.Properties:
| Property | Purpose |
|---|---|
TrxFullyQualifiedTypeNameProperty |
Poskytuje plně kvalifikovaný název testovací třídy. |
TrxCategoriesProperty |
Poskytuje kategorie testu. |
TrxExceptionProperty |
Poskytuje zprávu o selhání a výpis zásobníku. |
TrxMessagesProperty |
Obsahuje položky StandardOutputTrxMessage, StandardErrorTrxMessage a DebugOrTraceTrxMessage. |
TrxTestDefinitionName |
Přepíše název definice testu v sestavě. |
TrxWorkItemsProperty |
Poskytuje identifikátory pracovních položek. |
Můžete například rozšířit výsledek poté, co vaše architektura určí výsledek testu:
if (trxCapability.IsEnabled)
{
testNode.Properties.Add(
new TrxFullyQualifiedTypeNameProperty("Contoso.CalculatorTests"));
testNode.Properties.Add(new TrxCategoriesProperty(["Unit"]));
testNode.Properties.Add(new TrxMessagesProperty(
[new StandardOutputTrxMessage($"Captured output for {test.Name}.")]));
if (failure is not null)
{
testNode.Properties.Add(
new TrxExceptionProperty(failure.Message, failure.StackTrace));
}
}
If _trxCapability.IsEnabled Then
testNode.Properties.Add(
New TrxFullyQualifiedTypeNameProperty("Contoso.CalculatorTests"))
testNode.Properties.Add(New TrxCategoriesProperty({"Unit"}))
testNode.Properties.Add(New TrxMessagesProperty(
{New StandardOutputTrxMessage($"Captured output for {test.Name}.")}))
If failure IsNot Nothing Then
testNode.Properties.Add(
New TrxExceptionProperty(failure.Message, failure.StackTrace))
End If
End If
Tyto vlastnosti doplňují požadovaný stav testovacího uzlu; nenahrazují jej. Zprávy specifické pro TRX také nenahrazují prvky platformy StandardOutputProperty a StandardErrorProperty.
Kompletní ukázka obsahuje jeden úspěšný test a jeden úmyslně neúspěšný test. Zapíše --report-trxvýsledky i rozšířená metadata do souboru TRX a vrátí ukončovací kód 2. Pokud chcete spustit pouze test, který prošel, přidejte --filter-uid trx.pass.
Pokud tato funkce chybí nebo IsSupported je false, reporter TRX varuje, že framework nepodporuje obohacení TRX. Reporter může stále vytvořit sestavu z dostupných dat, ale podrobnosti specifické pro framework můžou chybět. Neinzerujte podporu, pokud vaše architektura neobsahuje odpovídající metadata.
IGracefulStopTestExecutionCapability
Chcete-li podporovat --maximum-failed-tests ve vlastní testovací architektuře, implementujte Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability. Funkce je součástí balíčku Microsoft.Testing.Platform a je k dispozici od MTP 1.5. Autoři testů, kteří používají architekturu, která už tuto možnost podporuje, nemusí tuto funkci implementovat.
Rozhraní definuje Task StopTestExecutionAsync(CancellationToken cancellationToken). Když počet selhání dosáhne požadovaného maxima, MTP zavolá tuto metodu. Vaše implementace musí frameworku sdělit, aby přestal plánovat nové testy, a zároveň umožní testům, které již byly spuštěny, dokončit se, spustit vyčištění a publikovat jejich výsledky.
Important
Funkce a AddMaximumFailedTestsService pomocná rutina jsou experimentální rozhraní API, která generují diagnostické zprávy kompilátoru TPEXP. Jejich smlouvy mohou být změněny nebo odstraněny. Ukázkové projekty explicitně potlačují TPEXP.
Při implementaci funkce postupujte podle těchto požadavků:
- Sdílejte stav zastavení mezi funkcí a plánovačem testů frameworku. Pouhé vrácení dokončeného úkolu nezastaví testy.
- Zajistěte, aby požadavky na zastavení byly bezpečné pro více vláken a idempotentní. Zastavení může požadovat více než jedna komponenta platformy.
- Vraťte se poté, co dáte znamení k zastavení. Nečekejte na celé spuštění ani na dokončení sběrnice zpráv: MTP může metodu volat, zatímco zpracovává výsledek testu, takže toto čekání může způsobit deadlock.
- Udržujte stav řádného zastavení odděleně od zrušení žádosti. Neukončíte proces ani nezrušíte publikování výsledků, abyste implementovali řádné zastavení. Pokud vaše operace zastavení vyžaduje asynchronní práci, respektujte token zrušení metody.
- Po dokončení aktivních testů dokončete normální životní cyklus požadavku, včetně publikování výsledků, vyčištění a volání
ExecuteRequestContext.Complete().
Následující implementace používá příznak bezpečný pro přístup z více vláken. V rámci frameworku zkontrolujte IsStopRequested, než naplánujete každý test, a přestaňte přijímat novou práci, když je příznak true.
public sealed class GracefulStopCapability : IGracefulStopTestExecutionCapability
{
private int _stopRequested;
public bool IsStopRequested => Volatile.Read(ref _stopRequested) != 0;
public Task StopTestExecutionAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Interlocked.Exchange(ref _stopRequested, 1);
return Task.CompletedTask;
}
}
Public NotInheritable Class GracefulStopCapability
Implements IGracefulStopTestExecutionCapability
Private _stopRequested As Integer
Public ReadOnly Property IsStopRequested As Boolean
Get
Return Volatile.Read(_stopRequested) <> 0
End Get
End Property
Public Function StopTestExecutionAsync(cancellationToken As CancellationToken) As Task _
Implements IGracefulStopTestExecutionCapability.StopTestExecutionAsync
cancellationToken.ThrowIfCancellationRequested()
Interlocked.Exchange(_stopRequested, 1)
Return Task.CompletedTask
End Function
End Class
Zpřístupňuje funkcionalitu prostřednictvím ITestFrameworkCapabilities.Capabilities. Příklad registrace používá kolekci TestFrameworkCapabilities MTP.
Během registrace testovacího frameworku předejte instanci registrované schopnosti do vašeho frameworku. Následující pomocná rutina přijímá továrnu frameworku a entitu IExtension, která vlastní volbu příkazového řádku. Volá také AddMaximumFailedTestsService z Microsoft.Testing.Platform.Helpers oboru názvů pro registraci --maximum-failed-tests poskytovatele voleb. Bez daného poskytovatele MTP možnost nerozpozná.
public static void Register(
ITestApplicationBuilder builder,
IExtension owner,
Func<GracefulStopCapability, ITestFramework> createFramework)
{
builder.RegisterTestFramework(
_ => new TestFrameworkCapabilities(new GracefulStopCapability()),
(capabilities, _) => createFramework(
capabilities.Capabilities.OfType<GracefulStopCapability>().Single()));
builder.AddMaximumFailedTestsService(owner);
}
Public Sub Register(
builder As ITestApplicationBuilder,
owner As IExtension,
createFramework As Func(Of GracefulStopCapability, ITestFramework))
builder.RegisterTestFramework(
Function(services) New TestFrameworkCapabilities(New GracefulStopCapability()),
Function(capabilities, services) createFramework(
capabilities.Capabilities.OfType(Of GracefulStopCapability)().Single()))
builder.AddMaximumFailedTestsService(owner)
End Sub
Továrna capability vytvoří nově vytvořený stav stop a továrna frameworku načte stejnou instanci. V rámci frameworku nevytvářejte druhou odpojenou schopnost. Pro frameworky, které podporují více požadavků na spuštění, zachovejte stav zastavení v rozsahu příslušného spuštění. Při spuštění nesmažte přijatou žádost o zastavení.
MTP odmítne --maximum-failed-tests při ověřování příkazového řádku, pokud je zprostředkovatel možností zaregistrovaný, ale framework tuto funkci nezpřístupňuje. Když prahová hodnota selhání aktivuje zastavení, MTP vrátí ukončovací kód 13. Konečný počet selhání může překročit prahovou hodnotu, protože zpracování výsledků je asynchronní a testy už můžou probíhat.
Informace o kontraktu rozhraní najdete v IGracefulStopTestExecutionCapability zdroji.