Skip to content

Commit 6f33f12

Browse files
committed
Simplify tests and add pytest hardware markers
- Replace complex mock-based tests with simple hardware tests - Add @pytest.mark.hardware to all hardware-dependent tests - Add pytest.ini and pyproject.toml configuration to skip hardware tests by default - Tests are now skipped unless explicitly run with '-m hardware'
1 parent e38364a commit 6f33f12

4 files changed

Lines changed: 31 additions & 92 deletions

File tree

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
teensytoany/_version.py export-subst
2+
# SCM syntax highlighting & preventing 3-way merges
3+
pixi.lock merge=binary linguist-language=YAML linguist-generated=true

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,8 @@ ENV/
100100

101101
# mypy
102102
.mypy_cache/
103+
# pixi environments
104+
.pixi/*
105+
!.pixi/config.toml
106+
pixi.toml
107+
pixi.lock

pytest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[pytest]
2+
markers =
3+
hardware: marks tests as requiring hardware (deselect with '-m "not hardware"')
4+
addopts = -m "not hardware"
Lines changed: 20 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,104 +1,32 @@
1-
import pytest
2-
from unittest.mock import Mock, patch, MagicMock
1+
import teensytoany
32
from teensytoany import TeensyToAny
3+
import pytest
4+
45

56

67
def test_project_import():
7-
"""Test that the package can be imported correctly."""
8-
import teensytoany
98
assert teensytoany.__version__
109
assert teensytoany.TeensyToAny
1110

1211

13-
class TestTeensyToAny:
14-
"""Test class for TeensyToAny functionality."""
15-
16-
def setup_method(self):
17-
"""Set up test fixtures."""
18-
self.mock_serial = Mock()
19-
self.mock_serial.read_until.return_value = b"0\n"
20-
self.mock_serial.timeout = 0.205
12+
@pytest.mark.hardware
13+
def test_nop():
14+
with TeensyToAny() as t:
15+
t.nop()
2116

22-
@patch('teensytoany.teensytoany.Serial')
23-
@patch('teensytoany.teensytoany.TeensyToAny.device_serial_number_pairs')
24-
def test_nop_command(self, mock_device_pairs, mock_serial_class):
25-
"""Test that the nop command works correctly."""
26-
mock_device_pairs.return_value = [('/dev/ttyACM0', '123456')]
27-
mock_serial_class.return_value = self.mock_serial
28-
29-
teensy = TeensyToAny(open=False)
30-
teensy._serial = self.mock_serial
31-
teensy._version = "0.0.1"
32-
33-
teensy.nop()
34-
35-
self.mock_serial.write.assert_called_with(b"nop\n")
36-
self.mock_serial.read_until.assert_called_once()
3717

38-
@patch('teensytoany.teensytoany.Serial')
39-
@patch('teensytoany.teensytoany.TeensyToAny.device_serial_number_pairs')
40-
def test_oversized_input_handling(self, mock_device_pairs, mock_serial_class):
41-
"""Test that oversized input (>2k bytes) is handled correctly by the firmware."""
42-
mock_device_pairs.return_value = [('/dev/ttyACM0', '123456')]
43-
mock_serial_class.return_value = self.mock_serial
44-
45-
teensy = TeensyToAny(open=False)
46-
teensy._serial = self.mock_serial
47-
teensy._version = "0.0.1"
48-
49-
# Create a command that exceeds the 2k buffer limit
50-
oversized_command = "nop " + "x" * 2500
51-
52-
# Mock the serial response to simulate ENOMEM error (12)
53-
self.mock_serial.read_until.return_value = b"12\n"
54-
55-
# The firmware should return ENOMEM (12) for oversized input
56-
with pytest.raises(RuntimeError, match="Responded with Error Code 12"):
57-
teensy._ask(oversized_command)
58-
59-
# Verify the command was written to serial
60-
self.mock_serial.write.assert_called_with((oversized_command + '\n').encode('utf-8'))
18+
@pytest.mark.hardware
19+
@pytest.mark.parametrize("i", range(256, 2048 + 1, 256))
20+
def test_nop_buffer_size(i):
21+
# We shouldn't fail with up to 2048 bytes of input
22+
with TeensyToAny() as t:
23+
t._ask("nop" + " " * (2048 - i - len("nop\n")))
6124

62-
@patch('teensytoany.teensytoany.Serial')
63-
@patch('teensytoany.teensytoany.TeensyToAny.device_serial_number_pairs')
64-
def test_normal_command_works(self, mock_device_pairs, mock_serial_class):
65-
"""Test that normal commands work correctly."""
66-
mock_device_pairs.return_value = [('/dev/ttyACM0', '123456')]
67-
mock_serial_class.return_value = self.mock_serial
68-
69-
teensy = TeensyToAny(open=False)
70-
teensy._serial = self.mock_serial
71-
teensy._version = "0.0.1"
72-
73-
# Mock successful response
74-
self.mock_serial.read_until.return_value = b"0\n"
75-
76-
result = teensy._ask("nop")
77-
assert result is None
78-
79-
self.mock_serial.write.assert_called_with(b"nop\n")
8025

81-
@patch('teensytoany.teensytoany.Serial')
82-
@patch('teensytoany.teensytoany.TeensyToAny.device_serial_number_pairs')
83-
def test_buffer_size_limits(self, mock_device_pairs, mock_serial_class):
84-
"""Test that commands near the buffer limit are handled correctly."""
85-
mock_device_pairs.return_value = [('/dev/ttyACM0', '123456')]
86-
mock_serial_class.return_value = self.mock_serial
87-
88-
teensy = TeensyToAny(open=False)
89-
teensy._serial = self.mock_serial
90-
teensy._version = "0.0.1"
91-
92-
# Test with command just under the limit (2048 bytes - some overhead)
93-
large_command = "nop " + "x" * 2000
94-
self.mock_serial.read_until.return_value = b"0\n"
95-
96-
result = teensy._ask(large_command)
97-
assert result is None
98-
99-
# Test with command at the limit
100-
limit_command = "nop " + "x" * 2040
101-
self.mock_serial.read_until.return_value = b"0\n"
102-
103-
result = teensy._ask(limit_command)
104-
assert result is None
26+
@pytest.mark.hardware
27+
@pytest.mark.parametrize("i", range(2048, 8096 + 1, 2048))
28+
def test_nop_buffer_size_fail(i):
29+
with TeensyToAny() as t:
30+
# We should fail with more than 2048 bytes of input
31+
with pytest.raises(Exception):
32+
t._ask("nop" + " " * (i + 1 - len("nop\n")))

0 commit comments

Comments
 (0)