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 framework overview

Component model

Orcraft models a test system as a hierarchy of components. Each level owns the level below it and contributes its own configuration and its own result.

Component Base class Contains Run method you write
Orcraft Test Batch OrcraftTestBatch Suites, groups and tests None - the config lists the suites, groups and tests to run
Orcraft Test Suite OrcraftTestSuite Groups None - the config lists the groups
Orcraft Test Group OrcraftTestGroup Tests None - the config lists the tests
Orcraft Test OrcraftTest Cases _run_case(case)
Orcraft Test Case OrcraftTestCase Case cycles None - the test's matrix generates its cases; you never subclass it
Orcraft Test Flow OrcraftTestFlow Steps _run_flow()
Orcraft Test Step OrcraftTestStep The smallest unit of work _run_step()

Every level but the case is written the same way: a config class, a result class and the component class that pairs them. What differs is whether there is a method to run - the declared levels hold their children in a config field, and the framework does the rest.

The first five levels are the structural hierarchy: a batch gathers suites, groups and tests to run as one, a suite holds groups, a group holds tests, and a test expands into cases. Flows and steps are the procedural hierarchy: they are what a case body actually does. A case may call flows, a flow calls steps, and a step is the unit that can be dispatched to a remote endpoint.

Every level is optional above and below the one you need. A single test file with a main() runs on its own without a group or a suite, and a case that only needs a few lines of Python does not have to be split into flows and steps at all. The pages in this section follow that order of dependence: the building blocks first - configuration fields, statuses and result fields - then the test that uses them, and outward from there to steps, flows, endpoints, groups and suites.

Orcraft package

The Orcraft test framework is the plain-Python library your tests are written against. It ships with the controller and is imported from a single package:

from orcraft import (
	OrcraftTest,
	OrcraftTestConfig,
	OrcraftTestCase,
	OrcraftConfigField,
)

There is no domain-specific language, no runner conventions and no decorators to memorize. A test is a Python class that inherits from a framework base class, declares its configuration as class attributes, and implements one method. Everything else - discovery, configuration, distribution to endpoints, execution, logging and result collection - is what the controller does with that class.

Because a suite is ordinary Python, the same files run without modification: standalone from the command line, from the controller GUI, from the controller CLI in a CI pipeline, and from an AI agent that sets the configuration in a subclass. The Tutorial walks through building one step by step; this section is the reference for what the framework itself offers.

Config, component, result

Whatever the level, a component is always three classes - a config that declares its inputs, the component that holds its behavior, and a result that declares its outputs:

class MyTestConfig(OrcraftTestConfig):
	name = OrcraftConfigField.Text(default="My Test")
	payload_size = OrcraftConfigField.Numeric(default=64, label="Payload Size")


class MyTestResult(OrcraftTestResult):
	measured_value = OrcraftResultField.Numeric(default=0, label="Measured Value")


class MyTest(OrcraftTest):
	def __init__(self, config: MyTestConfig | None = None) -> None:
		super().__init__(config or MyTestConfig())

	def _run_case(self, case: OrcraftTestCase):
		case.result = MyTestResult()
		case.result.measured_value = measure(self.config.payload_size)
		return case.result

Those declarations are not just Python defaults. The controller reads them to build the run configuration panel in the GUI, to validate that required values are supplied before a run starts, and to render the config and result tables in the log. A field added to a config class appears in the GUI with no further wiring.

Public API

Everything the framework exposes is importable directly from orcraft. Each entry links to the page that covers it:

Export Purpose
OrcraftTest, OrcraftTestConfig, OrcraftTestResult Orcraft Test - the unit that expands into cases, and the smallest thing worth running on its own.
OrcraftConfigField Namespace of config (input) field types.
OrcraftResultField Namespace of result (output) field types.
OrcraftStatus The PASS / FAIL / ERROR status enumeration.
OrcraftTestCase Orcraft Test Case - the per-case object handed to _run_case.
OrcraftTestStep, OrcraftTestStepConfig, OrcraftTestStepResult Orcraft Test Step - the smallest unit of work, and the unit of remote execution.
OrcraftTestFlow, OrcraftTestFlowConfig, OrcraftTestFlowResult Orcraft Test Flow - an ordered sequence of steps with a shared result.
OrcraftEndpointState Endpoint availability, for tests that drive an endpoint offline and back.
OrcraftTestGroup, OrcraftTestGroupConfig, OrcraftTestGroupResult Orcraft Test Group - a collection of related tests.
OrcraftTestSuite, OrcraftTestSuiteConfig, OrcraftTestSuiteResult Orcraft Test Suite - the top-level collection of groups.
OrcraftTestBatch, OrcraftTestBatchConfig, OrcraftTestBatchResult, OrcraftTestBatchItem Orcraft Test Batch - any mix of suites, groups and tests run as one; what a CI snapshot is.
OrcraftLogger Structured, colored logging that the controller renders in its log panel.

Type to search the docs.

    ↑↓ navigate ↵ open Esc close