Orcraft 1.1.3 public beta released 08-Nov-2026. The Free Plan and the Team trial are open; card payments and invoices open shortly.

Orcraft 1.1.3 public beta released 08-Nov-2026. The Free Plan and the Team trial are open; card payments and invoices open shortly.

Orcraft

The platform for test development and orchestration
that lets you and your AI Agents run the entire testing operation

Watch the demo

Orcraft Configuration Fields

Config fields are how a component declares what can be configured about it. They are plain class attributes, and they are read by the controller to build its run configuration panel, to validate a run before it starts, and to render the config table in the log.

Declaration

Config fields come from the OrcraftConfigField namespace and are declared on a config class:

class MyTestConfig(OrcraftTestConfig):
	name = OrcraftConfigField.Text(default="My Test")

	app_folder = OrcraftConfigField.PackageFolder(
		default="",
		label="App Folder",
		required=True,
		layout=OrcraftConfigField.Layout.NewRow,
	)

	attempts = OrcraftConfigField.Numeric(default=3, label="Attempts")

Inside the component the field reads as an ordinary attribute - self.config.app_folder - holding either the configured value or the declared default. There is no lookup by string key and no dictionary to keep in sync.

Output fields work the same way, from the OrcraftResultField namespace - see Orcraft Result Fields.

Inherited fields

Every config class starts with fields it did not declare. They fall into three groups by who may change them. All the overridable ones are optional - each has a working default, and redeclaring one in your config replaces that default without changing what the field is for.

Overridable in code

Set in your config class, fixed for the run.

Field Declared on Default Purpose
name Every component per component Display name in the GUI, CLI and logs. Defaults to "Test", "Step", "Flow", "Test Group" or "Test Suite".
description Every component "" Free text describing what the component does.
log_orientation Every component HORIZONTAL Orientation of the logged config table, or OFF to leave it out of the log. On a test it also sets the tables of its cycles and cases. The result table has its own log_orientation.
version Suite, group, test "" Version recorded with the results.
palette Test "gray" Log color palette for the test and everything it runs.
endpoints_file_path Test "" The saved endpoints file the test's endpoint pools pick from outside the controller. Left empty, a test with a pool is refused there; the controller picks from its own endpoints.
groups / tests / items Suite / group / batch [] The children the component runs. Optional to the framework, but an empty list runs nothing.
Override carefully

Redeclare a field with the same OrcraftConfigField type and a new default - name = OrcraftConfigField.Text(default="My Test"). A bare assignment such as name = "My Test" is not an override: it shadows the field with a plain attribute, and the GUI, the log table and required validation no longer see it.

Overridable in code or GUI

Set in your config class, and changeable again from the run configuration panel before a run.

Field Declared on Default Purpose
test_endpoint Test "localhost" The endpoint the test executes against.
fanout_permutations Test None The endpoint permutations a test with two or more fanned-out endpoint fields runs, as the run dialog's ticks set them; None runs them all. The CI export writes the ticks into the snapshot as an OrcraftConfigField.Raw field, the type of a value the framework sets whole. Hidden from the panel unless redeclared.
matrix Test None The dimensions that expand into cases.
number_of_cycles Test 1 How many times the whole test repeats.
case_number_of_cycles Test 1 How many times each case repeats.
upload_test_package Test "if_missing" Whether the test package is uploaded to the endpoint before the run.
update_endpoint_app Test "on_mismatch" Whether the endpoint application is updated before the run.
Override carefully

Same rule as above: redeclare with the same OrcraftConfigField type and a new default, never a bare value. The default you set here is what the run configuration panel shows until someone changes it there.

Reserved

Written by the framework while a run is in progress. A config that redeclares one of these, or code that assigns one, is refused with an error naming the field.

Field Declared on Purpose
target_endpoint Step The endpoint the step is dispatched to. Set by the flow that runs the step.
expect_endpoint_disconnect Step Marks a step that is meant to take its endpoint offline. Set by the flow through run_step.
start_time Every component When the run started, stamped at run time.
log_tab Every component Log indentation. Assigned by the framework at every level.
Refused by the framework

A class of your own that declares one of these names fails as soon as it is defined, with an error naming the field, and an assignment to one at run time raises the same error. The framework alone writes them.

Common config field options

Every field type is constructed with keyword arguments, and these are the ones every type accepts. They describe the field to the controller - its default, how it is labelled and laid out, whether a run may start without it - rather than what the value means to your test:

input_folder = OrcraftConfigField.Folder(
	default="",
	label="Input Folder",
	required=True,
	layout=OrcraftConfigField.Layout.NewRow,
	input_placeholder="Folder containing the input files",
)

Type-specific arguments - options for a selection, port for an endpoint, endpoints for a package field - are covered with their types below.

Option Meaning
default The value used when nothing else is configured.
default_factory A callable producing the default. Use this - never default - for lists and for anything that constructs objects, so instances are not shared. Only one of the two may be given.
label The name shown in the GUI and in log tables. Without it the field is not user-facing.
required Blocks a run that leaves the field empty, reporting it as a missing argument. Numeric fields are required by default; pass required=False for one that may legitimately be blank.
layout Where the field is placed in the GUI panel - see Layout and presentation.
width Width hint, in grid units, for the input in the GUI.
formatter A callable that renders the value for display, leaving the stored value untouched.
input_placeholder Placeholder text shown in an empty input.
button_text Caption for the field's action button, where it has one.
options The fixed set of values a selection field offers.
options_lambda A callable evaluated when the panel opens, for a selection whose values are not known in advance.
endpoints For package fields: which endpoint fields this file or folder should be uploaded to.

Config field types

Every field type in the OrcraftConfigField namespace, grouped by what it selects.

Basic types

Type Value Notes
Text str Free text. Non-string values are coerced with str(); None becomes an empty string.
Numeric int or float Required by default, because a cleared numeric input has nothing to fall back on.
Boolean bool Rendered as a checkbox.
name = OrcraftConfigField.Text(default="Boolean Parameter")
verbose = OrcraftConfigField.Boolean(default=False, label="Verbose")
attempts = OrcraftConfigField.Numeric(default=3, label="Attempts")
timeout = OrcraftConfigField.Numeric(default=None, label="Timeout", required=False)

Selection types

Type Value Notes
Select str One value from a fixed options tuple.
MultiSelect tuple[str, ...] Any number of values from a fixed options tuple.
SelectLambda str One value from a list produced by options_lambda at configuration time.
MultiSelectLambda tuple[str, ...] Any number of values from a list produced by options_lambda.

Use the lambda variants when the choices are not knowable when the test is written - a list of firmware versions on a server, branches in a repository, devices currently attached. The callable runs when the run configuration is opened, so the list is current rather than committed to source.

mode = OrcraftConfigField.Select(
	default="fast",
	label="Mode",
	options=("fast", "thorough"),
)

version = OrcraftConfigField.SelectLambda(
	default="",
	label="Version",
	options_lambda=list_available_versions,
)

Filesystem types

Type Value Selects
File str A single file path.
Folder str A single folder path.
FileList tuple[str, ...] Any number of file paths.
FolderList tuple[str, ...] Any number of folder paths.

These give the GUI a browse button and store the chosen path. The path is used as-is: the file stays where it is, and the test reads it from there.

Package upload types

Type Value Selects
PackageFile str A single file, uploaded with the test package.
PackageFolder str A single folder, uploaded with the test package.
PackageFileList tuple[str, ...] Any number of files, uploaded with the test package.
PackageFolderList tuple[str, ...] Any number of folders, uploaded with the test package.

A package field is a filesystem field that travels. The controller uploads what it points at to the endpoints that need it before the run, and inside the test the value resolves to the path on the machine the code is executing on. That is the difference that matters: a Folder is a path on the controller, a PackageFolder is a path that exists wherever the step runs.

The endpoints option binds a package field to specific endpoint fields, so files upload only where they are actually needed:

test_endpoint = OrcraftConfigField.Endpoint(default="localhost", label="Test Endpoint")
aux_endpoints = OrcraftConfigField.MultiSelectEndpoints(default=("localhost",), label="Aux Endpoints")

input_file = OrcraftConfigField.PackageFile(
	default="",
	label="Input File",
	required=True,
	endpoints=[test_endpoint],
)

input_folders = OrcraftConfigField.PackageFolderList(
	default=(),
	label="Input Folders",
	required=True,
	endpoints=[test_endpoint, aux_endpoints],
)

Without endpoints, a package field is uploaded to every endpoint the test uses.

Endpoint types

Type Value Meaning
Endpoint str One endpoint the test uses. A test may declare several - a producer and a consumer, for instance.
MultiSelectEndpoints tuple[str, ...] A set of endpoints used together within one run, iterated by the test itself.
EndpointFanout tuple[str, ...] A set of endpoints that each get their own run. Selecting three endpoints spawns three test runs.

All three accept port, secure_enabled and shared in addition to the shared options, and all three take an endpoint pool as their default in place of a machine name. Orcraft Endpoints covers what they do and when to reach for each field type.

Composition types

Type Declared on Holds
Groups Orcraft Test Suite config The group instances the suite runs.
Tests Orcraft Test Group config The test instances the group runs.
Matrix Orcraft Test config The dimensions that expand into cases.
Dimension Inside a matrix One named axis and its values.

Groups and Tests always use default_factory, because they construct component instances:

tests = OrcraftConfigField.Tests(
	default_factory=lambda: [
		MyFirstTest(),
		MySecondTest(),
	]
)

Matrix and Dimension have options of their own - generated values, exclusion rules, randomization and seeding. They are covered in Orcraft Matrix, alongside what they produce.

Layout and presentation

Member Meaning
Layout.NewRow Start the field on a new row of the configuration panel.
Layout.UnderPrevious Place the field directly beneath the previous one.
Format A presentation-only field, used for settings such as log orientation.
LogTableOrientation.HORIZONTAL Log the config table as a row of columns - compact for a handful of fields.
LogTableOrientation.VERTICAL Log one field per line - readable for many fields or long values.
LogTableOrientation.OFF Do not log the table at all - for components whose fields add nothing to the log.
log_orientation = OrcraftConfigField.Format(
	default=OrcraftConfigField.LogTableOrientation.VERTICAL
)

Every component logs two tables: a configuration table before it runs and a result table after. Each has its own log_orientation - the one on the config class controls the configuration table, the one on the result class controls the result table - so you can turn off one and keep the other. Turning off the configuration table also hides the description banner printed above it.

Test cycles, matrix cases and case cycles are built by the framework and have no config class of their own, so their Configuration tables follow the test's config: horizontal or vertical as the test's is, and OFF on a test's config hides the framework's cycle, case and matrix tables beneath it. The test's own Result table follows the result class the test assigns to self.result, and a case's Result table follows the class the body assigns to case.result, or reads as the test's does when the body assigns none. The demo suite's test_log_tables_off runs a matrix with two test cycles and two case cycles and prints nothing but plain log lines.

For example, a step whose inputs are obvious from its name can drop its configuration table and still log its result:

class MyStepConfig(OrcraftTestStepConfig):
	name = OrcraftConfigField.Text(default="My Step")
	log_orientation = OrcraftConfigField.Format(
		default=OrcraftConfigField.LogTableOrientation.OFF
	)

Plain attributes

Not everything a config carries has to be an Orcraft field. A plain class attribute is a legitimate way to hand a value to a component when nobody needs to see or edit it - the framework leaves it alone entirely:

class MyConsumeStepConfig(OrcraftTestStepConfig):
	name = OrcraftConfigField.Text(default="My Consume Step")
	sample_rate = OrcraftConfigField.Numeric(default=48000, label="Sample Rate")

	# Plain attributes: filled in by the calling flow, invisible everywhere else.
	calibration = None
	channel_map = ()

A flow sets them the same way it sets declared fields, through run_step keywords or the config constructor:

second_result = self.run_step(
	MyConsumeStep,
	sample_rate=self.config.sample_rate,
	calibration=first_result.calibration,
	channel_map=first_result.channel_map,
)
Aspect Orcraft field Plain attribute
Shown in the run configuration panel Yes, when it has a label Never
Logged in the config table Yes Never
Validated, coerced, required-checked Yes No - the value is stored as given
Settable through run_step keywords Yes Yes, as long as the attribute exists on the class
Travels to a remote endpoint with the step Yes Yes - see Type fidelity

The one rule is that the attribute must be declared on the class, even if only as None. run_step checks that the config has the name before setting it, so a keyword that matches nothing raises at the call site instead of silently creating an attribute nobody reads.

Use a plain attribute for data that is an implementation detail between a flow and its steps - a calibration table, a handle, a structure too large or too structured to be a GUI input. Use an Orcraft field for anything a person should be able to see or change before a run.

Not every inherited field is user-facing. name and description, for instance, are configured in code but not editable from the GUI, and fields whose value is at its default - a single cycle, an empty matrix - are hidden from the run panel rather than shown as clutter.

The two policy fields take a fixed set of values. upload_test_package:

Value Meaning
always Upload on every run. The safe choice while the suite is changing.
if_missing Upload only when the endpoint does not already have the package. The default.
never Never upload - the endpoint is expected to have the package already.

update_endpoint_app:

Value Meaning
always Update the endpoint application before every run.
on_mismatch Update only when the endpoint application does not match the controller. The default.
never Leave the endpoint application as it is.

Type to search the docs.

    ↑↓ navigate ↵ open Esc close