Skip to content

Commit b81cf80

Browse files
committed
tests: Extend test framework for driverless board qualification scenarios.
1 parent 0656179 commit b81cf80

3 files changed

Lines changed: 36 additions & 12 deletions

File tree

tests/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def pytest_configure(config):
2727
config.addinivalue_line("markers", "mock: tests that run with FakeI2C (no hardware)")
2828
config.addinivalue_line("markers", "hardware: tests that require a real board")
2929
config.addinivalue_line("markers", "manual: tests that require human validation")
30+
config.addinivalue_line("markers", "board: board qualification tests (no driver, hardware only)")
3031

3132

3233
def pytest_collection_modifyitems(config, items):

tests/runner/mpremote_bridge.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,21 @@ def run_script(
142142
last_line = output.strip().rsplit("\n", 1)[-1]
143143
return json.loads(last_line)
144144

145+
def run_raw_script(self, script):
146+
"""Run a raw MicroPython script on the board without driver context.
147+
148+
The script must set a ``result`` variable. Returns the
149+
JSON-decoded value of ``result``.
150+
"""
151+
code = (
152+
f"import json\n"
153+
f"{script}\n"
154+
f"print(json.dumps(result))"
155+
)
156+
output = self._run(code)
157+
last_line = output.strip().rsplit("\n", 1)[-1]
158+
return json.loads(last_line)
159+
145160
def scan_bus(self, i2c_config):
146161
"""Scan I2C bus and return list of addresses."""
147162
i2c_init = _i2c_init_code(i2c_config)

tests/test_scenarios.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,17 @@ def iter_scenario_tests():
3636
with open(yaml_file, encoding="utf-8") as f:
3737
scenario = yaml.safe_load(f)
3838

39-
driver = scenario["driver"]
39+
is_board = scenario.get("type") == "board"
40+
name = scenario.get("name", scenario.get("driver", yaml_file.stem))
4041
for test in scenario.get("tests", []):
4142
modes = test.get("mode", ["mock", "hardware"])
43+
if is_board:
44+
# Board scenarios are hardware-only
45+
modes = [m for m in modes if m == "hardware"]
4246
for mode in modes:
43-
test_id = f"{driver}/{test['name']}/{mode}"
44-
yield pytest.param(scenario, test, mode, id=test_id)
47+
test_id = f"{name}/{test['name']}/{mode}"
48+
marks = [pytest.mark.board] if is_board else []
49+
yield pytest.param(scenario, test, mode, id=test_id, marks=marks)
4550

4651

4752
def make_mock_instance(scenario):
@@ -154,15 +159,18 @@ def test_scenario(scenario, test, mode, port):
154159
input(f" [INTERACTIVE] {pre_prompt} ")
155160
else:
156161
print(f" [INTERACTIVE] {pre_prompt}")
157-
result = bridge.run_script(
158-
scenario["driver"],
159-
scenario["driver_class"],
160-
scenario["i2c"],
161-
test["script"],
162-
module_name=scenario.get("module_name"),
163-
hardware_init=scenario.get("hardware_init"),
164-
i2c_address=scenario.get("i2c_address"),
165-
)
162+
if scenario.get("type") == "board":
163+
result = bridge.run_raw_script(test["script"])
164+
else:
165+
result = bridge.run_script(
166+
scenario["driver"],
167+
scenario["driver_class"],
168+
scenario["i2c"],
169+
test["script"],
170+
module_name=scenario.get("module_name"),
171+
hardware_init=scenario.get("hardware_init"),
172+
i2c_address=scenario.get("i2c_address"),
173+
)
166174
else:
167175
pytest.fail(f"Unknown action: {action}")
168176

0 commit comments

Comments
 (0)