Skip to content

Example: Gherkin Test Scenarios with Behave

A worked example of the automated regression testing LoopCheck is built for, from feature file to CI pipeline.

This is one example, not a platform requirement

LoopCheck is driven entirely through the Python API. This page works through one worked example of a test setup built on top of it — Gherkin feature files executed with Behave. Any other framework (pytest, a plain script, an existing in-house harness) can drive the same API just as well.

Use this as a blueprint for the structure, not as a prescribed toolchain.

Why this example

Gherkin keeps the test intent readable for people who do not write the test code — system engineers, reviewers, or auditors — while the step definitions underneath call the Python API directly. That separation is useful in regulated projects, which is why it is shown here in full.

Feature files

In this example, tests are written in .feature files using Behave's Gherkin syntax:

Feature: Safety Interlock Response

  Scenario: Door opening stops active operation
    Given the system is in state "Active"
    When the "Door Interlock" is opened
    Then the system transitions to "Idle" within 100 ms
    And the output "Enable" is deasserted within 50 ms

Mapping steps to hardware

Each Gherkin step maps to a Python function that calls the LoopCheck API:

Step Purpose
Given Establish preconditions (power-on sequences, mode selection)
When Trigger stimuli (toggle GPIO, inject analog value, send serial command)
Then Verify DUT responses (GPIO state, timing, protocol responses)

Scenario execution

Tests are started using behave. Each scenario is executed as follows:

  1. Setup (before_scenario via behave hook) — Initialize LoopCheck connection, bring DUT to a known state, start log capture
  2. Stimulus — Python steps command LoopCheck to assert signals or trigger a sequence on CPU2
  3. Observation — LoopCheck monitors DUT outputs and timestamps all transitions
  4. Assertion — Step definitions query the log for expected events within timing tolerances
  5. Teardown (after_scenario via behave hook) — Return all signals to safe defaults, stop log capture and generate output of results

Traceability

Behave generates structured JSON output after each test run. This output can be synced to systems such as Jama or Azure DevOps to maintain traceability between requirements, test cases, and execution results.

Tags in the .feature files link each scenario to its corresponding requirement for coverage reporting:

@testplan:TP-42 @tc:TC-107
Scenario: Door opening stops active operation

CI/CD integration

Since the test suite is invoked via a single command-line call, it fits into CI/CD pipelines. A self-hosted GitLab Runner or Azure Pipelines agent with network access to the LoopCheck hardware can run the test suite as part of a merge or pull request workflow, so that code changes are only accepted after passing the HIL tests, without requiring manual tests during reviews.

This applies to any runner that can invoke the test suite from the command line — it is not specific to Behave.

Using a different framework

Nothing in the platform depends on Behave. The pattern above maps directly onto other harnesses:

This example Equivalent elsewhere
before_scenario / after_scenario hooks pytest fixtures, setUp / tearDown
Given / When / Then step definitions Ordinary test functions calling the same API
Behave JSON output JUnit XML, or any report format your ALM tool ingests
@testplan: / @tc: tags pytest markers, or naming conventions

What stays the same in every case: setup, stimulus, observation against timestamped logs, assertion within timing tolerances, and teardown to safe defaults.

Adapting the system to a new DUT