Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird erläutert, wie Sie ein benutzerdefiniertes Testframework für Microsoft.Testing.Platform erstellen. Das Testframework ist die einzige obligatorische Erweiterung. Es ermittelt und führt Tests aus und meldet Ergebnisse zurück an die Plattform.
Die vollständige Zusammenfassung des Erweiterungspunkts und der prozesinternen und prozessexternen Konzepte finden Sie unter Erstellen von benutzerdefinierten Erweiterungen.
Wenn Sie ein vorhandenes VSTest-basiertes Testframework zu Microsoft.Testing.Platform migrieren, verwenden Sie die VSTest Bridge-Erweiterung , um den Übergang zu vereinfachen.
Test-Framework-Erweiterung
Das Testframework ist die primäre Erweiterung, die der Testplattform die Fähigkeit verleiht, Tests zu ermitteln und auszuführen. Das Testframework ist dafür verantwortlich, die Ergebnisse der Tests an die Testplattform zu übermitteln. Das Testframework ist die einzige Erweiterung, die zum Ausführen einer Testsitzung zwingend notwendig ist.
Registrieren eines Testframeworks
In diesem Abschnitt wird erläutert, wie Sie das Testframework bei der Testplattform registrieren. Sie registrieren nur ein Testframework pro Testanwendungs-Generator mithilfe der API, wie in der TestApplication.RegisterTestFramework Dokumentation zur Microsoft.Testing.Platform-Architektur dargestellt.
Die Registrierungs-API wird wie folgt definiert:
ITestApplicationBuilder RegisterTestFramework(
Func<IServiceProvider, ITestFrameworkCapabilities> capabilitiesFactory,
Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework> adapterFactory);
Die RegisterTestFramework-API erwartet zwei Fabriken.
Func<IServiceProvider, ITestFrameworkCapabilities>: Dies ist ein Delegat, der ein Objekt akzeptiert, das dieIServiceProvider-Schnittstelle implementiert, und ein Objekt zurückgibt, das dieITestFrameworkCapabilities-Schnittstelle implementiert.IServiceProviderbietet Zugriff auf Plattformdienste wie Konfigurationen, Protokollierungen (Logger) und Befehlszeilenargumente.Die
ITestFrameworkCapabilities-Schnittstelle wird verwendet, um die vom Testframework unterstützten Funktionen für die Plattform und Erweiterungen anzukündigen. Durch die Implementierung und Unterstützung bestimmter Verhaltensweisen ermöglicht sie der Plattform und den Erweiterungen die korrekte Interaktion. Weitere Informationen zum Konzept von Funktionen finden Sie im entsprechenden Abschnitt.Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework>: Dies ist ein Delegat, der ein ITestFrameworkCapabilities-Objekt, bei dem es sich um die Instanz handelt, die vonFunc<IServiceProvider, ITestFrameworkCapabilities>zurückgegeben wird, und ein IServiceProvider-Objekt entgegennimmt, um erneut Zugriff auf Plattformdienste bereitzustellen. Das erwartete Rückgabeobjekt ist ein Objekt, das die ITestFramework-Schnittstelle implementiert.ITestFrameworkdient als Ausführungs-Engine, die Tests ermittelt und ausführt und anschließend die Ergebnisse an die Testplattform übermittelt.
Die Notwendigkeit für die Plattform, die Erstellung von ITestFrameworkCapabilities und ITestFramework zu trennen, ist eine Optimierung, die verhindert, dass das Testframework erstellt wird, wenn die unterstützten Funktionen nicht zum Ausführen der aktuellen Testsitzung ausreichen.
Das folgende Benutzercodebeispiel zeigt eine Testframeworkregistrierung, für die ein leerer Funktionssatz zurückgegeben wird:
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));
}
}
// ...
Sehen Sie sich nun den entsprechenden Einstiegspunkt in diesem Beispiel mit dem Registrierungscode an:
var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
// Register the testing framework
testApplicationBuilder.AddTestingFramework();
using var testApplication = await testApplicationBuilder.BuildAsync();
return await testApplication.RunAsync();
Hinweis
Die Rückgabe eines leeren ITestFrameworkCapabilities-Objekts sollte die Ausführung der Testsitzung nicht verhindern. Alle Testframeworks sollten in der Lage sein, Tests zu ermitteln und auszuführen. Die Auswirkungen sollten sich auf Erweiterungen beschränken, die deaktiviert werden können, wenn ein bestimmtes Feature nicht im Testframework verfügbar ist.
Erstellen eines Testframeworks
Microsoft.Testing.Platform.Extensions.TestFramework.ITestFramework wird durch Erweiterungen implementiert, die ein Testframework bereitstellen:
public interface ITestFramework : IExtension
{
Task<CreateTestSessionResult> CreateTestSessionAsync(CreateTestSessionContext context);
Task ExecuteRequestAsync(ExecuteRequestContext context);
Task<CloseTestSessionResult> CloseTestSessionAsync(CloseTestSessionContext context);
}
Die IExtension-Schnittstelle
Die ITestFramework Schnittstelle erbt von der IExtension Schnittstelle, von der alle Erweiterungspunkte erben.
IExtension wird verwendet, um den Namen und die Beschreibung der Erweiterung abzurufen.
IExtension bietet auch die Möglichkeit, die Erweiterung im Setup über Task<bool> IsEnabledAsync() dynamisch zu aktivieren oder zu deaktivieren. Stellen Sie sicher, dass Sie true von dieser Methode zurückgeben, wenn Sie keine spezifische Anforderungen haben, die eine Deaktivierung erfordern.
Die CreateTestSessionAsync -Methode
Die CreateTestSessionAsync-Methode wird zu Beginn der Testsitzung aufgerufen und zum Initialisieren des Testframeworks verwendet. Die API akzeptiert ein CloseTestSessionContext-Objekt und gibt ein CloseTestSessionResult-Objekt zurück.
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; }
}
Die SessionUid dient als eindeutiger Bezeichner für die aktuelle Testsitzung und stellt eine logische Verbindung mit den Ergebnissen der Sitzung her.
Das ClientInfo-Objekt enthält Details zur Entität, die das Testframework aufruft. Mithilfe dieser Informationen kann das Testframework sein Verhalten ändern. Zum Zeitpunkt der Erstellung dieses Dokuments würde bei einer Konsolenausführung beispielsweise ein Clientname wie „testingplatform-console“ gemeldet werden.
Das CancellationToken wird verwendet, um die Ausführung von CreateTestSessionAsync anzuhalten.
Das Rückgabeobjekt ist ein CloseTestSessionResult:
public sealed class CreateTestSessionResult
{
public string? WarningMessage { get; set; }
public string? ErrorMessage { get; set; }
public bool IsSuccess { get; set; }
}
Mit der IsSuccess-Eigenschaft wird angegeben, ob die Sitzung erfolgreich erstellt wurde. Wenn sie false zurückgibt, wird die Testausführung angehalten.
Die CloseTestSessionAsync -Methode
Der CloseTestSessionAsync-Methode steht hinsichtlich der Funktionalität CreateTestSessionAsync gegenüber, wobei der einzige Unterschied die Objektnamen sind. Weitere Informationen finden Sie im Abschnitt CreateTestSessionAsync.
Die ExecuteRequestAsync -Methode
Die ExecuteRequestAsync-Methode akzeptiert ein Objekt vom Typ ExecuteRequestContext. Wie der Name schon sagt, enthält dieses Objekt die Details zu der Aktion, die das Testframework ausführen soll.
Die ExecuteRequestContext-Definition lautet wie folgt:
public sealed class ExecuteRequestContext
{
public IRequest Request { get; }
public IMessageBus MessageBus { get; }
public CancellationToken CancellationToken { get; }
public void Complete();
}
IRequest: Dies ist die Basisschnittstelle für alle Anforderungstypen. Stellen Sie sich das Testframework als einen prozessinternen zustandsbehafteten Server vor, auf dem der Lebenszyklus stattfindet:
Das obige Diagramm zeigt, dass die Testplattform nach dem Erstellen der Testframeworkinstanz drei Anforderungen ausgibt. Das Testframework verarbeitet diese Anforderungen und verwendet den IMessageBus-Dienst, der in der Anforderung selbst enthalten ist, um das Ergebnis für jede Anforderung zu übermitteln. Sobald eine bestimmte Anforderung verarbeitet wurde, ruft das Testframework die Complete()-Methode für die Anforderung auf, um anzugeben, dass sie von der Testplattform erfüllt wurde.
Die Testplattform überwacht alle gesendeten Anforderungen. Nachdem alle Anforderungen erfüllt wurden, ruft sie CloseTestSessionAsync auf und verwirft die Instanz (sofern IDisposable/IAsyncDisposable implementiert ist).
Da sich die Anforderungen und ihr Abschluss offensichtlich überlappen können, ist die parallele und asynchrone Ausführung von Anforderungen möglich.
Hinweis
Derzeit sendet die Testplattform keine überlappenden Anforderungen. Sie wartet auf den Abschluss einer Anforderung >>, bevor die nächste Anforderung gesendet wird. Dieses Verhalten kann sich in Zukunft jedoch ändern. Die Unterstützung für gleichzeitige Anforderungen wird durch das Funktionssystem bestimmt.
Die IRequest-Implementierung gibt die genaue Anforderung an, die erfüllt werden muss. Das Testframework identifiziert den Anforderungstyp und behandelt die Anforderung entsprechend. Wenn der Anforderungstyp nicht erkannt wird, sollte eine Ausnahme ausgelöst werden.
Ausführliche Informationen zu den verfügbaren Anforderungen finden Sie im Abschnitt IRequest.
IMessageBus: Dieser Dienst, der mit der Anforderung verknüpft ist, ermöglicht dem Testframework die asynchrone Veröffentlichung von Informationen über die laufende Anforderung auf der Testplattform.
Der Nachrichtenbus dient als zentraler Hub für die Plattform und erleichtert die asynchrone Kommunikation zwischen allen Plattformkomponenten und Erweiterungen.
Eine umfassende Liste der Informationen, die auf der Testplattform veröffentlicht werden können, finden Sie im Abschnitt IMessageBus.
CancellationToken: Dieses Token wird verwendet, um die Verarbeitung einer bestimmten Anforderung zu unterbrechen.
Complete(): Wie in der obigen Sequenz dargestellt, benachrichtigt die Complete-Methode die Plattform, dass die Anforderung erfolgreich verarbeitet wurde und alle relevanten Informationen an den IMessageBus übermittelt wurden.
Warnung
Wird Complete() bei der Anforderung nicht ausgelöst, reagiert die Testanwendung nicht mehr.
Um das Testframework entsprechend Ihren Anforderungen oder den Anforderungen Ihrer Benutzer anzupassen, können Sie einen personalisierten Abschnitt in der Konfigurationsdatei oder benutzerdefinierte Befehlszeilenoptionen verwenden.
Behandeln von Anforderungen
Der folgende Abschnitt enthält eine detaillierte Beschreibung der verschiedenen Anforderungen, die ein Testframework empfangen und verarbeiten kann.
Bevor Sie mit dem nächsten Abschnitt fortfahren, müssen Sie das Konzept von IMessageBus verstehen, dem wesentlichen Dienst für die Übermittlung von Testausführungsinformationen an die Testplattform.
TestSessionContext
TestSessionContext ist eine gemeinsam genutzte Eigenschaft, die für alle Anforderungen verwendet wird und Informationen über die laufende Testsitzung bereitstellt.
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; }
}
Der TestSessionContext umfasst den SessionUid, einem eindeutigen Bezeichner für die laufende Testsitzung, der zum Protokollieren und Korrelieren von Testsitzungsdaten verwendet wird. Er enthält auch den ClientInfo-Typ, der Details zum Initiator der Testsitzung bereitstellt. Das Testframework kann basierend auf der Identität des Initiators der Testsitzung verschiedene Routen auswählen oder unterschiedliche Informationen veröffentlichen.
Discover-Testausführungsanforderung
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; }
}
Die DiscoverTestExecutionRequest weist das Testframework an, die Tests zu ermitteln und diese Informationen dem IMessageBus mitzuteilen.
Wie im vorherigen Abschnitt beschrieben, ist DiscoveredTestNodeStateProperty die Eigenschaft für einen ermittelten Test. Im Folgenden sehen Sie zur Referenz einen generischen Codeschnipsel:
var testNode = new TestNode
{
Uid = GenerateUniqueStableId(),
DisplayName = GetDisplayName(),
Properties = new PropertyBag(
DiscoveredTestNodeStateProperty.CachedInstance),
};
await context.MessageBus.PublishAsync(
this,
new TestNodeUpdateMessage(
discoverTestExecutionRequest.Session.SessionUid,
testNode));
// ...
Ausführungstestanforderung starten
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; }
}
Die RunTestExecutionRequest weist das Testframework an, die Tests auszuführen und diese Informationen an den IMessageBus zu übermitteln.
Im Folgenden sehen Sie zur Referenz einen generischen Codeschnipsel:
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));
TestNodeUpdateMessage-Daten
Wie im Abschnitt IMessageBus erwähnt, müssen Sie vor der Verwendung des Nachrichtenbusses den Datentyp angeben, den Sie bereitstellen möchten. Die Testplattform hat einen bekannten Typ TestNodeUpdateMessage definiert, der das Konzept der Testaktualisierungsinformationen darstellt.
In diesem Teil des Dokuments wird erläutert, wie Sie diese Nutzlastdaten verwenden. Sehen wir uns die Oberfläche genauer an:
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: DieTestNodeUpdateMessagebesteht aus zwei Eigenschaften: einemTestNodeund einerParentTestNodeUid. DieParentTestNodeUid-Eigenschaft gibt an, dass ein Test möglicherweise über einen übergeordneten Test verfügt, wodurch das Konzept einer Teststruktur eingeführt wird, in derTestNode-Instanzen in Bezug zueinander angeordnet werden können. Basierend auf der Baumbeziehung zwischen den Knoten ermöglicht diese Struktur zukünftige Verbesserungen und Funktionen. Wenn Ihr Testframework keine Testbaumstruktur erfordert, können Sie es einfach auf null setzen, sodass Sie eine einfache flache Liste vonTestNodes erhalten.TestNode: DerTestNodebesteht aus drei Eigenschaften, von denen eine dieUidvom TypTestNodeUidist. DieseUiddient als EINDEUTIGE STABILE ID für den Knoten. Der Begriff EINDEUTIGE STABILE ID impliziert, dass derselbeTestNodebei unterschiedlichen Ausführungen und auf verschiedenen Betriebssystemen eine IDENTISCHEUidbeibehalten sollte. DieTestNodeUidist eine beliebige nicht transparente Zeichenfolge, die von der Testplattform unverändert akzeptiert wird.
Von Bedeutung
Die Stabilität und Eindeutigkeit der ID sind in der Testdomäne von entscheidender Bedeutung. Sie ermöglichen die genaue Ausrichtung der Ausführung auf einen einzelnen Test und die Verwendung der ID als persistenten Bezeichner für einen Test, wodurch leistungsstarke Erweiterungen und Features ermöglicht werden.
Die zweite Eigenschaft ist DisplayName, der benutzerfreundliche Name für den Test. Dieser Name wird beispielsweise angezeigt, wenn Sie die Befehlszeile --list-tests ausführen.
Das dritte Attribut ist Properties, ein PropertyBag-Typ. Wie im Code gezeigt, ist dies ein spezieller Eigenschaftenbehälter, der generische Eigenschaften in Bezug auf die TestNodeUpdateMessage enthält. Dies bedeutet, dass Sie eine beliebige Eigenschaft an den Knoten anfügen können, der die Platzhalterschnittstelle IProperty implementiert.
Die Testplattform identifiziert bestimmte Eigenschaften, die TestNode.Properties hinzugefügt wurden, um zu bestimmen, ob ein Test erfolgreich war, fehlgeschlagen ist oder übersprungen wurde.
Sie finden die aktuelle Liste der verfügbaren Eigenschaften mit der relativen Beschreibung im Abschnitt TestNodeUpdateMessage.TestNode.
Auf den PropertyBag-Typ kann in der Regel in jeder IData-Schnittstelle zugegriffen werden. Er wird verwendet, um verschiedene Eigenschaften zu speichern, die von der Plattform und den Erweiterungen abgefragt werden können. Dieser Mechanismus ermöglicht es, die Plattform mit neuen Informationen zu erweitern, ohne inkompatible Änderungen einzuführen. Wenn eine Komponente die Eigenschaft erkennt, kann sie sie abfragen. Andernfalls ignoriert sie die Eigenschaft.
Schließlich macht dieser Abschnitt deutlich, dass Ihre Testframework-Implementierung die IDataProducer-Schnittstelle implementieren muss, die TestNodeUpdateMessages wie im folgenden Beispiel erzeugt:
internal sealed class TestingFramework
: ITestFramework, IDataProducer
{
// ...
public Type[] DataTypesProduced =>
[
typeof(TestNodeUpdateMessage)
];
// ...
}
Wenn Ihr Testadapter die Veröffentlichung von Dateien während der Ausführung erfordert, finden Sie die erkannten Eigenschaften in dieser Quelldatei: https://github.com/microsoft/testfx/blob/main/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs. Wie Sie sehen, können Sie Dateiressourcen auf allgemeine Weise bereitstellen oder sie einem bestimmten TestNode zuordnen. Wenn Sie vorhaben, ein SessionFileArtifact zu pushen, müssen Sie daran denken, dieses wie unten dargestellt vorab gegenüber der Plattform zu deklarieren:
internal sealed class TestingFramework
: ITestFramework, IDataProducer
{
// ...
public Type[] DataTypesProduced =>
[
typeof(TestNodeUpdateMessage),
typeof(SessionFileArtifact)
];
// ...
}
Bekannte Eigenschaften
Wie im Anfrageabschnitt beschrieben, identifiziert die Testplattform bestimmte Eigenschaften, die dem TestNodeUpdateMessage hinzugefügt werden, um den Status eines TestNode zu bestimmen (z. B. erfolgreich, fehlgeschlagen, übersprungen usw.). Auf diese Weise kann die Runtime eine genaue Liste der fehlgeschlagenen Tests mit den entsprechenden Informationen in der Konsole anzeigen und den entsprechenden Exitcode für den Testprozess festlegen.
In diesem Abschnitt erläutern wir die verschiedenen bekannten IProperty-Optionen und ihre jeweiligen Auswirkungen.
Eine umfassende Liste bekannter Eigenschaften finden Sie unter TestNodeProperties.cs. Wenn Sie feststellen, dass eine Eigenschaftsbeschreibung fehlt, geben Sie bitte ein Problem an.
Diese Eigenschaften lassen sich in folgende Kategorien unterteilen:
- Allgemeine Informationen: Eigenschaften, die in jede Anforderung eingeschlossen werden können.
-
Ermittlungsinformationen: Eigenschaften, die während einer Ermittlungsanforderung
DiscoverTestExecutionRequestbereitgestellt werden. -
Ausführungsinformationen: Eigenschaften, die während einer Testausführungsanforderung
RunTestExecutionRequestbereitgestellt werden.
Bestimmte Eigenschaften sind erforderlich und andere optional. Die obligatorischen Eigenschaften sind erforderlich, um grundlegende Testfunktionen bereitzustellen, z. B. das Melden fehlgeschlagener Tests und die Angabe, ob die gesamte Testsitzung erfolgreich war oder nicht.
Optionale Eigenschaften verbessern hingegen die Testerfahrung, indem sie zusätzliche Informationen bereitstellen. Sie sind besonders nützlich in IDE-Szenarien (Integrated Development Environment, integrierte Entwicklungsumgebung) wie z. B. Visual Studio und Visual Studio Code, bei Konsolenausführungen oder bei der Unterstützung bestimmter Erweiterungen, die detailliertere Informationen erfordern, damit sie korrekt funktionieren. Diese optionalen Eigenschaften haben jedoch keine Auswirkung auf die Ausführung der Tests.
Hinweis
Erweiterungen müssen Warnungen generieren und Ausnahmen verwalten, wenn für ihre ordnungsgemäße Funktion bestimmte Informationen erforderlich sind. Wenn eine Erweiterung nicht über die erforderlichen Informationen verfügt, sollte sie nicht zum Fehlschlagen der Testausführung führen, sondern sich einfach dagegen entscheiden, teilzunehmen.
Allgemeine Informationen
public record KeyValuePairStringProperty(
string Key,
string Value)
: IProperty;
Die KeyValuePairStringProperty steht für allgemeine Daten in Form von Schlüssel-Wert-Paaren.
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 wird verwendet, um die Position des Tests innerhalb der Quelldatei genau zu bestimmen. Dies ist besonders hilfreich, wenn der Initiator eine IDE wie Visual Studio oder Visual Studio Code ist.
public sealed record TestMethodIdentifierProperty(
string AssemblyFullName,
string Namespace,
string TypeName,
string MethodName,
string[] ParameterTypeFullNames,
string ReturnTypeFullName)
TestMethodIdentifierProperty ist ein eindeutiger Bezeichner für eine Testmethode, die dem ECMA-335-Standard entspricht.
Hinweis
Die zum Erstellen dieser Eigenschaft erforderlichen Daten können bequem mithilfe des .NET-Reflexionsfeatures mit Typen aus dem System.Reflection-Namespace abgerufen werden.
public sealed record TestMetadataProperty(
string Key,
string Value)
TestMetadataProperty wird verwendet, um die Eigenschaften oder Merkmale eines TestNode zu übermitteln.
Discovery-Informationen
public sealed record DiscoveredTestNodeStateProperty(
string? Explanation = null)
{
public static DiscoveredTestNodeStateProperty CachedInstance { get; }
}
Die DiscoveredTestNodeStateProperty gibt an, dass dieser Testknoten (TestNode) erkannt wurde. Wird verwendet, wenn ein DiscoverTestExecutionRequest an das Testframework gesendet wird.
Notieren Sie sich den praktischen zwischengespeicherten Wert, den die CachedInstance-Eigenschaft bereitstellt.
Diese Eigenschaft ist erforderlich.
Ausführungsinformationen
public sealed record InProgressTestNodeStateProperty(
string? Explanation = null)
{
public static InProgressTestNodeStateProperty CachedInstance { get; }
}
Die InProgressTestNodeStateProperty informiert die Testplattform, dass der TestNode für die Ausführung geplant ist und derzeit ausgeführt wird.
Notieren Sie sich den praktischen zwischengespeicherten Wert, den die CachedInstance-Eigenschaft bereitstellt.
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; }
}
Die TimingProperty wird verwendet, um zeitliche Details zur TestNode-Ausführung zu übermitteln. Sie ermöglicht auch die zeitliche Steuerung einzelner Ausführungsschritte über StepTimingInfo. Dies ist besonders nützlich, wenn Ihr Testkonzept in mehrere Phasen unterteilt ist (z. B. Initialisierung, Ausführung und Bereinigung).
Nur eine der folgenden Eigenschaften ist erforderlich pro TestNode. Sie kommuniziert das Ergebnis des TestNode an die Testplattform.
public sealed record PassedTestNodeStateProperty(
string? Explanation = null)
: TestNodeStateProperty(Explanation)
{
public static PassedTestNodeStateProperty CachedInstance
{ get; } = new PassedTestNodeStateProperty();
}
PassedTestNodeStateProperty informiert die Testplattform, dass dieser TestNode bestanden wurde.
Notieren Sie sich den praktischen zwischengespeicherten Wert, den die CachedInstance-Eigenschaft bereitstellt.
public sealed record SkippedTestNodeStateProperty(
string? Explanation = null)
: TestNodeStateProperty(Explanation)
{
public static SkippedTestNodeStateProperty CachedInstance
{ get; } = new SkippedTestNodeStateProperty();
}
SkippedTestNodeStateProperty informiert die Testplattform, dass dieser TestNode übersprungen wurde.
Notieren Sie sich den praktischen zwischengespeicherten Wert, den die CachedInstance-Eigenschaft bereitstellt.
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 informiert die Testplattform, dass dieser TestNode nach einer Assertion fehlgeschlagen ist.
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 informiert die Testplattform, dass bei diesem TestNode ein Fehler aufgetreten ist. Dieser Fehler unterscheidet sich von der FailedTestNodeStateProperty, die für Assertionsfehler verwendet wird. Beispielsweise können Sie Probleme wie Testinitialisierungsfehler mit ErrorTestNodeStateProperty melden.
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 informiert die Testplattform, dass dieser TestNode aufgrund einer Zeitüberschreitung (Timeout) fehlgeschlagen ist. Sie können das Timeout mithilfe der Timeout-Eigenschaft melden.
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 informiert die Testplattform, dass dieser TestNode aufgrund einer Stornierung fehlgeschlagen ist.