From 9107081220bc88ce1e404421e50065c538c1c742 Mon Sep 17 00:00:00 2001 From: "Andriy Kushnir (Orhideous)" Date: Thu, 22 Feb 2024 18:50:27 +0200 Subject: [PATCH] Restructure tests and remove remnants of old unittest --- tests/abstract_test_roomba.py | 46 -------------------- tests/conftest.py | 47 +++++++++++++++++++++ tests/test_discovery.py | 19 +++------ tests/test_roomba.py | 72 +++++++++++++++----------------- tests/test_roomba_integration.py | 60 ++++++++++++-------------- 5 files changed, 112 insertions(+), 132 deletions(-) delete mode 100644 tests/abstract_test_roomba.py create mode 100644 tests/conftest.py diff --git a/tests/abstract_test_roomba.py b/tests/abstract_test_roomba.py deleted file mode 100644 index 47ee929..0000000 --- a/tests/abstract_test_roomba.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Abstract test class for Roomba.""" -from roombapy import Roomba, RoombaFactory - -ROOMBA_CONFIG = { - "host": "127.0.0.1", - "username": "test", - "password": "test", - "name": "Roomba", - "continuous": True, - "delay": 120, -} - - -class AbstractTestRoomba: - """Abstract test class for Roomba.""" - - @staticmethod - def get_default_roomba( - address=ROOMBA_CONFIG["host"], - blid=ROOMBA_CONFIG["username"], - password=ROOMBA_CONFIG["password"], - continuous=ROOMBA_CONFIG["continuous"], - delay=ROOMBA_CONFIG["delay"], - ) -> Roomba: - """Get a default Roomba.""" - return RoombaFactory.create_roomba( - address=address, - blid=blid, - password=password, - continuous=continuous, - delay=delay, - ) - - @staticmethod - def get_message(topic, payload): - """Get a message.""" - - class Message: - pass - - message = Message - message.topic = topic - message.payload = payload - message.qos = "qos" - - return message diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..23a254f --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,47 @@ +"""Tools and fixtures for tests.""" +from dataclasses import dataclass + +import pytest +from roombapy import Roomba, RoombaFactory + +ROOMBA_CONFIG = { + "host": "127.0.0.1", + "username": "test", + "password": "test", + "name": "Roomba", + "continuous": True, + "delay": 120, +} + + +@dataclass +class Message: + """MQTT-like message.""" + + topic: str + payload: bytes + qos: str = "qos" + + +@pytest.fixture() +def roomba() -> Roomba: + """Mock for robot.""" + return RoombaFactory.create_roomba( + address=ROOMBA_CONFIG["host"], + blid=ROOMBA_CONFIG["username"], + password=ROOMBA_CONFIG["password"], + continuous=ROOMBA_CONFIG["continuous"], + delay=ROOMBA_CONFIG["delay"], + ) + + +@pytest.fixture() +def broken_roomba(): + """Mock for robot with broken credentials.""" + return RoombaFactory.create_roomba( + address=ROOMBA_CONFIG["host"], + blid="wrong", + password=ROOMBA_CONFIG["password"], + continuous=ROOMBA_CONFIG["continuous"], + delay=ROOMBA_CONFIG["delay"], + ) diff --git a/tests/test_discovery.py b/tests/test_discovery.py index 3edac37..e6316a4 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -2,17 +2,10 @@ from roombapy.discovery import RoombaDiscovery -class TestDiscovery: - """Test the discovery module.""" +def test_discovery_with_wrong_msg() -> None: + """Test discovery with wrong message.""" + discovery = RoombaDiscovery() + discovery.roomba_message = "test" + response = discovery.find() - def test_discovery_with_wrong_msg(self): - """Test discovery with wrong message.""" - # given - discovery = RoombaDiscovery() - - # when - discovery.roomba_message = "test" - response = discovery.find() - - # then - assert not response + assert not response diff --git a/tests/test_roomba.py b/tests/test_roomba.py index 332d8a2..73aa33b 100644 --- a/tests/test_roomba.py +++ b/tests/test_roomba.py @@ -1,45 +1,39 @@ """Test the Roomba class.""" -from tests import abstract_test_roomba +from roombapy import Roomba +from tests.conftest import Message -class TestRoomba(abstract_test_roomba.AbstractTestRoomba): - """Test the Roomba class.""" - def test_roomba_with_data(self): - """Test Roomba with data.""" - # given - roomba = self.get_default_roomba() +def test_roomba_with_data(roomba: Roomba) -> None: + """Test Roomba with data.""" + roomba.on_message( + None, + None, + Message( + "topic", + b'{"state":{"reported":{"cleanSchedule":{"cycle":["none",' + b'"none","none","none","none","none","none"],"h":' + b'[9,11,11,11,11,11,9],"m":[0,0,0,0,0,0,0]},"language":0' + b',"cleanMissionStatus":{"cycle":"none","phase":"charge",' + b'"expireM":0,"rechrgM":0,"error":0,"notReady":0,"mssnM":108' + b',"sqft":0,"initiator":"","nMssn":209},"dock":{"known":true}' + b',"bin":{"present":true,"full":false},"batteryType":"lith",' + b'"batPct":100,"mobilityVer":"7375","bootloaderVer":"36",' + b'"soundVer":"13"}}}', + ), + ) + roomba.on_message( + None, + None, + Message( + "topic", + b'{"state":{"reported":{"signal":{"rssi":-38,"snr":52}}}}', + ), + ) - # when - roomba.on_message( - None, - None, - TestRoomba.get_message( - "topic", - b'{"state":{"reported":{"cleanSchedule":{"cycle":["none",' - b'"none","none","none","none","none","none"],"h":' - b'[9,11,11,11,11,11,9],"m":[0,0,0,0,0,0,0]},"language":0' - b',"cleanMissionStatus":{"cycle":"none","phase":"charge",' - b'"expireM":0,"rechrgM":0,"error":0,"notReady":0,"mssnM":108' - b',"sqft":0,"initiator":"","nMssn":209},"dock":{"known":true}' - b',"bin":{"present":true,"full":false},"batteryType":"lith",' - b'"batPct":100,"mobilityVer":"7375","bootloaderVer":"36",' - b'"soundVer":"13"}}}', - ), - ) - roomba.on_message( - None, - None, - TestRoomba.get_message( - "topic", - b'{"state":{"reported":{"signal":{"rssi":-38,"snr":52}}}}', - ), - ) + state = roomba.master_state - # then - state = roomba.master_state - - assert state - assert state["state"]["reported"]["bin"]["present"] - assert not state["state"]["reported"]["bin"]["full"] - assert state["state"]["reported"]["batPct"] == 100 + assert state + assert state["state"]["reported"]["bin"]["present"] + assert not state["state"]["reported"]["bin"]["full"] + assert state["state"]["reported"]["batPct"] == 100 diff --git a/tests/test_roomba_integration.py b/tests/test_roomba_integration.py index 977e7d1..984771c 100644 --- a/tests/test_roomba_integration.py +++ b/tests/test_roomba_integration.py @@ -1,45 +1,37 @@ -"""Test Roomba integration with the real device.""" +"""Test Roomba integration with the mocked device.""" import asyncio +from asyncio import BaseEventLoop import pytest +from roombapy import Roomba -from tests import abstract_test_roomba +@pytest.mark.asyncio() +async def test_roomba_connect( + roomba: Roomba, event_loop: BaseEventLoop +) -> None: + """Connect to the Roomba.""" + is_connected = await roomba_connect(roomba, event_loop) + await roomba_disconnect(roomba, event_loop) + assert is_connected -class TestRoombaIntegration(abstract_test_roomba.AbstractTestRoomba): - """Test Roomba integration with the real device.""" - @pytest.mark.asyncio() - async def test_roomba_connect(self, event_loop): - """Test Roomba connect.""" - # given - roomba = self.get_default_roomba() +@pytest.mark.asyncio() +async def test_roomba_connect_error( + broken_roomba: Roomba, event_loop: BaseEventLoop +) -> None: + """Test Roomba connect error.""" + is_connected = await roomba_connect(broken_roomba, event_loop) + assert not is_connected - # when - is_connected = await self.roomba_connect(roomba, event_loop) - await self.roomba_disconnect(roomba, event_loop) - # then - assert is_connected +async def roomba_connect(robot: Roomba, loop: BaseEventLoop) -> None: + """Connect to the Roomba.""" + await loop.run_in_executor(None, robot.connect) + await asyncio.sleep(1) + return robot.roomba_connected - @pytest.mark.asyncio() - async def test_roomba_connect_error(self, event_loop): - """Test Roomba connect error.""" - # given - roomba = self.get_default_roomba(blid="wrong") - # when - is_connected = await self.roomba_connect(roomba, event_loop) - - # then - assert not is_connected - - async def roomba_connect(self, roomba, loop): - """Connect to the Roomba.""" - await loop.run_in_executor(None, roomba.connect) - await asyncio.sleep(1) - return roomba.roomba_connected - - async def roomba_disconnect(self, roomba, loop): - """Disconnect from the Roomba.""" - await loop.run_in_executor(None, roomba.disconnect) +async def roomba_disconnect(robot: Roomba, loop: BaseEventLoop) -> None: + """Disconnect from the Roomba.""" + await loop.run_in_executor(None, robot.disconnect)