Skip to content

Commit fad94f6

Browse files
committed
Split out the arduino pin tests into separate tests
1 parent c537db5 commit fad94f6

File tree

2 files changed

+112
-54
lines changed

2 files changed

+112
-54
lines changed

tests/conftest.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ def query(self, request: str) -> str:
6565
"""
6666
# Assert that we have not run out of responses
6767
# and that the request is the next one we expect
68-
assert self.request_index < len(self.responses)
68+
if self.request_index >= len(self.responses):
69+
raise AssertionError(f"Unexpected request: {request}")
6970
assert request == self.responses[self.request_index][0]
7071

7172
# Fetch the response and increment the request index

tests/test_arduino.py

Lines changed: 110 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -84,83 +84,140 @@ def test_arduino_ultrasound(arduino_serial: MockArduino) -> None:
8484
arduino.ultrasound_measure(25, 2)
8585

8686

87-
def test_arduino_pins(arduino_serial: MockArduino) -> None:
88-
"""
89-
Test the arduino pins properties and methods.
90-
91-
This test uses the mock serial wrapper to simulate the arduino.
92-
"""
87+
@pytest.mark.parametrize("pin,expected,command,response", [
88+
(2, GPIOPinMode.OUTPUT, "PIN:2:MODE:GET?", "OUTPUT"),
89+
(10, GPIOPinMode.INPUT_PULLUP, "PIN:10:MODE:GET?", "INPUT_PULLUP"),
90+
(AnalogPins.A0, GPIOPinMode.INPUT, "PIN:14:MODE:GET?", "INPUT"),
91+
])
92+
def test_arduino_get_pin_mode(
93+
arduino_serial: MockArduino,
94+
pin: int,
95+
expected: GPIOPinMode,
96+
command: str,
97+
response: str,
98+
) -> None:
9399
arduino = arduino_serial.arduino_board
94100
arduino_serial.serial_wrapper._add_responses([
95-
("PIN:2:MODE:GET?", "OUTPUT"),
96-
("PIN:10:MODE:GET?", "INPUT_PULLUP"),
97-
("PIN:14:MODE:GET?", "INPUT"),
98-
("PIN:2:MODE:SET:OUTPUT", "ACK"),
99-
("PIN:10:MODE:SET:INPUT_PULLUP", "ACK"),
100-
("PIN:14:MODE:SET:INPUT", "ACK"),
101-
# PIN:<n>:ANALOG:GET?
101+
(command, response),
102102
])
103103

104-
# Test that we can get the mode of a pin
105-
assert arduino.pins[2].mode == GPIOPinMode.OUTPUT
106-
assert arduino.pins[10].mode == GPIOPinMode.INPUT_PULLUP
107-
assert arduino.pins[AnalogPins.A0].mode == GPIOPinMode.INPUT
104+
assert arduino.pins[pin].mode == expected
105+
106+
107+
def test_arduino_set_invalid_pin_mode(arduino_serial: MockArduino) -> None:
108+
arduino = arduino_serial.arduino_board
108109

109110
with pytest.raises(IOError):
110111
arduino.pins[2].mode = 1
111112

112-
# Test that we can set the mode of a pin
113-
arduino.pins[2].mode = GPIOPinMode.OUTPUT
114-
arduino.pins[10].mode = GPIOPinMode.INPUT_PULLUP
115-
arduino.pins[AnalogPins.A0].mode = GPIOPinMode.INPUT
116113

117-
# Test that we can get the digital value of a pin
114+
@pytest.mark.parametrize("pin,mode,command,response", [
115+
(2, GPIOPinMode.OUTPUT, "PIN:2:MODE:SET:OUTPUT", "ACK"),
116+
(10, GPIOPinMode.INPUT_PULLUP, "PIN:10:MODE:SET:INPUT_PULLUP", "ACK"),
117+
(AnalogPins.A0, GPIOPinMode.INPUT, "PIN:14:MODE:SET:INPUT", "ACK"),
118+
])
119+
def test_arduino_set_pin_mode(
120+
arduino_serial: MockArduino,
121+
pin: int,
122+
mode: GPIOPinMode,
123+
command: str,
124+
response: str,
125+
) -> None:
126+
arduino = arduino_serial.arduino_board
118127
arduino_serial.serial_wrapper._add_responses([
119-
("PIN:2:MODE:GET?", "OUTPUT"), # mode is read before digital value
120-
("PIN:2:DIGITAL:GET?", "1"),
121-
("PIN:10:MODE:GET?", "INPUT_PULLUP"),
122-
("PIN:10:DIGITAL:GET?", "0"),
123-
("PIN:14:MODE:GET?", "INPUT"),
124-
("PIN:14:DIGITAL:GET?", "1"),
128+
(command, response),
125129
])
126-
assert arduino.pins[2].digital_value is True
127-
assert arduino.pins[10].digital_value is False
128-
assert arduino.pins[AnalogPins.A0].digital_value is True
129130

130-
# Test that we can set the digital value of a pin
131+
arduino.pins[pin].mode = mode
132+
133+
134+
@pytest.mark.parametrize("pin,expected,command,response,mode_command,mode_response", [
135+
(2, True, "PIN:2:DIGITAL:GET?", "1", "PIN:2:MODE:GET?", "OUTPUT"),
136+
(10, False, "PIN:10:DIGITAL:GET?", "0", "PIN:10:MODE:GET?", "INPUT_PULLUP"),
137+
(AnalogPins.A0, True, "PIN:14:DIGITAL:GET?", "1", "PIN:14:MODE:GET?", "INPUT"),
138+
])
139+
def test_arduino_get_digital_value(
140+
arduino_serial: MockArduino,
141+
pin: int,
142+
expected: bool,
143+
command: str,
144+
response: str,
145+
mode_command: str,
146+
mode_response: str,
147+
) -> None:
148+
arduino = arduino_serial.arduino_board
131149
arduino_serial.serial_wrapper._add_responses([
132-
("PIN:2:MODE:GET?", "OUTPUT"), # mode is read before digital value
133-
("PIN:2:DIGITAL:SET:1", "ACK"),
134-
("PIN:2:MODE:GET?", "OUTPUT"),
135-
("PIN:2:DIGITAL:SET:0", "ACK"),
136-
("PIN:10:MODE:GET?", "INPUT_PULLUP"),
137-
("PIN:10:MODE:GET?", "INPUT_PULLUP"),
138-
("PIN:14:MODE:GET?", "INPUT"),
139-
("PIN:14:MODE:GET?", "INPUT"),
150+
(mode_command, mode_response),
151+
(command, response),
140152
])
141-
arduino.pins[2].digital_value = True
142-
arduino.pins[2].digital_value = False
143-
with pytest.raises(IOError, match=r"Digital write is not supported.*"):
144-
arduino.pins[10].digital_value = False
153+
154+
assert arduino.pins[pin].digital_value == expected
155+
156+
157+
@pytest.mark.parametrize("pin,value,command,response,mode_command,mode_response", [
158+
(2, True, "PIN:2:DIGITAL:SET:1", "ACK", "PIN:2:MODE:GET?", "OUTPUT"),
159+
(2, False, "PIN:2:DIGITAL:SET:0", "ACK", "PIN:2:MODE:GET?", "OUTPUT"),
160+
])
161+
def test_arduino_set_digital_value(
162+
arduino_serial: MockArduino,
163+
pin: int,
164+
value: bool,
165+
command: str,
166+
response: str,
167+
mode_command: str,
168+
mode_response: str,
169+
) -> None:
170+
arduino = arduino_serial.arduino_board
171+
arduino_serial.serial_wrapper._add_responses([
172+
(mode_command, mode_response),
173+
(command, response),
174+
])
175+
176+
arduino.pins[pin].digital_value = value
177+
178+
179+
@pytest.mark.parametrize("pin,mode_command,mode_response", [
180+
(10, "PIN:10:MODE:GET?", "INPUT_PULLUP"),
181+
(AnalogPins.A0, "PIN:14:MODE:GET?", "INPUT"),
182+
])
183+
def test_arduino_set_invalid_digital_value(
184+
arduino_serial: MockArduino,
185+
pin: int,
186+
mode_command: str,
187+
mode_response: str,
188+
) -> None:
189+
arduino = arduino_serial.arduino_board
190+
arduino_serial.serial_wrapper._add_responses([
191+
(mode_command, mode_response),
192+
(mode_command, mode_response),
193+
])
194+
145195
with pytest.raises(IOError, match=r"Digital write is not supported.*"):
146-
arduino.pins[AnalogPins.A0].digital_value = True
196+
arduino.pins[pin].digital_value = False
197+
147198

148-
# Test that we can get the analog value of a pin
199+
def test_arduino_get_analog_value(arduino_serial: MockArduino) -> None:
200+
arduino = arduino_serial.arduino_board
149201
arduino_serial.serial_wrapper._add_responses([
150-
("PIN:2:MODE:GET?", "OUTPUT"), # mode is read before analog value
151-
("PIN:2:MODE:GET?", "OUTPUT"),
152-
("PIN:10:MODE:GET?", "INPUT"),
153202
("PIN:14:MODE:GET?", "INPUT"),
154203
("PIN:14:ANALOG:GET?", "1000"),
155204
])
156-
with pytest.raises(IOError, match=r"Analog read is not supported.*"):
157-
arduino.pins[2].analog_value
158-
with pytest.raises(IOError, match=r"Pin does not support analog read"):
159-
arduino.pins[10].analog_value
205+
160206
# 4.888 = round((5 / 1023) * 1000, 3)
161207
assert arduino.pins[AnalogPins.A0].analog_value == 4.888
162208

163209

210+
def test_arduino_get_invalid_analog_value_from_digital_only_pin(arduino_serial: MockArduino) -> None:
211+
arduino = arduino_serial.arduino_board
212+
arduino_serial.serial_wrapper._add_responses([
213+
("PIN:2:MODE:GET?", "OUTPUT"),
214+
("PIN:2:MODE:GET?", "OUTPUT"),
215+
])
216+
217+
with pytest.raises(IOError, match=r".*not support.*"):
218+
arduino.pins[2].analog_value
219+
220+
164221
def test_invalid_properties(arduino_serial: MockArduino) -> None:
165222
"""
166223
Test that settng invalid properties raise an AttributeError.

0 commit comments

Comments
 (0)