Table of Contents

Class Spec<TState>

Namespace
Microsoft.Accordant
Assembly
Accordant.Operations.dll

A Spec contains the list of operations that define the behavior of a stateful system. Each operation is registered under a unique name.

public class Spec<TState> : ISpec where TState : class, IState

Type Parameters

TState

The type of state the spec operates on.

Inheritance
Spec<TState>
Implements
Inherited Members

Properties

this[string]

The indexer property can be used to register operations under a given name and retrieve them given the registered name.

public IOperation this[string name] { get; set; }

Parameters

name string

Property Value

IOperation

Operations

The operations registered in this spec.

public IEnumerable<IOperation> Operations { get; }

Property Value

IEnumerable<IOperation>

Methods

Add(IOperation)

Registers an IOperation with this spec.

public void Add(IOperation operation)

Parameters

operation IOperation

The operation to register.

Allows(IOperation, object, object, StateProfile)

Validates whether the spec allows the observed response for the given operation, request, and state profile. This non-generic overload accepts object types for request and response, useful when the caller doesn't know the exact types at compile time.

public (bool IsValid, string Message, StateProfile UpdatedStateProfile) Allows(IOperation operation, object request, object response, StateProfile stateProfile)

Parameters

operation IOperation

The operation that was invoked.

request object

The request that was sent.

response object

The observed response from the system.

stateProfile StateProfile

The state profile representing possible states before the operation.

Returns

(bool IsValid, string Message, StateProfile UpdatedStateProfile)

A tuple of (isValid, explanationMessage, updatedStateProfile).

Allows(IOperation, object, object, TState)

Validates whether the spec allows the observed response for the given operation, request, and state. This non-generic overload accepts object types for request and response, useful when the caller doesn't know the exact types at compile time.

public (bool IsValid, string Message, StateProfile UpdatedStateProfile) Allows(IOperation operation, object request, object response, TState state)

Parameters

operation IOperation

The operation that was invoked.

request object

The request that was sent.

response object

The observed response from the system.

state TState

The state the system was in before the operation.

Returns

(bool IsValid, string Message, StateProfile UpdatedStateProfile)

A tuple of (isValid, explanationMessage, updatedStateProfile).

AllowsConcurrent(StateProfile, IList<(IOperation operation, object request, object response)>)

Validates whether the spec allows the observed responses for a set of operations that were invoked concurrently. If the responses can be explained by some logical ordering of the operations, returns the updated state profile. If not, returns an explanation message.

public (bool IsValid, string Message, StateProfile UpdatedStateProfile) AllowsConcurrent(StateProfile stateProfile, IList<(IOperation operation, object request, object response)> concurrentCalls)

Parameters

stateProfile StateProfile

The state profile representing possible states before the concurrent operations.

concurrentCalls IList<(IOperation operation, object request, object response)>

The list of concurrent operation calls with their requests and responses.

Returns

(bool IsValid, string Message, StateProfile UpdatedStateProfile)

A tuple of (isValid, explanationMessage, updatedStateProfile).

Allows<TRequest, TResponse>(Operation<TRequest, TResponse, TState>, TRequest, object, StateProfile)

Validates whether the spec allows the observed response for the given operation, request, and state profile. If valid, returns the updated state profile reflecting any state transitions. If not valid, returns an explanation message.

public (bool IsValid, string Message, StateProfile UpdatedStateProfile) Allows<TRequest, TResponse>(Operation<TRequest, TResponse, TState> operation, TRequest request, object response, StateProfile stateProfile)

Parameters

operation Operation<TRequest, TResponse, TState>

The operation that was invoked.

request TRequest

The request that was sent.

response object

The observed response from the system.

stateProfile StateProfile

The state profile representing possible states before the operation.

Returns

(bool IsValid, string Message, StateProfile UpdatedStateProfile)

A tuple of (isValid, explanationMessage, updatedStateProfile).

Type Parameters

TRequest

The type of request.

TResponse

The type of response.

Allows<TRequest, TResponse>(Operation<TRequest, TResponse, TState>, TRequest, object, TState)

Validates whether the spec allows the observed response for the given operation, request, and state. If valid, returns the updated state profile reflecting any state transitions. If not valid, returns an explanation message.

public (bool IsValid, string Message, StateProfile UpdatedStateProfile) Allows<TRequest, TResponse>(Operation<TRequest, TResponse, TState> operation, TRequest request, object response, TState state)

Parameters

operation Operation<TRequest, TResponse, TState>

The operation that was invoked.

request TRequest

The request that was sent.

response object

The observed response from the system.

state TState

The state the system was in before the operation.

Returns

(bool IsValid, string Message, StateProfile UpdatedStateProfile)

A tuple of (isValid, explanationMessage, updatedStateProfile).

Type Parameters

TRequest

The type of request.

TResponse

The type of response.

ConfigureDerivations(string, params RequestDerivation[])

Configures request derivations for an inline operation. This allows inline operations to have derivations without needing a class-based definition.

public Spec<TState> ConfigureDerivations(string operationName, params RequestDerivation[] derivations)

Parameters

operationName string

The name of the operation to configure derivations for.

derivations RequestDerivation[]

The derivations to set for this operation.

Returns

Spec<TState>

This spec for fluent chaining.

Examples

spec.Operation<(string, string), ApiResult<Todo>>("GetTodo", (req, state) => { ... });

spec.ConfigureDerivations("GetTodo",
    Derive.From<Todo, ApiResult<Todo>, (string, string)>("CreateTodo")
        .When((req, resp) => resp.IsSuccess)
        .As((req, resp) => (resp.Data.UserId, resp.Data.TodoId)));

Exceptions

InvalidOperationException

Thrown if the operation is not an inline operation (class-based operations should override DerivedFrom instead).

ConfigurePolling(string, PollingSetup)

Configures polling for an inline operation. This allows inline operations to have polling without needing a class-based definition.

public Spec<TState> ConfigurePolling(string operationName, PollingSetup polling)

Parameters

operationName string

The name of the operation to configure polling for.

polling PollingSetup

The polling setup for this operation.

Returns

Spec<TState>

This spec for fluent chaining.

Examples

spec.Operation<string, ApiResult<Job>>("CreateJob", (req, state) => { ... });

spec.ConfigurePolling("CreateJob", new PollingSetup
{
    Operation = "GetJob",
    WaitTimeInMs = 100,
    MaxRetryCount = 100
});

Exceptions

InvalidOperationException

Thrown if the operation is not an inline operation (class-based operations should override Polling instead).

CreateTestingContext(string)

Creates a new TestingContext for this spec.

public TestingContext CreateTestingContext(string testDirectoryPath = null)

Parameters

testDirectoryPath string

Optional path for test output.

Returns

TestingContext

A new testing context.

ExecuteWith<TTarget>()

Creates an ExecuteBuilder<TTarget, TState> for binding execution logic to operations in this spec.

public ExecuteBuilder<TTarget, TState> ExecuteWith<TTarget>()

Returns

ExecuteBuilder<TTarget, TState>

An ExecuteBuilder<TTarget, TState> for fluent binding.

Type Parameters

TTarget

The type of the system under test.

GenerateConcurrentTests(TState, InputSet, TestGenerationOptions)

Generates concurrent test cases from the given inputs.

public IList<ConcurrentTestCase> GenerateConcurrentTests(TState initialState, InputSet inputs, TestGenerationOptions options = null)

Parameters

initialState TState

The initial state for test generation.

inputs InputSet

The input set containing operation inputs to use.

options TestGenerationOptions

Additional test generation options.

Returns

IList<ConcurrentTestCase>

A list of concurrent test cases.

GenerateTests(TState, InputSet, TestGenerationOptions)

Generates sequential test cases from the given inputs.

public IList<SequentialTestCase> GenerateTests(TState initialState, InputSet inputs, TestGenerationOptions options = null)

Parameters

initialState TState

The initial state for test generation.

inputs InputSet

The input set containing operation inputs to use.

options TestGenerationOptions

Additional test generation options.

Returns

IList<SequentialTestCase>

A list of sequential test cases.

GetOperation(string)

This method returns the operation registered under the given name.

public IOperation GetOperation(string name)

Parameters

name string

Returns

IOperation

GetOperationName(IOperation)

This method returns the name the given operation was registered under.

public string GetOperationName(IOperation operation)

Parameters

operation IOperation

Returns

string

GetOperation<TRequest, TResponse>(string)

Gets a typed operation by name.

public Operation<TRequest, TResponse, TState> GetOperation<TRequest, TResponse>(string name)

Parameters

name string

The name of the operation.

Returns

Operation<TRequest, TResponse, TState>

The typed operation.

Type Parameters

TRequest

The request type.

TResponse

The response type.

Operation<TRequest, TResponse>(string, Func<TRequest, TState, ExpectedOutcomes>)

Creates and registers an inline operation using a lambda expression. Returns the spec for fluent chaining.

public Spec<TState> Operation<TRequest, TResponse>(string name, Func<TRequest, TState, ExpectedOutcomes> apply)

Parameters

name string

The name of the operation.

apply Func<TRequest, TState, ExpectedOutcomes>

The function that defines the operation's behavior.

Returns

Spec<TState>

This spec for fluent chaining.

Type Parameters

TRequest

The type of request.

TResponse

The type of response.

RegisterOperation(string, IOperation)

This method registers the given operation under the given name.

public void RegisterOperation(string name, IOperation operation)

Parameters

name string
operation IOperation

RegisterOperationProperties()

Automatically registers all public properties that implement IOperation. Call this in the derived Spec constructor after initializing operation properties.

protected void RegisterOperationProperties()

RunTests(TestingContext, TState, IList<ConcurrentTestCase>, TestExecutionOptions)

Runs the given concurrent test cases.

public Task<IList<TestCaseExecutionResult>> RunTests(TestingContext context, TState initialState, IList<ConcurrentTestCase> testCases, TestExecutionOptions options = null)

Parameters

context TestingContext

The testing context with registered services.

initialState TState

The initial state for each test.

testCases IList<ConcurrentTestCase>

The test cases to run.

options TestExecutionOptions

Execution options.

Returns

Task<IList<TestCaseExecutionResult>>

The execution results.

RunTests(TestingContext, TState, IList<SequentialTestCase>, TestExecutionOptions)

Runs the given sequential test cases.

public Task<IList<TestCaseExecutionResult>> RunTests(TestingContext context, TState initialState, IList<SequentialTestCase> testCases, TestExecutionOptions options = null)

Parameters

context TestingContext

The testing context with registered services.

initialState TState

The initial state for each test.

testCases IList<SequentialTestCase>

The test cases to run.

options TestExecutionOptions

Execution options.

Returns

Task<IList<TestCaseExecutionResult>>

The execution results.

VisualizeStateSpace(TState, InputSet, TestGenerationOptions, VisualizationOptions)

Generates a GraphViz DOT visualization of the state space explored during test generation. This is useful for understanding how test cases are generated and debugging state transitions.

public string VisualizeStateSpace(TState initialState, InputSet inputs, TestGenerationOptions generationOptions = null, VisualizationOptions visualizationOptions = null)

Parameters

initialState TState

The initial state for visualization.

inputs InputSet

The input set containing operation inputs to use.

generationOptions TestGenerationOptions

Test generation options that control state space exploration.

visualizationOptions VisualizationOptions

Options for customizing the visualization output.

Returns

string

A string containing the GraphViz DOT file content.

WithJsonPrinters()

Configures JSON serialization for both request and response logging. Uses System.Text.Json with default options.

public Spec<TState> WithJsonPrinters()

Returns

Spec<TState>

This spec for fluent chaining.

WithRequestPrinter(Func<object, string>)

Configures a custom request printer for logging during test execution.

public Spec<TState> WithRequestPrinter(Func<object, string> printer)

Parameters

printer Func<object, string>

A function that converts a request to a string for logging.

Returns

Spec<TState>

This spec for fluent chaining.

WithResponsePrinter(Func<object, string>)

Configures a custom response printer for logging during test execution.

public Spec<TState> WithResponsePrinter(Func<object, string> printer)

Parameters

printer Func<object, string>

A function that converts a response to a string for logging.

Returns

Spec<TState>

This spec for fluent chaining.