Orcraft Result Fields
A result reports whatever measurements its component chose to declare, on top of the status and descriptions every result carries. This page covers the declared fields, the inherited ones, and the counters each level sums from the level below. How the status itself is set is covered in Orcraft Statuses.
Result fields
Result fields come from the OrcraftResultField namespace and are declared on a result
class, exactly the way config fields are declared on a config class:
class MyTestResult(OrcraftTestResult):
measured_value = OrcraftResultField.Numeric(default=0, label="Measured Value")
within_limits = OrcraftResultField.Boolean(default=False, label="Within Limits")
output_file = OrcraftResultField.Text(default="", label="Output File")
log_orientation = OrcraftResultField.Format(
default=OrcraftResultField.LogTableOrientation.VERTICAL
)
| Type | Value |
|---|---|
Text |
str |
Numeric |
int or float |
Boolean |
bool |
Format |
Presentation-only, used for log_orientation. |
Each accepts default, default_factory, label and
formatter, with the same meanings they have for
config fields. A field with
a label appears in the logged result table and in the controller; one without stays
internal.
A formatter changes how a value is displayed without changing what is stored, which is
how a raw number becomes a percentage or a status becomes a colored word in the log.
Plain attributes
The same holds on the way out. A result can carry plain attributes alongside its declared fields, and the framework hands them to the caller without ever showing them:
class MyProduceStepResult(OrcraftTestStepResult):
item_count = OrcraftResultField.Numeric(default=0, label="Item Count")
# Plain attributes: for the calling flow, never a result column.
calibration = None
channel_map = ()
class MyProduceStep(OrcraftTestStep):
def _run_step(self) -> OrcraftTestStepResult:
self.result = MyProduceStepResult()
self.result.item_count = len(items)
self.result.calibration = {"gain": 0.98, "offset": -0.02}
self.result.channel_map = (0, 2, 1, 3)
return self.result
Declared fields are the step's visible surface: they appear in the logged result table and as result columns in the controller. Plain attributes are private to the flow that ran the step. They come back with the result - including from a remote endpoint, with their Python types intact - but they are deliberately excluded from the result columns, because they are often exactly the kind of thing nobody wants as a column: a whole state grid, a buffer, megabytes of structure that the next step needs and a table would render as noise.
Anything on the result that is not an Orcraft field, not underscored and not a method counts as a plain attribute - whether it was declared on the class or assigned in the body.
Inherited fields
Result classes inherit a set of fields they never declare. Overridden by user marks the ones your code may assign - none of them has to be, since every result is complete without them. Reserved marks the ones the framework writes as the run progresses, and its icon says how strictly: is a field the framework sets on your behalf - through a checkpoint, an exception - that you may still set directly; is fully reserved: the framework refuses a class that redeclares it and an assignment from your code, with an error naming the field. See the per-component pages for the counters each level adds on top.
| Field | Overridden by user (optional) | Reserved | Meaning |
|---|---|---|---|
status |
The component's outcome - one of the values listed under Statuses. The framework derives it from checkpoints and descriptions; assign it yourself only for ERROR. |
||
failure_description |
Why the system under test was judged incorrect. Set by you or by a failing checkpoint; setting it moves a passing result to FAIL on its own. |
||
error_description |
Why the component could not complete. Set by you, or by the framework on an uncaught exception. | ||
warning_description |
– | Something worth flagging that did not change the status. | |
finish_time |
– | When the component finished. | |
elapsed_time |
– | How long it took. | |
log_orientation |
– | Whether the result table is logged horizontally, vertically or not at all (OFF). Override its default in code. On a test it also sets its cases' Result tables, unless a case is given a result class of its own. |
Fields you may set are assigned at run time - case.result.warning_description = "..." -
not redeclared. Redeclare only to change a default, and then with the same
OrcraftResultField type:
log_orientation = OrcraftResultField.Format(default=OrcraftResultField.LogTableOrientation.VERTICAL).
A bare value on the class shadows the field, and the log table and the controller no longer see it.
A class of your own that declares one of the reserved 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. Only
log_orientation is meant to be redeclared, and only to change its default.
Aggregated counters
Each level above a case counts what happened beneath it, so a summary is available without any code keeping score:
| Result | Counters |
|---|---|
OrcraftTestResult |
total_cases, done_cases, passed_cases, failed_cases, error_cases, warning_cases |
OrcraftTestGroupResult |
The same case counters, plus total_tests, passed_tests, failed_tests, error_tests, warning_tests |
OrcraftTestSuiteResult |
The case and test counters, plus total_groups, passed_groups, failed_groups, error_groups, warning_groups |
Because case counts carry all the way to the top, a suite result answers both questions at once: how many of its groups came back clean, and how many individual cases were actually executed to get there.