Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo explica como criar uma estrutura de testes personalizada para a Microsoft.Testing.Platform. O framework de teste é a única extensão obrigatória. Descobre e executa testes, e reporta resultados à plataforma.
Para o resumo completo do ponto de extensão e conceitos em processo/fora de processo, veja Criar extensões personalizadas.
Se estiver a migrar um framework de teste já existente baseado em VSTest, implementar a ITestFramework interface nativamente é a abordagem recomendada. A extensão VSTest Bridge está disponível como um passo de transição, mas uma implementação nativa proporciona a melhor experiência.
Extensão da estrutura de teste
A estrutura de teste é a principal extensão que fornece à plataforma de teste a capacidade de descobrir e executar testes. A estrutura de teste é responsável por comunicar os resultados dos testes de volta para a plataforma de teste. A estrutura de teste é a única extensão obrigatória necessária para executar uma sessão de teste.
Registrar uma estrutura de teste
Esta seção explica como registrar a estrutura de teste com a plataforma de teste. Você registra apenas uma estrutura de teste por cada criador de aplicações de teste usando a API TestApplication.RegisterTestFramework conforme mostrado na documentação da arquitetura Microsoft.Testing.Platform.
A API de registro é definida da seguinte forma:
ITestApplicationBuilder RegisterTestFramework(
Func<IServiceProvider, ITestFrameworkCapabilities> capabilitiesFactory,
Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework> adapterFactory);
A API RegisterTestFramework espera duas fábricas:
Func<IServiceProvider, ITestFrameworkCapabilities>: Este é um delegado que aceita um objeto que implementa a interfaceIServiceProvidere retorna um objeto que implementa a interfaceITestFrameworkCapabilities. OIServiceProviderfornece acesso a serviços da plataforma, como configurações, registradores e argumentos de linha de comando.A interface
ITestFrameworkCapabilitiesé usada para anunciar os recursos suportados pela estrutura de teste para a plataforma e extensões. Permite que a plataforma e as extensões interajam corretamente, implementando e suportando comportamentos específicos. Para uma melhor compreensão do conceito de capacidades, consulte a respetiva secção.Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework>: Este é um delegado que recebe um objeto ITestFrameworkCapabilities, que é a instância retornada peloFunc<IServiceProvider, ITestFrameworkCapabilities>, e um IServiceProvider para fornecer novamente acesso aos serviços da plataforma. O objeto de retorno esperado é aquele que implementa o ITestFramework interface. OITestFrameworkserve como o mecanismo de execução que descobre e executa testes e, em seguida, comunica os resultados de volta para a plataforma de teste.
A necessidade de a plataforma separar a criação do ITestFrameworkCapabilities e a criação do ITestFramework é uma otimização para evitar a criação do framework de teste se os recursos suportados não forem suficientes para executar a sessão de teste atual.
Considere o seguinte exemplo de código de usuário, que demonstra um registro de estrutura de teste que retorna um conjunto de recursos vazio:
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));
}
}
// ...
Agora, considere o ponto de entrada correspondente deste exemplo com o código de registro:
var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args);
// Register the testing framework
testApplicationBuilder.AddTestingFramework();
using var testApplication = await testApplicationBuilder.BuildAsync();
return await testApplication.RunAsync();
Observação
Retornar ITestFrameworkCapabilities vazio não deve impedir a execução da sessão de teste. Todas as estruturas de teste devem ser capazes de descobrir e executar testes. O impacto deve limitar-se a extensões que podem optar por não participar se o quadro de ensaio não tiver uma determinada funcionalidade.
Criar uma estrutura de teste
O Microsoft.Testing.Platform.Extensions.TestFramework.ITestFramework é implementado por extensões que fornecem uma estrutura de teste:
public interface ITestFramework : IExtension
{
Task<CreateTestSessionResult> CreateTestSessionAsync(CreateTestSessionContext context);
Task ExecuteRequestAsync(ExecuteRequestContext context);
Task<CloseTestSessionResult> CloseTestSessionAsync(CloseTestSessionContext context);
}
O interface IExtension
A ITestFramework interface herda da IExtension interface, interface da qual todos os pontos de extensão herdam.
IExtension é usado para recuperar o nome e a descrição da extensão. O IExtension também fornece uma maneira de ativar ou desativar dinamicamente a extensão na instalação, através Task<bool> IsEnabledAsync(). Por favor, certifique-se de devolver true deste método, caso não tenha requisitos específicos para o desativar.
O método CreateTestSessionAsync
O método CreateTestSessionAsync é chamado no início da sessão de teste e é usado para inicializar a estrutura de teste. A API aceita um objeto CreateTestSessionContext e retorna um CreateTestSessionResult.
public sealed class CreateTestSessionContext : TestSessionContext
{
public CancellationToken CancellationToken { get; }
}
A SessionUid propriedade é herdada de TestSessionContext (ver a secção TestSessionContext).
O CancellationToken é usado para interromper a execução de CreateTestSessionAsync.
O objeto de retorno é um CreateTestSessionResult:
public sealed class CreateTestSessionResult
{
public string? WarningMessage { get; set; }
public string? ErrorMessage { get; set; }
public bool IsSuccess { get; set; }
}
A propriedade IsSuccess é usada para indicar se a criação da sessão foi bem-sucedida. Quando ele retorna false, a execução do teste é interrompida.
O método CloseTestSessionAsync
O método CloseTestSessionAsync é justaposto ao CreateTestSessionAsync em funcionalidade, com a única diferença sendo os nomes dos objetos. Para obter mais informações, consulte a seção CreateTestSessionAsync.
O método ExecuteRequestAsync
O método ExecuteRequestAsync aceita um objeto do tipo ExecuteRequestContext. Esse objeto, como sugerido por seu nome, contém as especificidades sobre a ação que se espera que a estrutura de teste execute.
A definição ExecuteRequestContext é:
public sealed class ExecuteRequestContext
{
public IRequest Request { get; }
public IMessageBus MessageBus { get; }
public CancellationToken CancellationToken { get; }
public void Complete();
}
IRequest: Esta é a interface base para qualquer tipo de solicitação. Você deve pensar na estrutura de teste como um servidor com estado em processo onde o ciclo de vida é:
O diagrama anterior ilustra que a plataforma de teste emite três solicitações após a criação da instância da estrutura de teste. A estrutura de teste processa essas solicitações e utiliza o serviço IMessageBus, que está incluído na própria solicitação, para entregar o resultado para cada solicitação específica. Uma vez que uma solicitação específica tenha sido tratada, a estrutura de teste invoca o método Complete() nela, indicando à plataforma de teste que a solicitação foi atendida.
A plataforma de testes monitora todas as solicitações enviadas. Uma vez que todas as solicitações tenham sido atendidas, ele invoca CloseTestSessionAsync e elimina a instância (se IDisposable/IAsyncDisposable for implementada).
É evidente que as solicitações e suas finalizações podem se sobrepor, permitindo a execução simultânea e assíncrona de solicitações.
Observação
Atualmente, a plataforma de testes não envia solicitações sobrepostas e aguarda a conclusão de uma solicitação >> antes de enviar a próxima. No entanto, esse comportamento pode mudar no futuro. O suporte para solicitações simultâneas será determinado através do sistema de capacidades .
A implementação IRequest especifica a solicitação precisa que precisa ser atendida. A estrutura de teste identifica o tipo de solicitação e a trata de acordo. Se o tipo de solicitação não for reconhecido, uma exceção deve ser gerada.
Você pode encontrar detalhes sobre as solicitações disponíveis na seção IRequest.
IMessageBus: Este serviço, vinculado à solicitação, permite que a estrutura de teste de forma assíncrona publique informações sobre a solicitação em andamento na plataforma de teste.
O barramento de mensagens serve como o hub central para a plataforma, facilitando a comunicação assíncrona entre todos os componentes e extensões da plataforma.
Para obter uma lista abrangente de informações que podem ser publicadas na plataforma de teste, consulte a seção IMessageBus.
CancellationToken: Este token é utilizado para interromper o processamento de uma solicitação específica.
Complete(): Como descrito na sequência anterior, o método Complete notifica a plataforma de que a solicitação foi processada com sucesso e todas as informações relevantes foram transmitidas para o IMessageBus.
Advertência
Negligenciar a invocação de Complete() na solicitação fará com que o aplicativo de teste pare de responder.
Para personalizar sua estrutura de teste de acordo com seus requisitos ou os de seus usuários, você pode usar uma seção personalizada dentro do arquivo de de configuração ou com opções de linha de comando personalizadas.
Tratamento de pedidos
A seção subsequente fornece uma descrição detalhada das várias solicitações que uma estrutura de teste pode receber e processar.
Antes de prosseguir para a próxima seção, é crucial compreender completamente o conceito do IMessageBus, que é o serviço essencial para transmitir informações de execução de teste para a plataforma de teste.
TestSessionContext
O TestSessionContext é uma propriedade compartilhada em todas as solicitações, fornecendo informações sobre a sessão de teste em andamento:
public class TestSessionContext
{
public SessionUid SessionUid { get; }
}
public readonly struct SessionUid(string value)
{
public string Value { get; }
}
O TestSessionContext consiste no SessionUid, um identificador exclusivo para a sessão de teste em andamento que ajuda no registro e correlação de dados da sessão de teste.
PedidoDeExecuçãoDeTesteDeDescoberta
public class DiscoverTestExecutionRequest
{
public TestSessionContext Session { get; }
public ITestExecutionFilter Filter { get; }
}
O DiscoverTestExecutionRequest instrui a estrutura de teste a descobrir os testes e comunicar essas informações pensadas para o IMessageBus.
Conforme descrito na seção anterior, a propriedade para um teste descoberto é DiscoveredTestNodeStateProperty. Aqui está um trecho de código genérico para referência:
var testNode = new TestNode
{
Uid = GenerateUniqueStableId(),
DisplayName = GetDisplayName(),
Properties = new PropertyBag(
DiscoveredTestNodeStateProperty.CachedInstance),
};
await context.MessageBus.PublishAsync(
this,
new TestNodeUpdateMessage(
discoverTestExecutionRequest.Session.SessionUid,
testNode));
// ...
ExecutarPedidoDeTeste
public class RunTestExecutionRequest
{
public TestSessionContext Session { get; }
public ITestExecutionFilter Filter { get; }
}
O RunTestExecutionRequest instrui a estrutura de teste a executar os testes e comunicar essas informações pensadas para o IMessageBus.
Aqui está um trecho de código genérico para referência:
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));
Os dados TestNodeUpdateMessage
Como mencionado na seção IMessageBus, antes de utilizar o barramento de mensagens, deve especificar o tipo de dados que pretende fornecer. A plataforma de teste definiu um tipo amplamente conhecido, TestNodeUpdateMessage, para representar o conceito de de informações de atualização de teste.
Esta parte do documento explicará como utilizar esses dados de carga útil. Vamos examinar a superfície:
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: OTestNodeUpdateMessageconsiste em duas propriedades: umTestNodee umParentTestNodeUid. OParentTestNodeUidindica que um teste pode ter um teste pai, introduzindo o conceito de uma árvore de teste ondeTestNodes podem ser organizados em relação uns aos outros. Esta estrutura permite futuras melhorias e funcionalidades baseadas na relação da árvore entre os nós. Se sua estrutura de teste não exigir uma estrutura de árvore de teste, você pode optar por não usá-la e simplesmente defini-la como nula, resultando em uma lista simples deTestNodes.TestNode: OTestNodeé composto por três propriedades, uma das quais é aUiddo tipoTestNodeUid. EsteUidserve como o ID ESTÁVEL ÚNICO para o nó. O termo UNIQUE STABLE ID implica que o mesmoTestNodedeve manter umUidIDÊNTICO em diferentes execuções e sistemas operativos. OTestNodeUidé uma cadeia de caracteres opaca arbitrária que a plataforma de teste aceita como está.
Importante
A estabilidade e a exclusividade do ID são cruciais no domínio de teste. Eles permitem o direcionamento preciso de um único teste para execução e permitem que o ID sirva como um identificador persistente para um teste, facilitando extensões e recursos poderosos.
A segunda propriedade é DisplayName, que é o nome amigável para o teste. Por exemplo, esse nome é exibido quando você executa a linha de comando --list-tests.
O terceiro atributo é Properties, que é um tipo PropertyBag. Como demonstrado no código, este é um conjunto de propriedades especializado que contém propriedades genéricas sobre o TestNodeUpdateMessage. Isto implica que se pode acrescentar qualquer propriedade ao nó que implementa a interface de marcador de posição IProperty.
A plataforma de teste identifica propriedades específicas adicionadas a um TestNode.Properties para determinar se um teste foi aprovado, reprovado ou ignorado.
Você pode encontrar a lista atual de propriedades disponíveis com a descrição relativa na seção TestNodeUpdateMessage.TestNode.
O tipo PropertyBag é normalmente acessível em todos os IData e é utilizado para armazenar propriedades diversas que podem ser consultadas pela plataforma e extensões. Este mecanismo permite-nos melhorar a plataforma com novas informações sem introduzir alterações significativas. Se um componente reconhece a propriedade, ele pode consultá-la; caso contrário, irá desconsiderá-la.
Finalmente, esta seção deixa claro que a implementação da estrutura de teste precisa implementar o IDataProducer que produz TestNodeUpdateMessagecomo no exemplo abaixo:
internal sealed class TestingFramework
: ITestFramework, IDataProducer
{
// ...
public Type[] DataTypesProduced =>
[
typeof(TestNodeUpdateMessage)
];
// ...
}
Se o adaptador de teste exigir a publicação de arquivos durante a execução, você poderá encontrar as propriedades reconhecidas neste arquivo de origem: https://github.com/microsoft/testfx/blob/main/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs. Como você pode ver, você pode fornecer ativos de arquivo de uma maneira geral ou associá-los a um TestNodeespecífico. Lembra-te que, se pretendes enviar um SessionFileArtifact, deves declará-lo previamente à plataforma, como demonstrado abaixo:
internal sealed class TestingFramework
: ITestFramework, IDataProducer
{
// ...
public Type[] DataTypesProduced =>
[
typeof(TestNodeUpdateMessage),
typeof(SessionFileArtifact)
];
// ...
}
Propriedades bem conhecidas
Conforme detalhado na seção de solicitações, a plataforma de teste identifica propriedades específicas adicionadas ao TestNodeUpdateMessage para determinar o status de um TestNode (por exemplo, bem-sucedido, reprovado, ignorado, etc.). Isso permite que o tempo de execução exiba com precisão uma lista de testes com falha com suas informações correspondentes no console e defina o código de saída apropriado para o processo de teste.
Neste segmento, elucidamos as várias opções de IProperty conhecidas e suas respetivas implicações.
Para obter uma lista abrangente de propriedades conhecidas, consulte TestNodeProperties.cs. Se você notar que uma descrição do imóvel está faltando, registre um problema.
Estas propriedades podem ser divididas nas seguintes categorias:
- Informações genéricas: Propriedades que podem ser incluídas em qualquer tipo de solicitação.
-
Informações de descoberta: Propriedades fornecidas durante uma solicitação de descoberta de
DiscoverTestExecutionRequest. -
Informações de execução: Propriedades que são fornecidas durante uma solicitação de execução de teste
RunTestExecutionRequest.
Algumas propriedades são necessárias, enquanto outras são opcionais. As propriedades obrigatórias são necessárias para fornecer funcionalidade de teste básica, como relatar testes com falha e indicar se toda a sessão de teste foi bem-sucedida ou não.
As propriedades opcionais, por outro lado, melhoram a experiência de teste fornecendo informações adicionais. Eles são particularmente úteis em cenários IDE (como VS, VSCode, etc.), execuções de console ou ao suportar extensões específicas que exigem informações mais detalhadas para funcionar corretamente. No entanto, essas propriedades opcionais não afetam a execução dos testes.
Observação
As extensões são encarregadas de alertar e gerenciar exceções quando exigem informações específicas para funcionar corretamente. Se uma extensão não tiver as informações necessárias, ela não deve fazer com que a execução do teste falhe, mas sim, deve simplesmente optar por não participar.
Informações genéricas
public record KeyValuePairStringProperty(
string Key,
string Value)
: IProperty;
O KeyValuePairStringProperty significa um par geral de dados de chave/valor.
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 é usado para identificar o local do teste dentro do arquivo de origem. Isto é particularmente útil quando o iniciador é um IDE como o Visual Studio ou o Visual Studio Code.
public sealed record TestMethodIdentifierProperty(
string AssemblyFullName,
string Namespace,
string TypeName,
string MethodName,
string[] ParameterTypeFullNames,
string ReturnTypeFullName)
TestMethodIdentifierProperty é um identificador único para um método de teste.
public sealed record TestMetadataProperty(
string Key,
string Value)
TestMetadataProperty é utilizado para transmitir as características ou as particularidades de um TestNode.
Informações de descoberta
public sealed record DiscoveredTestNodeStateProperty(
string? Explanation = null)
{
public static DiscoveredTestNodeStateProperty CachedInstance { get; }
}
O DiscoveredTestNodeStateProperty indica que este TestNode foi descoberto. Ele é utilizado quando um DiscoverTestExecutionRequest é enviado para o framework de teste.
Tome nota do prático valor armazenado em cache oferecido pela propriedade CachedInstance.
Esta propriedade é obrigatória.
Informações sobre a execução
public sealed record InProgressTestNodeStateProperty(
string? Explanation = null)
{
public static InProgressTestNodeStateProperty CachedInstance { get; }
}
O InProgressTestNodeStateProperty informa à plataforma de testes que o TestNode foi programado para execução e está em andamento.
Tome nota do prático valor armazenado em cache oferecido pela propriedade 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; }
}
O TimingProperty é utilizado para transmitir detalhes temporais sobre a execução de TestNode. Ele também permite a temporização das etapas de execução individuais via StepTimingInfo. Isso é particularmente útil quando seu conceito de teste é dividido em várias fases, como inicialização, execução e limpeza.
Uma e apenas uma das seguintes propriedades é necessária por TestNode e comunica o resultado do TestNode à plataforma de teste.
public sealed record PassedTestNodeStateProperty(
string? Explanation = null)
: TestNodeStateProperty(Explanation)
{
public static PassedTestNodeStateProperty CachedInstance
{ get; } = new PassedTestNodeStateProperty();
}
PassedTestNodeStateProperty informa a plataforma de testes que este TestNode foi aprovado.
Tome nota do prático valor armazenado em cache oferecido pela propriedade CachedInstance.
public sealed record SkippedTestNodeStateProperty(
string? Explanation = null)
: TestNodeStateProperty(Explanation)
{
public static SkippedTestNodeStateProperty CachedInstance
{ get; } = new SkippedTestNodeStateProperty();
}
SkippedTestNodeStateProperty informa a plataforma de testes que este TestNode foi ignorado.
Tome nota do prático valor armazenado em cache oferecido pela propriedade 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 informa a plataforma de teste que este TestNode falhou após uma verificação.
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 informa a plataforma de teste que este TestNode falhou. Este tipo de falha é diferente do FailedTestNodeStateProperty, que é usado para falhas de asserção. Por exemplo, você pode relatar problemas como erros de inicialização de teste com 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 informa a plataforma de teste que esse TestNode falhou por um motivo de tempo limite. Você pode reportar o tempo limite usando a propriedade 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 informa a plataforma de testes que este TestNode falhou devido ao cancelamento.