Docs Manual Test Plans

Manual Test Plans

A manual test plan is a test plan whose every step waits for a human verdict.
Use it for exploratory release smoke, regulatory sign-off, UAT, or any scenario
where automation cannot decide pass/fail on its own.

There are two ways to make a run go fully manual:

  1. Build a manual plan from the start with the wizard. Every test case in
    the plan is created with executionMode: manual baked into its parameters,
    so any future run — scheduled, ad-hoc, or via CI — keeps the same contract.
  2. Override an existing plan at run time. POST a flag on the run request
    and every TCM item in this run goes manual, regardless of how the plan was
    originally configured. The plan itself is not mutated, so the next run
    without the override returns to the sticky per-item mode.

Both paths produce the same in-flight UX: every step appears in the run drawer
with a Pass / Fail / Skip verdict picker, a free-form comment field, and an
attachment uploader.

Path 1 — wizard (UI)

  1. Open the Test Plans page.
  2. Click Create manual test plan in the toolbar (the hand-raised icon
    between “Master Run” and the search box).
  3. Step 1 — Basics. Enter a name (≤200 chars) and an optional markdown
    description (≤4000 chars).
  4. Step 2 — Cases. Click Pick test cases… to open the TCM tree-picker.
    Select one or more cases. The wizard shows a live count of selected cases
    and lets you remove individual cases without re-opening the picker.
  5. Step 3 — Review. Verify the summary, then choose:
    • Save draft — creates the plan but does not start a run.
    • Create + Run — creates the plan and immediately dispatches a run with
      the manual override applied.

Keyboard: Esc closes the wizard; Cmd/Ctrl+Enter triggers the primary
action on the current step (Next on steps 1–2, Create + Run on step 3).

What the user sees during a manual run

Once a manual run is dispatched, the run-detail page opens with a drawer
on the right side. Each step appears in order with three buttons (Pass / Fail
/ Skip), a comment field, and an “Attach evidence” uploader. The orchestrator
suspends the poll deadline while a step waits for human action — testers can
take hours or even days. A 72-hour hard cap exists as a defence against runs
that are accidentally left open forever.

When the last step is resolved, the run finalises with the cumulative status:
all pass → passed; any fail → failed; any skip with no fail → partial.

Path 2 — override at run time (API + CI)

The override turns any plan into a one-off manual run without changing the
plan definition. Useful when you want to re-verify an automated suite by hand
after an incident, or when a release manager wants a spot-check without
forking the plan.

curl -X POST \
     -H "X-API-Key: $MOCKARTY_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"executionModeOverride":"manual"}' \
     "$MOCKARTY_URL/api/v1/test-plans/$PLAN_ID/run"

Allowed values for executionModeOverride:

Value Effect on TCM items
"" / omit No override. Every item uses its stored Parameters.executionMode.
"manual" Every item runs manually — every step gates for a human verdict.
"auto" Every item runs unattended (semi-automatic mode in TCM terms).

Any other value is rejected with HTTP 400 and code validation so a typo in
your CI script surfaces immediately instead of silently falling back to the
stored mode.

Precedence

When deciding the mode for a single item, the orchestrator applies the first
non-empty value it finds:

  1. executionModeOverride on the run request (if set).
  2. parameters.executionMode on the plan item.
  3. Default: manual.

Because the override is run-scoped, two runs of the same plan can have
different modes — e.g. a CI run with executionModeOverride: "auto" for the
nightly smoke, and an ad-hoc run with executionModeOverride: "manual" when
a tester wants to re-verify by hand.

Trigger from SDKs / CLI

The same executionModeOverride field is exposed across every official client.

Go SDK (sdk/go-sdk):

run, err := client.TestPlans().RunManual(ctx, "#42", mockarty.RunManualOptions{
    ExecutionModeOverride: "manual",
    RecordDetailed:        true,
    NotifyOnCompletion:    true,
    NotifyEmails:          []string{"qa-lead@example.com"},
})

Python SDK (sdk/py-sdk):

run = client.test_plans.run_manual(
    "#42",
    execution_mode_override="manual",
    record_detailed=True,
    notify_on_completion=True,
    notify_emails=["qa-lead@example.com"],
)

Java SDK (sdk/java-sdk):

TestPlanApi.RunManualOptions opts = new TestPlanApi.RunManualOptions()
    .executionModeOverride("manual")
    .recordDetailed(true)
    .notifyOnCompletion(true)
    .notifyEmails(List.of("qa-lead@example.com"));
TestPlanRun run = client.testPlans().runManual("#42", opts);

CLI (mockarty-cli):

mockarty-cli testplan run-manual '#42' \
    --execution-mode-override=manual \
    --record-detailed \
    --notify-on-completion \
    --notify-emails=qa-lead@example.com

Resolving a manual step

While a manual run is in flight, every step that gates for a verdict surfaces
in GET /api/v1/me/awaiting-manual (the same data the topbar bell renders).
Push the verdict via the resolve endpoint:

curl -X POST \
     -H "X-API-Key: $MOCKARTY_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"resolution":"pass","note":"smoke ok","noteFmt":"plain"}' \
     "$MOCKARTY_URL/api/v1/namespaces/$NS/tcm/case-runs/$CASE_RUN_ID/steps/$STEP_UID/resolve"

Or from a client:

mockarty-cli testplan resolve-step "$CASE_RUN_ID" "$STEP_UID" \
    --resolution=pass --note="smoke ok"
err := client.TestPlans().ResolveStep(ctx, caseRunID, stepUID, mockarty.ResolveStepOptions{
    Resolution: mockarty.StepResolutionPass,
    Note:       "smoke ok",
    NoteFmt:    "plain",
})
client.test_plans.resolve_step(
    case_run_id, step_uid,
    resolution="pass", note="smoke ok", note_fmt="plain",
)

CI scripts can use mockarty-cli me awaiting-manual --format=json to fail
fast if any manual gate is still open at the end of a pipeline:

count=$(mockarty-cli me awaiting-manual --format=json | jq '.count')
if [ "$count" -gt 0 ]; then
    echo "::error ::$count manual gates still open"
    exit 1
fi

CI/CD considerations

  • A manual run will never complete on its own. CI pipelines that wait for
    a terminal status (e.g. until status == passed) will hang. Either dispatch
    manual runs from a separate job that doesn’t block the pipeline, or use
    executionModeOverride: "auto" for the CI path and reserve manual mode for
    human-driven sessions.
  • Notifications fire on the same lifecycle events for manual and
    automated runs — a manual plan can still notify on completion via webhook
    or email when the last tester closes the last step.