Delen via


Een testframework bouwen

In dit artikel wordt uitgelegd hoe u een aangepast testframework maakt voor Microsoft.Testing.Platform. Het testframework is de enige verplichte extensie. Het detecteert en voert tests uit en rapporteert resultaten terug naar het platform.

Zie Aangepaste extensies maken voor een volledige samenvatting van het uitbreidingspunt en de concepten in en buiten het proces.

Als u een bestaand op VSTest gebaseerd testframework migreert naar Microsoft.Testing.Platform, gebruikt u de VSTest Bridge-extensie om de overgang te vereenvoudigen.

Extensie voor testframework

Het testframework is de primaire extensie die het testplatform de mogelijkheid biedt om tests te detecteren en uit te voeren. Het testframework is verantwoordelijk voor de communicatie van de resultaten van de tests naar het testplatform. Het testframework is de enige verplichte extensie die is vereist voor het uitvoeren van een testsessie.

Een testframework registreren

In deze sectie wordt uitgelegd hoe u het testframework registreert bij het testplatform. U registreert slechts één testframework per testtoepassingsbouwer met behulp van de API, zoals wordt weergegeven in de TestApplication.RegisterTestFrameworkarchitectuurdocumentatie microsoft.Testing.Platform .

De registratie-API wordt als volgt gedefinieerd:

ITestApplicationBuilder RegisterTestFramework(
    Func<IServiceProvider, ITestFrameworkCapabilities> capabilitiesFactory,
    Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework> adapterFactory);

De RegisterTestFramework-API verwacht twee fabrieken:

  1. Func<IServiceProvider, ITestFrameworkCapabilities>: dit is een gemachtigde die een object accepteert dat de IServiceProvider-interface implementeert en een object retourneert dat de ITestFrameworkCapabilities-interface implementeert. De IServiceProvider biedt toegang tot platformservices, zoals configuraties, loggers en opdrachtregelargumenten.

    De ITestFrameworkCapabilities-interface wordt gebruikt om de mogelijkheden aan te kondigen die door het testframework worden ondersteund voor het platform en extensies. Hiermee kunnen het platform en de extensies correct communiceren door specifieke gedragingen te implementeren en te ondersteunen. Raadpleeg de desbetreffende sectie voor een beter begrip van het concept van mogelijkheden.

  2. Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework>: dit is een gemachtigde die een ITestFrameworkCapabilities--object gebruikt. Dit is het exemplaar dat wordt geretourneerd door de Func<IServiceProvider, ITestFrameworkCapabilities>en een IServiceProvider- om nogmaals toegang te verlenen tot platformservices. Het verwachte retourobject is een object dat de ITestFramework-interface implementeert. De ITestFramework fungeert als de uitvoeringsengine waarmee tests worden gedetecteerd en uitgevoerd en vervolgens de resultaten worden gecommuniceerd naar het testplatform.

Het scheiden van de creatie van ITestFrameworkCapabilities en de creatie van ITestFramework door het platform is een optimalisatie om te voorkomen dat het testframework wordt gemaakt als de ondersteunde mogelijkheden niet voldoende zijn om de huidige testsessie uit te voeren.

Bekijk het volgende voorbeeld van gebruikerscode, waarin een testframeworkregistratie wordt gedemonstreert die een lege mogelijkhedenset retourneert:

internal class TestingFrameworkCapabilities : ITestFrameworkCapabilities
{
    public IReadOnlyCollection<ITestFrameworkCapability> Capabilities => [];
}

internal class TestingFramework : ITestFramework
{
   public TestingFramework(ITestFrameworkCapabilities capabilities, IServiceProvider serviceProvider)
   {
       // ...
   }
   // Omitted for brevity...
}

public static class TestingFrameworkExtensions
{
    public static void AddTestingFramework(this ITestApplicationBuilder builder)
    {
        builder.RegisterTestFramework(
            _ => new TestingFrameworkCapabilities(),
            (capabilities, serviceProvider) => new TestingFramework(capabilities, serviceProvider));
    }
}

// ...

Bekijk nu het bijbehorende toegangspunt van dit voorbeeld met de registratiecode:

var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
// Register the testing framework
testApplicationBuilder.AddTestingFramework();
using var testApplication = await testApplicationBuilder.BuildAsync();
return await testApplication.RunAsync();

Opmerking

Het retourneren van lege ITestFrameworkCapabilities mag niet voorkomen dat de testsessie wordt uitgevoerd. Alle testframeworks moeten in staat zijn om tests te detecteren en uit te voeren. De impact moet worden beperkt tot extensies die zich kunnen afmelden als het testframework een bepaalde functie mist.

Een testframework maken

De Microsoft.Testing.Platform.Extensions.TestFramework.ITestFramework wordt geïmplementeerd door extensies die een testframework bieden:

public interface ITestFramework : IExtension
{
    Task<CreateTestSessionResult> CreateTestSessionAsync(CreateTestSessionContext context);
    Task ExecuteRequestAsync(ExecuteRequestContext context);
    Task<CloseTestSessionResult> CloseTestSessionAsync(CloseTestSessionContext context);
}

De IExtension-interface

De ITestFramework interface neemt over van de IExtension interface. Dit is een interface waaruit alle extensiepunten overnemen. IExtension wordt gebruikt om de naam en beschrijving van de extensie op te halen. De IExtension biedt ook een manier om de extensie dynamisch in of uit te schakelen in de installatie, via Task<bool> IsEnabledAsync(). Zorg ervoor dat u true retourneert vanuit deze methode als u geen specifieke vereisten hebt om deze uit te schakelen.

De methode CreateTestSessionAsync

De CreateTestSessionAsync methode wordt aangeroepen aan het begin van de testsessie en wordt gebruikt om het testframework te initialiseren. De API accepteert een CloseTestSessionContext-object en retourneert een CloseTestSessionResult.

public sealed class CreateTestSessionContext : TestSessionContext
{
    public SessionUid SessionUid { get; }
    public ClientInfo Client { get; }
    public CancellationToken CancellationToken { get; }
}

public readonly struct SessionUid
{
    public string Value { get; }
}

public sealed class ClientInfo
{
    public string Id { get; }
    public string Version { get; }
}

De SessionUid fungeert als de unieke id voor de huidige testsessie en biedt een logische verbinding met de resultaten van de sessie. De ClientInfo bevat informatie over de entiteit die het testframework aanroept. Deze informatie kan worden gebruikt door het testframework om het gedrag ervan te wijzigen. Vanaf het moment dat dit document is geschreven, zou een consoleuitvoering bijvoorbeeld een clientnaam rapporteren, zoals 'testingplatform-console'. De CancellationToken wordt gebruikt om de uitvoering van CreateTestSessionAsyncte stoppen.

Het retourobject is een CloseTestSessionResult:

public sealed class CreateTestSessionResult
{
    public string? WarningMessage { get; set; }
    public string? ErrorMessage { get; set; }
    public bool IsSuccess { get; set; }
}

De eigenschap IsSuccess wordt gebruikt om aan te geven of de sessie is gemaakt. Wanneer deze falseretourneert, wordt de testuitvoering gestopt.

De methode CloseTestSessionAsync

De methode CloseTestSessionAsync wordt naast de CreateTestSessionAsync in functionaliteit geplaatst, waarbij het enige verschil de objectnamen is. Zie de sectie CreateTestSessionAsync voor meer informatie.

De methode ExecuteRequestAsync

De methode ExecuteRequestAsync accepteert een object van het type ExecuteRequestContext. Dit object, zoals wordt voorgesteld door de naam, bevat de details over de actie die het testframework naar verwachting zal uitvoeren. De ExecuteRequestContext definitie is:

public sealed class ExecuteRequestContext
{
    public IRequest Request { get; }
    public IMessageBus MessageBus { get; }
    public CancellationToken CancellationToken { get; }
    public void Complete();
}

IRequest: dit is de basisinterface voor elk type aanvraag. Denk aan het testframework als een in-process stateful server waar de levenscyclus als volgt is:

Een sequentiediagram dat de levenscyclus van het testframework vertegenwoordigt.

In het voorgaande diagram ziet u dat het testplatform drie aanvragen uitgeeft nadat het testframework-exemplaar is gemaakt. Het testframework verwerkt deze aanvragen en maakt gebruik van de IMessageBus-service, die is opgenomen in de aanvraag zelf, om het resultaat voor elke specifieke aanvraag te leveren. Zodra een bepaalde aanvraag is verwerkt, roept het testframework de Complete() methode erop aan, die aangeeft aan het testplatform dat aan de aanvraag is voldaan. Het testplatform bewaakt alle verzonden aanvragen. Zodra aan alle aanvragen is voldaan, wordt CloseTestSessionAsync aangeroepen en wordt het exemplaar verwijderd (als IDisposable/IAsyncDisposable is geïmplementeerd). Het is duidelijk dat de aanvragen en hun voltooiingen elkaar kunnen overlappen, waardoor gelijktijdige en asynchrone uitvoering van aanvragen mogelijk is.

Opmerking

Momenteel verzendt het testplatform geen overlappende aanvragen en wacht op de voltooiing van een aanvraag >> voordat het volgende wordt verzonden. Dit gedrag kan echter in de toekomst veranderen. De ondersteuning voor gelijktijdige aanvragen wordt bepaald via de mogelijkheden systeem.

De IRequest implementatie geeft de exacte aanvraag aan die moet worden vervuld. Het testframework identificeert het type aanvraag en verwerkt deze dienovereenkomstig. Als het aanvraagtype niet wordt herkend, moet er een uitzondering worden gegenereerd.

U vindt meer informatie over de beschikbare aanvragen in de sectie IRequest.

IMessageBus: met deze service, gekoppeld aan de aanvraag, kan het testframework asynchroon informatie over de lopende aanvraag naar het testplatform publiceren. De berichtenbus fungeert als de centrale hub voor het platform, waardoor asynchrone communicatie tussen alle platformonderdelen en -extensies wordt vergemakkelijkt. Raadpleeg de sectie IMessageBus voor een uitgebreide lijst met informatie die kan worden gepubliceerd naar het testplatform.

CancellationToken: dit token wordt gebruikt om de verwerking van een bepaalde aanvraag te onderbreken.

Complete(): Zoals weergegeven in de vorige reeks, meldt de Complete methode het platform dat de aanvraag is verwerkt en alle relevante informatie is verzonden naar de IMessageBus-.

Waarschuwing

Als u niet Complete() op de aanvraag aanroept, reageert de testtoepassing niet meer.

Als u uw testframework wilt aanpassen aan uw vereisten of die van uw gebruikers, kunt u een persoonlijke sectie in het configuratiebestand of met aangepaste opdrachtregeloptiesgebruiken.

Aanvragen verwerken

De volgende sectie bevat een gedetailleerde beschrijving van de verschillende aanvragen die een testframework kan ontvangen en verwerken.

Voordat u verdergaat met de volgende sectie, is het essentieel om het concept van de IMessageBusgrondig te begrijpen. Dit is de essentiële service voor het overbrengen van testuitvoeringsgegevens naar het testplatform.

TestSessionContext

De TestSessionContext is een gedeelde eigenschap voor alle verzoeken, die informatie biedt over de lopende testsessie.

public class TestSessionContext
{
    public SessionUid SessionUid { get; }
    public ClientInfo Client { get; }
}

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

public sealed class ClientInfo
{
    public string Id { get; }
    public string Version { get; }
}

De TestSessionContext bestaat uit de SessionUid, een unieke id voor de lopende testsessie die helpt bij het vastleggen en correleren van testsessiegegevens. Het bevat ook het ClientInfo type, dat details bevat over de initiator van de testsessie. Het testframework kan verschillende routes kiezen of verschillende informatie publiceren op basis van de identiteit van de initiatorvan de testsessie.

OntdekTestUitvoeringsverzoek

public class DiscoverTestExecutionRequest
{
    // Detailed in the custom section below
    public TestSessionContext Session { get; }

    // This is experimental and intended for future use, please disregard for now.
    public ITestExecutionFilter Filter { get; }
}

De DiscoverTestExecutionRequest geeft het testframework opdracht om de tests te ontdekken en deze informatie te communiceren naar de IMessageBus.

Zoals beschreven in de vorige sectie is de eigenschap voor een gedetecteerde test DiscoveredTestNodeStateProperty. Hier volgt een algemeen codefragment ter referentie:

var testNode = new TestNode
{
    Uid = GenerateUniqueStableId(),
    DisplayName = GetDisplayName(),
    Properties = new PropertyBag(
        DiscoveredTestNodeStateProperty.CachedInstance),
};

await context.MessageBus.PublishAsync(
    this,
    new TestNodeUpdateMessage(
        discoverTestExecutionRequest.Session.SessionUid,
        testNode));

// ...

VoerTestUitvoeringAanvraagUit

public class RunTestExecutionRequest
{
    // Detailed in the custom section below
    public TestSessionContext Session { get; }

    // This is experimental and intended for future use, please disregard for now.
    public ITestExecutionFilter Filter { get; }
}

De RunTestExecutionRequest instrueert het testframework om de tests uit te voeren en deze informatie naar de IMessageBus te communiceren.

Hier volgt een algemeen codefragment ter referentie:

var skippedTestNode = new TestNode()
{
    Uid = GenerateUniqueStableId(),
    DisplayName = GetDisplayName(),
    Properties = new PropertyBag(
        SkippedTestNodeStateProperty.CachedInstance),
};

await context.MessageBus.PublishAsync(
    this,
    new TestNodeUpdateMessage(
        runTestExecutionRequest.Session.SessionUid,
        skippedTestNode));

// ...

var successfulTestNode = new TestNode()
{
    Uid = GenerateUniqueStableId(),
    DisplayName = GetDisplayName(),
    Properties = new PropertyBag(
        PassedTestNodeStateProperty.CachedInstance),
};

await context.MessageBus.PublishAsync(
    this,
    new TestNodeUpdateMessage(
        runTestExecutionRequest.Session.SessionUid,
        successfulTestNode));

// ...

var assertionFailedTestNode = new TestNode()
{
    Uid = GenerateUniqueStableId(),
    DisplayName = GetDisplayName(),
    Properties = new PropertyBag(
        new FailedTestNodeStateProperty(assertionException)),
};

await context.MessageBus.PublishAsync(
    this,
    new TestNodeUpdateMessage(
        runTestExecutionRequest.Session.SessionUid,
        assertionFailedTestNode));

// ...

var failedTestNode = new TestNode()
{
    Uid = GenerateUniqueStableId(),
    DisplayName = GetDisplayName(),
    Properties = new PropertyBag(
        new ErrorTestNodeStateProperty(ex.InnerException!)),
};

await context.MessageBus.PublishAsync(
    this,
    new TestNodeUpdateMessage(
        runTestExecutionRequest.Session.SessionUid,
        failedTestNode));

De TestNodeUpdateMessage-gegevens

Zoals vermeld in de sectie IMessageBus, moet u voordat u de berichtenbus gebruikt, het type gegevens opgeven dat u wilt opgeven. Het testplatform heeft een bekend type gedefinieerd, TestNodeUpdateMessage, om het concept van een testupdate-informatiete vertegenwoordigen.

In dit gedeelte van het document wordt uitgelegd hoe u deze ladinggegevens kunt gebruiken. Laten we het oppervlak bekijken:

public sealed class TestNodeUpdateMessage(
    SessionUid sessionUid,
    TestNode testNode,
    TestNodeUid? parentTestNodeUid = null)
{
    public TestNode TestNode { get; }
    public TestNodeUid? ParentTestNodeUid { get; }
}

public class TestNode
{
    public required TestNodeUid Uid { get; init; }
    public required string DisplayName { get; init; }
    public PropertyBag Properties { get; init; } = new();
}

public sealed class TestNodeUid(string value)

public sealed partial class PropertyBag
{
    public PropertyBag();
    public PropertyBag(params IProperty[] properties);
    public PropertyBag(IEnumerable<IProperty> properties);
    public int Count { get; }
    public void Add(IProperty property);
    public bool Any<TProperty>();
    public TProperty? SingleOrDefault<TProperty>();
    public TProperty Single<TProperty>();
    public TProperty[] OfType<TProperty>();
    public IEnumerable<IProperty> AsEnumerable();
    public IEnumerator<IProperty> GetEnumerator();
    ...
}

public interface IProperty
{
}
  • TestNodeUpdateMessage: de TestNodeUpdateMessage bestaat uit twee eigenschappen: een TestNode en een ParentTestNodeUid. De ParentTestNodeUid geeft aan dat een test een hoofdtest kan hebben, en introduceert het concept van een testboom waarin TestNode's ten opzichte van elkaar kunnen worden gerangschikt. Deze structuur maakt toekomstige verbeteringen en functies mogelijk op basis van de boom relatie tussen de knooppunten. Als uw testframework geen teststructuur nodig heeft, kunt u ervoor kiezen om het niet te gebruiken en deze eenvoudig in te stellen op null, wat resulteert in een eenvoudige platte lijst met TestNodes.

  • TestNode: de TestNode bestaat uit drie eigenschappen, waarvan een de Uid van het type TestNodeUidis. Deze Uid fungeert als de UNIEKE STABIELE ID voor het knooppunt. De term UNIQUE STABLE ID impliceert dat dezelfde TestNode een IDENTIEKeUid moet onderhouden voor verschillende uitvoeringen en besturingssystemen. De TestNodeUid is een willekeurige ondoorzichtige tekenreeks die het testplatform als zodanig accepteert.

Belangrijk

De stabiliteit en uniekheid van de id zijn cruciaal in het testdomein. Ze maken het nauwkeurig richten van een enkele test mogelijk voor uitvoering en stellen de ID in staat om te fungeren als een permanente identificator voor een test, waardoor krachtige uitbreidingen en functies mogelijk worden gemaakt.

De tweede eigenschap is DisplayName, de mensvriendelijke naam voor de test. Deze naam wordt bijvoorbeeld weergegeven wanneer u de --list-tests opdrachtregel uitvoert.

Het derde kenmerk is Properties, een PropertyBag type. Zoals gedemonstreerd in de code, is dit een speciale eigenschappentas die algemene eigenschappen over de TestNodeUpdateMessagebevat. Dit impliceert dat u elke eigenschap kunt toevoegen aan het knooppunt waarmee de tijdelijke aanduidingsinterface IPropertywordt geïmplementeerd.

Het testplatform identificeert specifieke eigenschappen die zijn toegevoegd aan een TestNode.Properties om te bepalen of een test is geslaagd, mislukt of is overgeslagen.

U vindt de huidige lijst met beschikbare eigenschappen met de relatieve beschrijving in de sectie TestNodeUpdateMessage.TestNode.

Het PropertyBag type is doorgaans toegankelijk in elke IData en wordt gebruikt voor het opslaan van diverse eigenschappen die kunnen worden opgevraagd door het platform en extensies. Met dit mechanisme kunnen we het platform verbeteren met nieuwe informatie zonder wijzigingen die fouten veroorzaken. Als een onderdeel de eigenschap herkent, kan er een query op worden uitgevoerd; anders zal het buiten beschouwing worden gelaten.

Ten slotte maakt dit deel duidelijk dat u de implementatie van uw framework moet testen door de IDataProducer te implementeren die TestNodeUpdateMessage's produceert, zoals in het onderstaande voorbeeld.

internal sealed class TestingFramework
    : ITestFramework, IDataProducer
{
   // ...

   public Type[] DataTypesProduced =>
   [
       typeof(TestNodeUpdateMessage)
   ];

   // ...
}

Als voor uw testadapter de publicatie van bestanden tijdens de uitvoering is vereist, kunt u de herkende eigenschappen vinden in dit bronbestand: https://github.com/microsoft/testfx/blob/main/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs. Zoals u kunt zien, kunt u bestandsassets op een algemene manier opgeven of koppelen aan een specifieke TestNode. Als u van plan bent om een SessionFileArtifactte pushen, moet u deze vooraf declareren naar het platform, zoals hieronder wordt weergegeven:

internal sealed class TestingFramework
    : ITestFramework, IDataProducer
{
   // ...

   public Type[] DataTypesProduced =>
   [
       typeof(TestNodeUpdateMessage),
       typeof(SessionFileArtifact)
   ];

   // ...
}

Bekende eigenschappen

Zoals beschreven in de sectie Aanvragen, identificeert het testplatform specifieke eigenschappen die aan de TestNodeUpdateMessage sectie worden toegevoegd om de status van een TestNode te bepalen (bijvoorbeeld geslaagd, mislukt, overgeslagen, enzovoort). Hierdoor kan de runtime een lijst met mislukte tests nauwkeurig weergeven met de bijbehorende informatie in de console en de juiste afsluitcode voor het testproces instellen.

In dit segment behandelen we de verschillende bekende IProperty opties en de bijbehorende implicaties.

Zie TestNodeProperties.cs voor een uitgebreide lijst met bekende eigenschappen. Als u merkt dat een beschrijving van de eigenschap ontbreekt, dient u een probleem in.

Deze eigenschappen kunnen worden onderverdeeld in de volgende categorieën:

  1. Algemene informatie: Eigenschappen die kunnen worden opgenomen in elk type aanvraag.
  2. detectiegegevens: eigenschappen die tijdens een DiscoverTestExecutionRequest detectieaanvraag worden opgegeven.
  3. uitvoeringsinformatie: eigenschappen die worden opgegeven tijdens een testuitvoeringsaanvraag RunTestExecutionRequest.

Bepaalde eigenschappen zijn vereist, terwijl andere optioneel zijn. De verplichte eigenschappen zijn vereist om basisfunctionaliteit voor testen te bieden, zoals het rapporteren van mislukte tests en het aangeven of de volledige testsessie al dan niet is geslaagd.

Optionele eigenschappen verbeteren daarentegen de testervaring door aanvullende informatie te verstrekken. Ze zijn met name handig in IDE-scenario's (zoals VS, VSCode, enzovoort), consoleuitvoeringen of bij het ondersteunen van specifieke extensies waarvoor meer gedetailleerde informatie nodig is om correct te functioneren. Deze optionele eigenschappen zijn echter niet van invloed op de uitvoering van de tests.

Opmerking

Extensies worden belast met waarschuwingen en het beheren van uitzonderingen wanneer ze specifieke informatie nodig hebben om correct te werken. Als een extensie niet over de benodigde informatie beschikt, moet de uitvoering van de test niet mislukken, maar moet de extensie zich gewoon afmelden.

Algemene informatie
public record KeyValuePairStringProperty(
    string Key,
    string Value)
        : IProperty;

De KeyValuePairStringProperty staat voor een algemene sleutel-waardecombinatiegegevens.

public record struct LinePosition(
    int Line,
    int Column);

public record struct LinePositionSpan(
    LinePosition Start,
    LinePosition End);

public abstract record FileLocationProperty(
    string FilePath,
    LinePositionSpan LineSpan)
        : IProperty;

public sealed record TestFileLocationProperty(
    string FilePath,
    LinePositionSpan LineSpan)
        : FileLocationProperty(FilePath, LineSpan);

TestFileLocationProperty wordt gebruikt om de locatie van de test in het bronbestand vast te stellen. Dit is met name handig wanneer de initiator een IDE is, zoals Visual Studio of Visual Studio Code.

public sealed record TestMethodIdentifierProperty(
    string AssemblyFullName,
    string Namespace,
    string TypeName,
    string MethodName,
    string[] ParameterTypeFullNames,
    string ReturnTypeFullName)

TestMethodIdentifierProperty is een unieke id voor een testmethode, die aan de ECMA-335-standaard is gekoppeld.

Opmerking

De gegevens die nodig zijn om deze eigenschap te maken, kunnen gemakkelijk worden verkregen met behulp van de .NET-weerspiegelingsfunctie, met behulp van typen uit de System.Reflection naamruimte.

public sealed record TestMetadataProperty(
    string Key,
    string Value)

TestMetadataProperty wordt gebruikt om de kenmerken of eigenschappen van een TestNodeover te brengen.

Detectie-informatie
public sealed record DiscoveredTestNodeStateProperty(
    string? Explanation = null)
{
    public static DiscoveredTestNodeStateProperty CachedInstance { get; }
}

De DiscoveredTestNodeStateProperty geeft aan dat deze TestNode is gedetecteerd. Deze wordt gebruikt wanneer een DiscoverTestExecutionRequest naar het testframework wordt verzonden. Let op de handige in de cache opgeslagen waarde die wordt aangeboden door de eigenschap CachedInstance. Deze eigenschap is vereist.

Uitvoeringsinformatie
public sealed record InProgressTestNodeStateProperty(
    string? Explanation = null)
{
    public static InProgressTestNodeStateProperty CachedInstance { get; }
}

De InProgressTestNodeStateProperty informeert het testplatform dat de TestNode is gepland voor uitvoering en momenteel in uitvoering is. Let op de handige in de cache opgeslagen waarde die wordt aangeboden door de eigenschap CachedInstance.

public readonly record struct TimingInfo(
    DateTimeOffset StartTime,
    DateTimeOffset EndTime,
    TimeSpan Duration);

public sealed record StepTimingInfo(
    string Id,
    string Description,
    TimingInfo Timing);

public sealed record TimingProperty : IProperty
{
    public TimingProperty(TimingInfo globalTiming)
        : this(globalTiming, [])
    {
    }

    public TimingProperty(
        TimingInfo globalTiming,
        StepTimingInfo[] stepTimings)
    {
        GlobalTiming = globalTiming;
        StepTimings = stepTimings;
    }

    public TimingInfo GlobalTiming { get; }

    public StepTimingInfo[] StepTimings { get; }
}

De TimingProperty wordt gebruikt voor het overbrengen van timing details over de uitvoering van TestNode. Het maakt ook de timing van afzonderlijke uitvoeringsstappen mogelijk via StepTimingInfo. Dit is met name handig wanneer uw testconcept is onderverdeeld in meerdere fasen, zoals initialisatie, uitvoering en opschonen.

Eén en slechts één van de volgende eigenschappen is vereist per TestNode en communiceert het resultaat van de TestNode door aan het testplatform.

public sealed record PassedTestNodeStateProperty(
    string? Explanation = null)
        : TestNodeStateProperty(Explanation)
{
    public static PassedTestNodeStateProperty CachedInstance
        { get; } = new PassedTestNodeStateProperty();
}

PassedTestNodeStateProperty informeert het testplatform dat deze TestNode is geslaagd. Let op de handige in de cache opgeslagen waarde die wordt aangeboden door de eigenschap CachedInstance.

public sealed record SkippedTestNodeStateProperty(
    string? Explanation = null)
        : TestNodeStateProperty(Explanation)
{
    public static SkippedTestNodeStateProperty CachedInstance
        { get; } =  new SkippedTestNodeStateProperty();
}

SkippedTestNodeStateProperty informeert het testplatform dat deze TestNode is overgeslagen. Let op de handige in de cache opgeslagen waarde die wordt aangeboden door de eigenschap CachedInstance.

public sealed record FailedTestNodeStateProperty : TestNodeStateProperty
{
    public FailedTestNodeStateProperty()
        : base(default(string))
    {
    }

    public FailedTestNodeStateProperty(string explanation)
        : base(explanation)
    {
    }

    public FailedTestNodeStateProperty(
        Exception exception,
        string? explanation = null)
        : base(explanation ?? exception.Message)
    {
        Exception = exception;
    }

    public Exception? Exception { get; }
}

FailedTestNodeStateProperty informeert het testplatform dat deze TestNode is mislukt na een assertie.

public sealed record ErrorTestNodeStateProperty : TestNodeStateProperty
{
    public ErrorTestNodeStateProperty()
        : base(default(string))
    {
    }

    public ErrorTestNodeStateProperty(string explanation)
        : base(explanation)
    {
    }

    public ErrorTestNodeStateProperty(
        Exception exception,
        string? explanation = null)
            : base(explanation ?? exception.Message)
    {
        Exception = exception;
    }

    public Exception? Exception { get; }
}

ErrorTestNodeStateProperty informeert het testplatform dat deze TestNode is mislukt. Dit type fout verschilt van de FailedTestNodeStateProperty, die wordt gebruikt voor assertiefouten. U kunt bijvoorbeeld problemen melden zoals test initialisatiefouten met ErrorTestNodeStateProperty.

public sealed record TimeoutTestNodeStateProperty : TestNodeStateProperty
{
    public TimeoutTestNodeStateProperty()
        : base(default(string))
    {
    }

    public TimeoutTestNodeStateProperty(string explanation)
        : base(explanation)
    {
    }

    public TimeoutTestNodeStateProperty(
        Exception exception,
        string? explanation = null)
            : base(explanation ?? exception.Message)
    {
        Exception = exception;
    }

    public Exception? Exception { get; }

    public TimeSpan? Timeout { get; init; }
}

TimeoutTestNodeStateProperty informeert het testplatform dat deze TestNode is mislukt vanwege een time-out. U kunt de time-out rapporteren met behulp van de eigenschap Timeout.

public sealed record CancelledTestNodeStateProperty : TestNodeStateProperty
{
    public CancelledTestNodeStateProperty()
        : base(default(string))
    {
    }

    public CancelledTestNodeStateProperty(string explanation)
        : base(explanation)
    {
    }

    public CancelledTestNodeStateProperty(
        Exception exception,
        string? explanation = null)
        : base(explanation ?? exception.Message)
    {
        Exception = exception;
    }

    public Exception? Exception { get; }
}

CancelledTestNodeStateProperty informeert het testplatform dat deze TestNode is mislukt vanwege annulering.