Merge pull request #10 from pimoroni/improve-tests

Improve test quality and coverage
This commit is contained in:
Philip Howard
2020-03-20 12:08:38 +00:00
committed by GitHub
6 changed files with 133 additions and 21 deletions

38
library/tests/conftest.py Normal file
View File

@@ -0,0 +1,38 @@
"""Test configuration.
These allow the mocking of various Python modules
that might otherwise have runtime side-effects.
"""
import sys
import mock
import pytest
@pytest.fixture(scope='function', autouse=False)
def GPIO():
"""Mock RPi.GPIO module."""
GPIO = mock.MagicMock()
# Fudge for Python < 37 (possibly earlier)
sys.modules['RPi'] = mock.Mock()
sys.modules['RPi'].GPIO = GPIO
sys.modules['RPi.GPIO'] = GPIO
yield GPIO
del sys.modules['RPi']
del sys.modules['RPi.GPIO']
@pytest.fixture(scope='function', autouse=False)
def spidev():
"""Mock spidev module."""
spidev = mock.MagicMock()
sys.modules['spidev'] = spidev
yield spidev
del sys.modules['spidev']
@pytest.fixture(scope='function', autouse=False)
def numpy():
"""Mock numpy module."""
numpy = mock.MagicMock()
sys.modules['numpy'] = numpy
yield numpy
del sys.modules['numpy']

View File

@@ -1,24 +1,16 @@
import sys from tools import force_reimport
import mock
def _mock(): def test_128_64_0(GPIO, spidev, numpy):
sys.modules['numpy'] = mock.Mock() force_reimport('ST7735')
sys.modules['spidev'] = mock.Mock()
sys.modules['RPi'] = mock.Mock()
sys.modules['RPi.GPIO'] = mock.Mock()
def test_128_64_0():
_mock()
import ST7735 import ST7735
display = ST7735.ST7735(port=0, cs=0, dc=24, width=128, height=64, rotation=0) display = ST7735.ST7735(port=0, cs=0, dc=24, width=128, height=64, rotation=0)
assert display.width == 128 assert display.width == 128
assert display.height == 64 assert display.height == 64
def test_128_64_90(): def test_128_64_90(GPIO, spidev, numpy):
_mock() force_reimport('ST7735')
import ST7735 import ST7735
display = ST7735.ST7735(port=0, cs=0, dc=24, width=128, height=64, rotation=90) display = ST7735.ST7735(port=0, cs=0, dc=24, width=128, height=64, rotation=90)
assert display.width == 64 assert display.width == 64

View File

@@ -0,0 +1,25 @@
import mock
from tools import force_reimport
def test_display(GPIO, spidev, numpy):
force_reimport('ST7735')
import ST7735
display = ST7735.ST7735(port=0, cs=0, dc=24)
numpy.dstack().flatten().tolist.return_value = [0xff, 0x00, 0xff, 0x00]
display.display(mock.MagicMock())
spidev.SpiDev().xfer3.assert_called_with([0xff, 0x00, 0xff, 0x00])
def test_color565(GPIO, spidev, numpy):
force_reimport('ST7735')
import ST7735
assert ST7735.color565(255, 255, 255) == 0xFFFF
def test_image_to_data(GPIO, spidev, numpy):
force_reimport('ST7735')
numpy.dstack().flatten().tolist.return_value = []
import ST7735
assert ST7735.image_to_data(mock.MagicMock()) == []

View File

@@ -1,13 +1,47 @@
import sys
import mock import mock
from tools import force_reimport
def test_setup(): def test_setup(GPIO, spidev, numpy):
sys.modules['numpy'] = mock.Mock() force_reimport('ST7735')
sys.modules['spidev'] = mock.Mock()
sys.modules['RPi'] = mock.Mock()
sys.modules['RPi.GPIO'] = mock.Mock()
import ST7735 import ST7735
display = ST7735.ST7735(port=0, cs=0, dc=24) display = ST7735.ST7735(port=0, cs=0, dc=24)
del display del display
GPIO.output.assert_has_calls([
mock.call(24, True),
mock.call(24, False)
], any_order=True)
def test_setup_no_invert(GPIO, spidev, numpy):
force_reimport('ST7735')
import ST7735
display = ST7735.ST7735(port=0, cs=0, dc=24, invert=False)
del display
def test_setup_with_backlight(GPIO, spidev, numpy):
force_reimport('ST7735')
import ST7735
display = ST7735.ST7735(port=0, cs=0, dc=24, backlight=4)
GPIO.setup.assert_called_with(4, GPIO.OUT)
display.set_backlight(GPIO.HIGH)
GPIO.output.assert_has_calls([
mock.call(4, GPIO.LOW),
mock.call(4, GPIO.HIGH),
# Dozens of falls with True/False here
# due to _init() being called and the display
# setup setting the command/data pin
mock.call(4, GPIO.HIGH)
], any_order=True)
def test_setup_with_reset(GPIO, spidev, numpy):
force_reimport('ST7735')
import ST7735
display = ST7735.ST7735(port=0, cs=0, dc=24, rst=4)
GPIO.setup.assert_called_with(4, GPIO.OUT)
del display

23
library/tests/tools.py Normal file
View File

@@ -0,0 +1,23 @@
import sys
def force_reimport(module):
"""Force the module under test to be re-imported.
Because pytest runs all tests within the same scope (this makes me cry)
we have to do some manual housekeeping to avoid tests polluting each other.
Since conftest.py already does some sys.modules mangling I see no reason not to
do the same thing here.
"""
if "." in module:
steps = module.split(".")
else:
steps = [module]
for i in range(len(steps)):
module = ".".join(steps[0:i + 1])
try:
del sys.modules[module]
except KeyError:
pass

View File

@@ -1,5 +1,5 @@
[tox] [tox]
envlist = py{27,35},qa envlist = py{27,35,37},qa
skip_missing_interpreters = True skip_missing_interpreters = True
[testenv] [testenv]