Skip to content

Add shared buffered Serial test helper - #1265

Open
VivienP wants to merge 1 commit into
PyLabRobot:mainfrom
VivienP:feat/io-test-helpers
Open

Add shared buffered Serial test helper#1265
VivienP wants to merge 1 commit into
PyLabRobot:mainfrom
VivienP:feat/io-test-helpers

Conversation

@VivienP

@VivienP VivienP commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Three driver test modules duplicate Serial buffering, lifecycle stubs and write recording. This adds pylabrobot.io.testing.fake_serial() and replaces those fixtures in the generic barcode scanner, KBiosystems sealer and Azenta IntelliXcap96 tests.

Related to #1235; this is a Serial-first increment.

The helper returns create_autospec(Serial, instance=True, spec_set=True) without constructing or opening a transport. It provides an instance-local receive buffer, responses appended by a synchronous on_write callback when writes are awaited, input-buffer reset, async lifecycle no-ops and synchronous timeout access with exception-safe restoration. Reads return immediately; non-positive sizes leave the buffer unchanged, matching pyserial's Windows/POSIX behavior.

Sealer command echoes and IntelliXcap STX/ETX framing remain in their test-local callbacks. Command assertions compare complete native write.await_args_list values against literal bytes, including terminators, and check call_count == await_count. Existing behavioral tests are retained.

Public methods outside the supported profile raise named NotImplementedError exceptions until explicitly configured through the native mock API. The profile includes unsupported file methods inherited from the standard-library io.IOBase; the Serial/FTDI inheritance change remains separate. Transport implementation tests retain their existing boundaries. There is no timing simulation, device emulator, assertion DSL or additional transport helper.

Validation on Windows with Python 3.12:

  • python -m pytest: 3212 passed, 0 failed, 1 skipped, 63 warnings in 1047.96 seconds. The skipped module is the_ghost_touch_tests.py, because optional Pillow (PIL) is absent. Warnings are outside the changed files, including existing deprecations and two unawaited-coroutine warnings in Spark tests.
  • Helper tests: 16 passed; the three migrated modules: 109 passed, with no skips. The broader pylabrobot/io suite: 134 passed, with no skips.
  • python -m ruff check pylabrobot: passed.
  • python -m ruff format --check pylabrobot: all 812 files formatted.
  • python -m mypy pylabrobot: one error in unchanged pylabrobot/thermo_fisher/btx/gemini/X2/the_ghost_touch.py:28, due to missing PIL. Mypy over the five changed files with --follow-imports=silent passes.
  • Commit hooks: Ruff format, Ruff check and typos passed.

Helper tests cover buffer slicing and isolation, callback responses and exceptions, reset behavior, timeout restoration, sync/async method shapes, unsupported methods and native overrides, exact write assertions, and unawaited writes. Negative controls cover wrong command bytes, wrong terminators, extra writes and missing writes. Validation used mocked transports and local test servers; no hardware validation is claimed.

@VivienP
VivienP requested a review from a team as a code owner September 12, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant