다음을 통해 공유


테스트 프레임워크 빌드

이 문서에서는 Microsoft.Testing.Platform에 대한 사용자 지정 테스트 프레임워크를 만드는 방법을 설명합니다. 테스트 프레임워크는 유일한 필수 확장입니다. 테스트를 검색하고 실행하고 결과를 플랫폼에 다시 보고합니다.

전체 확장 지점 요약 및 In-process/out-of-process 개념은 사용자 지정 확장 만들기를 참조하세요.

기존 VSTest 기반 테스트 프레임워크를 마이그레이션하는 경우 인터페이스를 ITestFramework 기본적으로 구현하는 것이 좋습니다. VSTest Bridge 확장은 전환 단계로 사용할 수 있지만 네이티브 구현은 최상의 환경을 제공합니다.

테스트 프레임워크 확장

테스트 프레임워크는 테스트를 검색하고 실행할 수 있는 기능을 테스트 플랫폼에 제공하는 기본 확장입니다. 테스트 프레임워크는 테스트 결과를 테스트 플랫폼에 다시 전달하는 역할을 담당합니다. 테스트 프레임워크는 테스트 세션을 실행하는 데 필요한 유일한 필수 확장입니다.

테스트 프레임워크 등록

이 섹션에서는 테스트 플랫폼에 테스트 프레임워크를 등록하는 방법을 설명합니다. TestApplication.RegisterTestFramework 설명서와 같이 API를 사용하여 테스트 애플리케이션 작성기당 하나의 테스트 프레임워크만 등록합니다.

등록 API는 다음과 같이 정의됩니다.

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

RegisterTestFramework API는 두 개의 공장을 기대합니다.

  1. Func<IServiceProvider, ITestFrameworkCapabilities>: IServiceProvider 인터페이스를 구현하는 개체를 수락하고 ITestFrameworkCapabilities 인터페이스를 구현하는 개체를 반환하는 대리자입니다. 이 IServiceProvider 구성, 로거 및 명령줄 인수와 같은 플랫폼 서비스에 대한 액세스를 제공합니다.

    ITestFrameworkCapabilities 인터페이스는 테스트 프레임워크에서 지원하는 기능을 플랫폼 및 확장에 알리는 데 사용됩니다. 이를 통해 플랫폼 및 확장은 특정 동작을 구현하고 지원하여 올바르게 상호 작용할 수 있습니다. 기능의개념을 더 잘 이해하려면 해당 섹션을 참조하세요.

  2. Func<ITestFrameworkCapabilities, IServiceProvider, ITestFramework>: 에 의해 반환된 Func<IServiceProvider, ITestFrameworkCapabilities> 개체와 IServiceProvider를 수용하여 플랫폼 서비스에 대한 액세스를 제공하는 대리자입니다. 예상되는 반환 개체는 ITestFramework 인터페이스를 구현하는 개체입니다. ITestFramework 테스트를 검색하고 실행한 다음, 결과를 테스트 플랫폼에 다시 전달하는 실행 엔진 역할을 합니다.

플랫폼이 ITestFrameworkCapabilities 만들기 및 ITestFramework 만들기를 구분해야 하는 것은 지원되는 기능이 현재 테스트 세션을 실행하기에 충분하지 않은 경우 테스트 프레임워크를 만들지 않도록 하기 위한 최적화입니다.

빈 기능 집합을 반환하는 테스트 프레임워크 등록을 보여 주는 다음 사용자 코드 예제를 살펴보겠습니다.

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

// ...

이제 등록 코드를 사용하여 이 예제의 해당 진입점을 고려합니다.

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

비고

ITestFrameworkCapabilities 반환해도 테스트 세션의 실행을 방지할 수 없습니다. 모든 테스트 프레임워크는 테스트를 검색하고 실행할 수 있어야 합니다. 테스트 프레임워크에 특정 기능이 없는 경우 옵트아웃할 수 있는 확장으로 영향을 제한해야 합니다.

테스트 프레임워크 만들기

Microsoft.Testing.Platform.Extensions.TestFramework.ITestFramework 테스트 프레임워크를 제공하는 확장에 의해 구현됩니다.

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

IExtension 인터페이스

인터페이스는 모든 확장 지점이 상속하는 ITestFramework 인터페이스에서 상속된 IExtension 인터페이스입니다. IExtension 확장의 이름과 설명을 검색하는 데 사용됩니다. 또한 IExtensionTask<bool> IsEnabledAsync()통해 설정에서 확장을 동적으로 사용하거나 사용하지 않도록 설정하는 방법을 제공합니다. 특정 요구 사항이 없고 이를 사용하지 않도록 설정하지 않는 경우에는 이 메서드에서 true를 반환해야 합니다.

CreateTestSessionAsync 메서드

CreateTestSessionAsync 메서드는 테스트 세션 시작 시 호출되며 테스트 프레임워크를 초기화하는 데 사용됩니다. API는 CreateTestSessionContext 개체를 허용하고 CreateTestSessionResult반환합니다.

public sealed class CreateTestSessionContext : TestSessionContext
{
    public CancellationToken CancellationToken { get; }
}

SessionUid 속성은 TestSessionContext에서 상속됩니다 ( TestSessionContext 섹션 참조). CancellationToken CreateTestSessionAsync실행을 중지하는 데 사용됩니다.

반환 개체는 CreateTestSessionResult:

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

IsSuccess 속성은 세션 만들기에 성공했는지 여부를 나타내는 데 사용됩니다. false반환하면 테스트 실행이 중지됩니다.

CloseTestSessionAsync 메서드

CloseTestSessionAsync 메서드는 기능 면에서 CreateTestSessionAsync과 비교되며, 유일한 차이점은 개체 이름입니다. 자세한 내용은 CreateTestSessionAsync 섹션을 참조하세요.

ExecuteRequestAsync 메서드

ExecuteRequestAsync 메서드는 ExecuteRequestContext형식의 개체를 허용합니다. 이 개체는 이름에서 제안한 대로 테스트 프레임워크가 수행해야 하는 작업에 대한 세부 정보를 보유합니다. ExecuteRequestContext 정의는 다음과 같습니다.

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

IRequest: 모든 유형의 요청에 대한 기본 인터페이스입니다. 테스트 프레임워크를 수명 주기가 있는 프로세스 내 상태 저장 서버로 생각해야 합니다.

테스트 프레임워크의 수명 주기를 나타내는 시퀀스 다이어그램입니다.

위의 다이어그램은 테스트 프레임워크 인스턴스를 만든 후 테스트 플랫폼이 세 가지 요청을 발급하는 것을 보여 줍니다. 테스트 프레임워크는 이러한 요청을 처리하고 요청 자체에 포함된 IMessageBus 서비스를 활용하여 각 특정 요청에 대한 결과를 제공합니다. 특정 요청이 처리되면 테스트 프레임워크는 요청이 처리되었음을 테스트 플랫폼에 나타내는 Complete() 메서드를 호출합니다. 테스트 플랫폼은 디스패치된 모든 요청을 모니터링합니다. 모든 요청이 처리되면 CloseTestSessionAsync 호출하고 인스턴스를 삭제합니다(IDisposable/IAsyncDisposable 구현된 경우). 요청과 해당 완료가 겹쳐서 요청의 동시 및 비동기 실행을 가능하게 할 수 있습니다.

비고

현재 테스트 플랫폼은 겹치는 요청을 보내지 않으며 다음 요청을 보내기 전에 요청 >> 완료될 때까지 기다립니다. 그러나 이 동작은 나중에 변경될 수 있습니다. 동시 요청에 대한 지원은 기능 시스템을 통해 결정됩니다.

IRequest 구현은 수행해야 하는 정확한 요청을 지정합니다. 테스트 프레임워크는 요청 유형을 식별하고 그에 따라 처리합니다. 요청 유형을 인식할 수 없는 경우 예외가 발생해야 합니다.

사용 가능한 요청에 대한 자세한 내용은 IRequest 섹션에서 확인할 수 있습니다.

IMessageBus: 요청과 연결된 이 서비스를 사용하면 테스트 프레임워크가 비동기적으로 테스트 플랫폼에 진행 중인 요청에 대한 정보를 게시할 수 있습니다. 메시지 버스는 플랫폼의 중앙 허브 역할을 하여 모든 플랫폼 구성 요소 및 확장 간의 비동기 통신을 용이하게 합니다. 테스트 플랫폼에 게시할 수 있는 포괄적인 정보 목록은 IMessageBus 섹션을 참조하세요.

CancellationToken: 이 토큰은 특정 요청의 처리를 중단하는 데 활용됩니다.

Complete(): 이전 시퀀스에 설명된 것처럼 Complete 메서드는 요청이 성공적으로 처리되었으며 모든 관련 정보가 IMessageBus전송되었음을 플랫폼에 알립니다.

경고

요청에서 Complete() 호출하지 않으면 테스트 애플리케이션이 응답하지 않습니다.

요구 사항 또는 사용자의 요구 사항에 따라 테스트 프레임워크를 사용자 지정하려면 구성 파일 내에서 또는 사용자 지정 명령줄 옵션개인 설정된 섹션을 사용할 수 있습니다.

요청 처리

후속 섹션에서는 테스트 프레임워크가 수신하고 처리할 수 있는 다양한 요청에 대한 자세한 설명을 제공합니다.

다음 섹션으로 진행하기 전에 테스트 실행 정보를 테스트 플랫폼에 전달하는 데 필수적인 서비스인 IMessageBus개념을 철저히 이해하는 것이 중요합니다.

TestSessionContext

TestSessionContext 진행 중인 테스트 세션에 대한 정보를 제공하는 모든 요청에서 공유 속성입니다.

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

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

TestSessionContext는 테스트 세션 데이터를 로깅하고 상관 관계를 지정하는 데 도움이 되는, 진행 중인 테스트 세션의 고유 식별자인 SessionUid로 구성됩니다.

테스트 실행 요청 검색

public class DiscoverTestExecutionRequest
{
    public TestSessionContext Session { get; }
    public ITestExecutionFilter Filter { get; }
}

DiscoverTestExecutionRequest 테스트 프레임워크 검색하고 이 정보를 IMessageBus전달하도록 지시합니다.

이전 섹션에서 설명한 대로 검색된 테스트의 속성은 DiscoveredTestNodeStateProperty. 참조를 위한 제네릭 코드 조각은 다음과 같습니다.

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

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

// ...

테스트 실행 요청

public class RunTestExecutionRequest
{
    public TestSessionContext Session { get; }
    public ITestExecutionFilter Filter { get; }
}

RunTestExecutionRequest 테스트 프레임워크 테스트 실행하고 이 정보를 IMessageBus전달하도록 지시합니다.

참조를 위한 제네릭 코드 조각은 다음과 같습니다.

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 데이터

IMessageBus 섹션에서 설명한 대로 메시지 버스를 활용하기 전에 제공하려는 데이터 형식을 지정해야 합니다. 테스트 플랫폼은 TestNodeUpdateMessage개념을 나타내기 위해 잘 알려진 형식인 정의했습니다.

문서의 이 부분에서는 이 페이로드 데이터를 활용하는 방법을 설명합니다. 표면을 살펴보겠습니다.

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: TestNodeUpdateMessageTestNodeParentTestNodeUid두 가지 속성으로 구성됩니다. ParentTestNodeUid은 테스트에 부모 테스트가 있을 수 있음을 나타내며, 서로 간에 로 배열할 수 있는, TestNode의 개념을 도입합니다. 이 구조를 사용하면 노드 간의 트리 관계를 기반으로 향후 향상된 기능과 기능을 사용할 수 있습니다. 테스트 프레임워크에 테스트 트리 구조가 필요하지 않은 경우 테스트 트리 구조를 사용하지 않도록 선택하고 null로 설정하면 TestNode간단한 플랫 목록이 생성됩니다.

  • TestNode: TestNode 세 가지 속성으로 구성되며, 그 중 하나는 Uid형식의 TestNodeUid. 이 Uid 노드에 대한 UNIQUE STABLE ID 역할을 합니다. UNIQUE STABLE ID 용어는 다른 실행 및 운영 체제에서도 동일한 TestNodeIDENTICALUid를 유지해야 함을 의미합니다. TestNodeUid 테스트 플랫폼에서 그대로 허용하는 임의 불투명 문자열.

중요합니다

ID의 안정성과 고유성은 테스트 도메인에서 매우 중요합니다. 단일 테스트의 정확한 실행을 대상으로 지정하고 ID를 테스트의 영구 식별자로 사용할 수 있도록 하여 강력한 확장 및 기능을 지원합니다.

두 번째 속성은 DisplayName( 테스트의 인간 친화적인 이름)입니다. 예를 들어 이 이름은 --list-tests 명령줄을 실행할 때 표시됩니다.

세 번째 특성은 Properties 형식인 PropertyBag. 코드에서 설명한 것처럼 이 속성 모음은 TestNodeUpdateMessage대한 제네릭 속성을 보유하는 특수한 속성 모음입니다. 이는 자리 표시자 인터페이스 IProperty구현하는 모든 속성을 노드에 추가할 수 있음을 의미합니다.

테스트 플랫폼은 TestNode.Properties에 추가된 특정 속성을 식별하여 테스트가 통과했는지, 실패했는지, 건너뛰었는지를 결정합니다.

TestNodeUpdateMessage.TestNode 섹션에서 상대 설명과 함께 사용 가능한 속성의 현재 목록을 찾을 수 있습니다.

PropertyBag 형식은 일반적으로 모든 IData 액세스할 수 있으며 플랫폼 및 확장에서 쿼리할 수 있는 기타 속성을 저장하는 데 활용됩니다. 이 메커니즘을 사용하면 호환성이 손상되는 변경을 도입하지 않고도 새 정보로 플랫폼을 향상시킬 수 있습니다. 구성 요소가 속성을 인식하는 경우 쿼리할 수 있습니다. 그렇지 않으면 무시됩니다.

마지막으로, 이 섹션은 아래 예시와 같이 IDataProducer을 생성하는 TestNodeUpdateMessage을 구현해야 하는 프레임워크 구현을 테스트하는 것을 명확히 합니다.

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

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

   // ...
}

테스트 어댑터가 실행 중에 파일을 게시해야 하는 경우, https://github.com/microsoft/testfx/blob/main/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs소스 파일에서 확인된 속성을 찾을 수 있습니다. 보시다시피, 파일 자산을 일반적으로 제공하거나 특정 TestNode에 연결할 수 있습니다. SessionFileArtifact푸시하려는 경우 아래와 같이 플랫폼에 미리 선언해야 합니다.

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

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

   // ...
}

잘 알려진 특성

요청 섹션에 자세히 설명된 대로 테스트 플랫폼은 추가된 특정 속성을 식별하여 TestNodeUpdateMessage 상태 TestNode (예: 성공, 실패, 건너뛰기 등)를 확인합니다. 이렇게 하면 런타임이 콘솔에서 해당 정보를 사용하여 실패한 테스트 목록을 정확하게 표시하고 테스트 프로세스에 적절한 종료 코드를 설정할 수 있습니다.

이 세그먼트에서는 잘 알려진 다양한 IProperty 옵션과 해당 의미를 설명합니다.

잘 알려진 속성의 포괄적인 목록은 TestNodeProperties.cs 참조하세요. 속성 설명이 누락된 경우 문제를 제출하세요.

이러한 속성은 다음 범주로 나눌 수 있습니다.

  1. 제네릭 정보: 모든 종류의 요청에 포함할 수 있는 속성입니다.
  2. 검색 정보: DiscoverTestExecutionRequest 검색 요청 중에 제공되는 속성입니다.
  3. 실행 정보: 테스트 실행 요청 RunTestExecutionRequest동안 제공되는 속성입니다.

특정 속성은 필요하지만다른 속성은 선택 사항입니다. 필수 속성은 실패한 테스트를 보고하고 전체 테스트 세션이 성공했는지 여부를 나타내는 것과 같은 기본 테스트 기능을 제공하는 데 필요합니다.

반면 선택적 속성은 추가 정보를 제공하여 테스트 환경을 향상시킵니다. 특히 IDE 시나리오(예: VS, VSCode 등), 콘솔 실행 또는 보다 자세한 정보가 필요한 특정 확장을 지원하는 경우에 유용합니다. 그러나 이러한 선택적 속성은 테스트 실행에 영향을 미치지 않습니다.

비고

확장은 특정 정보가 올바르게 작동해야 하는 경우 예외를 경고하고 관리하는 작업을 수행합니다. 확장에 필요한 정보가 없는 경우, 테스트 실행이 실패하지 않도록 하고, 대신 참여를 포기해야 합니다.

일반 정보
public record KeyValuePairStringProperty(
    string Key,
    string Value)
        : IProperty;

KeyValuePairStringProperty 일반 키/값 쌍 데이터를 나타냅니다.

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 소스 파일 내에서 테스트의 위치를 정확히 파악하는 데 사용됩니다. 이는 초기자가 Visual Studio 또는 Visual Studio Code 같은 IDE인 경우에 특히 유용합니다.

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

TestMethodIdentifierProperty 는 테스트 메서드의 고유 식별자입니다.

public sealed record TestMetadataProperty(
    string Key,
    string Value)

TestMetadataProperty은(는) TestNode 특성을 전달하는 데 활용됩니다.

검색 정보
public sealed record DiscoveredTestNodeStateProperty(
    string? Explanation = null)
{
    public static DiscoveredTestNodeStateProperty CachedInstance { get; }
}

DiscoveredTestNodeStateProperty 이 TestNode가 검색되었음을 나타냅니다. DiscoverTestExecutionRequest 테스트 프레임워크로 전송될 때 활용됩니다. CachedInstance 속성에서 제공하는 편리한 캐시된 값을 기록해 둡다. 이 속성은 반드시 필요합니다.

실행 정보
public sealed record InProgressTestNodeStateProperty(
    string? Explanation = null)
{
    public static InProgressTestNodeStateProperty CachedInstance { get; }
}

InProgressTestNodeStateProperty은 테스트 플랫폼에 TestNode이 실행되도록 예약되었으며 현재 진행 중임을 알립니다. 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; }
}

TimingProperty TestNode 실행에 대한 타이밍 세부 정보를 릴레이하는 데 사용됩니다. 또한 StepTimingInfo통해 개별 실행 단계의 타이밍을 허용합니다. 이는 테스트 개념을 초기화, 실행 및 정리와 같은 여러 단계로 나눌 때 특히 유용합니다.

다음 속성 중 하나만 필요하며 TestNode 결과를 테스트 플랫폼에 전달합니다.

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

PassedTestNodeStatePropertyTestNode이 통과되었음을 테스트 플랫폼에 알립니다. CachedInstance 속성에서 제공하는 편리한 캐시된 값을 기록해 둡다.

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

SkippedTestNodeStatePropertyTestNode을 건너뛰었다고 테스트 플랫폼에 알립니다. 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은 어설션 후 이 TestNode이 실패했음을 테스트 플랫폼에 알립니다.

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

ErrorTestNodeStatePropertyTestNode 실패했음을 테스트 플랫폼에 알릴 수 있습니다. 이러한 유형의 오류는 어설션 실패에 사용되는 FailedTestNodeStateProperty과 다릅니다. 예를 들어 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 시간 제한 이유로 이 TestNode 실패했음을 테스트 플랫폼에 알릴 수 있습니다. 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는 취소로 인해 이 TestNode이 실패했음을 테스트 플랫폼에 알립니다.