Skip to content

Commit

Permalink
Make tests pass for refactored classes
Browse files Browse the repository at this point in the history
  • Loading branch information
sabidhasan committed Aug 15, 2019
1 parent cf654ba commit 6663e8d
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 117 deletions.
7 changes: 7 additions & 0 deletions test/test_BaseEngine.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
set_environ("TESTING")
import hardware.engine_base


def mock_gpio_input(RPi_pin_number):
""" The mock input function randomly decides when it has it an object in front of it """
return random.random() > 0.9


def mock_gpio_infinite(RPi_pin_number):
""" This RPi will never report the echo coming back, so should time out """
return 0
Expand All @@ -33,15 +35,18 @@ class BaseEngineTests(unittest.TestCase):
def setUp(self):
self.engine = MockEngine(1000)


# Raises error when directly instantiated
def test_raises_not_implemented_error(self):
self.assertRaises(NotImplementedError, hardware.engine_base.BaseEngine, 0)


# Defines an ultrasonic sensor timeout
def test_us_timeout(self):
# self.engine = MockEngine(1000)
self.assertEqual(self.engine.ultra_sonic_sensor_timeout, 1000)


# When _engine_instantated is True, it doesn't reinitialize the engine
def test_engine_initializes_once(self):
mock_engine = MagicMock()
Expand All @@ -50,6 +55,7 @@ def test_engine_initializes_once(self):
MockEngine(1000)
self.assertEqual(len(mock_engine.mock_calls), 0)


# Ultrasonic distance reading returns a distance
@patch('hardware.engine_base.GPIO.input', side_effect=mock_gpio_input)
def test_get_us_distance(self, mock_gpio):
Expand All @@ -58,6 +64,7 @@ def test_get_us_distance(self, mock_gpio):
self.assertLess(reported_distance, math.inf,
'reported distance is not non-infinite or non-float, when object present')


# An infinite distance measurement times out and returns infinity
@patch('hardware.engine_base.GPIO.input', side_effect=mock_gpio_infinite)
def test_long_us_distance(self, mock_gpio):
Expand Down
4 changes: 4 additions & 0 deletions test/test_Camera.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@ class CameraTests(unittest.TestCase):
def tearDown(self):
Camera.camera = None


def test_frame(self):
camera = Camera()
self.assertEqual(camera.frame, None, 'frame is defined before data acquired')


# Invalid resolution raises error
def test_invalid_resolution(self):
self.assertRaises(ValueError, Camera, width = 22, height = 22)


# Test resolution
def test_resolution(self):
camera = Camera(width=999, height=999)
self.assertEqual(camera.width, 999)
self.assertEqual(camera.height, 999)

116 changes: 0 additions & 116 deletions test/test_Engine.py

This file was deleted.

12 changes: 11 additions & 1 deletion test/test_ImageData.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def setUp(self):
raw_camera_data = get_mocked_camera_input()
self.image = ImageData(raw_camera_data)


def tearDown(self):
for filename in ['test/test_images/test_color.jpg', 'test/test_images/test_desaturated.jpg']:
try:
Expand All @@ -22,15 +23,18 @@ def tearDown(self):
# Test must have failed, so no file was created
continue


# Test width and height attributes
def test_height(self):
self.assertEqual(self.image.height, 256,
'height does not equal expected value')


def test_width(self):
self.assertEqual(self.image.width, 256,
'width does not equal expected value')


def test_save_to_disk(self):
with open('test/test_images/image_banana_color.jpg', 'rb') as f:
expected_color_image = f.read()
Expand All @@ -40,6 +44,7 @@ def test_save_to_disk(self):
self.assertEqual(expected_color_image, actual_color_image,
'saved image does not match expected image')


def test_desaturate(self):
with open('test/test_images/image_banana_bw.jpg', 'rb') as f:
expected_bw_image = f.read()
Expand All @@ -49,13 +54,15 @@ def test_desaturate(self):
self.assertEqual(expected_bw_image, actual_bw_image,
'after desaturation, the image does not match expected value')


def test_base64(self):
with open('test/test_images/image_banana_b64.bin', 'rb') as f:
expected_b64 = f.read()
actual_b64 = self.image.tobase64()
self.assertEqual(actual_b64, expected_b64,
'base 64 string does not equal expected string')


def test_suggested_histogram_luminosity(self):
# Suggests correct histogram luminosity (based on bottom half of the image)
mocked_camera_input = get_mocked_camera_input()
Expand All @@ -69,14 +76,17 @@ def test_suggested_histogram_luminosity(self):
self.assertEqual(expected_luminosity, actual_luminosity,
'expected luminosity does not equal calculated luminosity')


def test_histogram_with_format(self):
# Throws error when unexpected format passed
self.assertRaises(TypeError, self.image.histogram, format='jpeg')



def test_histogram_with_lumin(self):
# Throws error when unexpected luminescence_threshold is invalid
self.assertRaises(ValueError, self.image.histogram, luminescence_threshold=1.1)


def test_histogram(self):
# Tests if produced histogram matches expected value
LUMINESCENCE_THRESHOLD = 0.5
Expand Down
51 changes: 51 additions & 0 deletions test/test_SelfDrivingEngine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import unittest
from unittest.mock import Mock, MagicMock, call, patch
from helpers.os import set_environ
from helpers.testing_tools import measure_time_for_fn, percent_error, \
get_activated_pin_ids_from_calls, get_all_pin_ids_from_calls

# Set testing environment so Engine imports fake RPi modules
set_environ("TESTING")
import hardware.engine_self_driving


class SelfDrivingEngineTests(unittest.TestCase):
@patch('hardware.engine_self_driving.GPIO.PWM')
def setUp(self, mock_gpio):
self.engine = hardware.engine_self_driving.SelfDrivingEngine()


@patch('hardware.engine_self_driving.GPIO.output')
def test_turn_wheels_left(self, mock_gpio):
self.engine.turn_wheels_left()
actual_activated_pins = get_activated_pin_ids_from_calls(mock_gpio.call_args_list)
self.assertTrue(11 in actual_activated_pins, 'Pin 11 was not activated, as expected')


@patch('hardware.engine_self_driving.GPIO.output')
def test_turn_wheels_right(self, mock_gpio):
self.engine.turn_wheels_right()
actual_activated_pins = get_activated_pin_ids_from_calls(mock_gpio.call_args_list)
self.assertTrue(7 in actual_activated_pins, 'Pin 7 was not activated')


@patch('hardware.engine_self_driving.GPIO.output')
def test_turn_wheels_forward(self, mock_gpio):
expected_calls = [call(11, False), call(7, False)]
self.engine.turn_wheels_forward()

all_called = [call in mock_gpio.call_args_list for call in expected_calls]
self.assertTrue(all_called, 'All expected calls were not called')


def test_start_continuous_move(self):
expected_duty_cycle = 30
self.engine.start_continuous_move()
first_call = self.engine.pwm.start.call_args_list[0][0][0]
self.assertEqual(first_call, expected_duty_cycle, 'Expected duty cycle not used for PWM')


def test_stop_all_motion(self):
self.engine.stop_all_motion()
call_count = len(self.engine.pwm.stop.call_args_list)
self.assertEqual(call_count, 1)

0 comments on commit 6663e8d

Please sign in to comment.