Uh oh!
There was an error while loading. Please reload this page.
Add roborock.testing — stateful device simulators for integration testing - #860
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new roborock.testing package intended to provide stateful device simulators, fake transport channels, and a fake cloud environment so downstream projects can write higher-fidelity integration tests against the real client codepaths.
Changes:
- Added
roborock.testingfakes:FakeChannel,FakeRoborockCloud,RoborockDeviceSimulator, and a V1 stateful firmware simulator (V1VacuumSimulator). - Added a new
tests/testing/test suite validating the new fakes/simulators and their interaction with the real device manager/client traits. - Modified test fixtures to (intendedly) reuse the shared
FakeChannelrather than maintaining a local copy.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
roborock/testing/__init__.py | Exposes the new testing fakes/simulators and documents intended architecture/usage. |
roborock/testing/channel.py | Adds FakeChannel transport implementation for publish/subscribe testing and simulators. |
roborock/testing/simulator.py | Adds base stateful simulator that wires fake channels to per-protocol _handle_publish logic. |
roborock/testing/v1_simulator.py | Adds a V1 vacuum firmware simulator with handlers for core RPCs and DPS push updates. |
roborock/testing/cloud.py | Adds a fake cloud orchestrator that patches HTTP + channel factories for integration-style tests. |
tests/testing/test_channel.py | New tests for FakeChannel subscribe/unsubscribe/notify/publish capturing. |
tests/testing/test_cloud.py | New tests for fake-cloud login/home/device discovery and protocol unsupported behavior. |
tests/testing/test_v1_simulator.py | New integration tests validating trait behavior via the V1 simulator. |
tests/testing/__init__.py | Adds the tests.testing package marker. |
tests/fixtures/channel_fixtures.py | Fixture file changed; currently ends up empty and needs to re-export FakeChannel (or imports updated). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Introduces a new roborock.testing package that provides stateful firmware simulators, fake transport channels, and cloud environment fakes. This allows downstream consumers (like the Home Assistant integration) to write high-fidelity integration tests using the real client library classes instead of fragile top-level mocks. New modules: - channel.py: FakeChannel in-memory transport implementing Channel protocol - simulator.py: RoborockDeviceSimulator base class - v1_simulator.py: V1VacuumSimulator with stateful command handlers - cloud.py: FakeRoborockCloud with HTTP endpoint mocking Tests split by module: - test_channel.py: FakeChannel subscribe/publish/notify - test_cloud.py: Discovery, login errors, dynamic device addition - test_v1_simulator.py: Trait refresh/reset, state transitions, push updates
…Error in base _handle_publish
Lash-L
left a comment
There was a problem hiding this comment.
Really cool stuff. minimal comments, I think the most important things will just become clear as it starts being used.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
… direct test manipulation
…it and dynamically resolve status_info fields from self.status
…ULT_PRODUCT_ID constant
…ardcoded qiCNieZa in mock_data
…te trigger_push_update
Uh oh!
There was an error while loading. Please reload this page.
Summary
Introduces a new
roborock.testingpackage that provides stateful firmware simulators, fake transport channels, and cloud environment fakes. This allows downstream consumers (like the Home Assistant integration) to write high-fidelity integration tests using the real client library classes instead of fragile top-level mocks.Motivation
Today, testing against this library requires mocking at the Python API level (patching methods, return values, etc.), which is brittle and doesn't exercise the real protocol handling, message encoding, or trait update logic. This package fakes communication at two well-defined boundaries:
aioresponsesintercepts network requests so the realRoborockApiClientexecutes fully against fake endpoints.RoborockMessagelevel. The realV1Channel, subscribers, and DPS listeners all run under test.Architecture
New Files
roborock/testing/__init__.pychannel.pyFakeChannel— in-memory transport with mock attributes for failure injection and call inspectionsimulator.pyRoborockDeviceSimulator— base class with optional local/MQTT channelsv1_simulator.pyV1VacuumSimulator— stateful V1 firmware simulator with command handlers forget_status,app_start,app_stop,set_custom_mode, consumables, DND, etc.cloud.pyFakeRoborockCloud— cloud environment orchestrator withFakeUserState,FakeWebApiClient, andpatch_device_manager()context managertests/testing/test_channel.pytest_cloud.pytest_v1_simulator.pyModified
tests/fixtures/channel_fixtures.pyFakeChannelfromroborock.testinginstead of defining it locallyUsage Example
Future Work
Migrate existing tests to use
roborock.testingAn earlier review identified which existing test suites should migrate to use these fakes vs. remain as-is:
High priority — should migrate:
tests/devices/test_device_manager.py— Currently mockscreate_v1_channelandcreate_mqtt_channelwith fragilesend_commandside-effect arrays. Usingpatch_device_manager()with aV1VacuumSimulatorwould eliminate the brittle handshake sequence mocking entirely.tests/devices/test_v1_device.py— Manually stubs subscribe, connection, and channel creation withAsyncMock. Using a realV1Channelbound toFakeChannelwould test actual client routing logic.Medium priority — optional migration:
test_status.py,test_consumable.py) — Direct mocks are fine for parsing edge cases, but integration-level tests using the simulator would complement them.Should remain unchanged:
tests/e2e/) — These verify raw protocol byte parsing, TCP framing, and cryptography at Layer 1. Our fakes operate above that layer, so these tests serve a different purpose.Additional enhancements
RoborockDeviceSimulatorsupportshas_local_channel=Falsefor MQTT-only protocols, but no A01 (Zeo/Dyad) or B01 (Q7/Q10) simulators exist yet.patch_device_manager()currently raisesNotImplementedErrorfor these.app_segment_clean), map operations, volume control, etc.