Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 129 additions & 69 deletions exercises/concept/ellens-alien-game/classes_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,73 +3,111 @@


try:
from classes import new_aliens_collection
except ImportError as err:
raise ImportError("We tried to import the new_aliens_collection() function, "
"but could not find it. Did you remember to create it?") from err
from classes import Alien
except ImportError as import_fail:
# pylint: disable=raise-missing-from
raise ImportError("\n\nMISSING CLASS --> We tried to import the 'Alien' class from "
"your classes.py file, but could not find it."
"Did you misname or forget to create it?") from None

try:
from classes import Alien
from classes import new_aliens_collection
except ImportError as err:
raise ImportError("We tried to import the 'Alien' class from the classes.py file, but could not find it. "
"Did you remember to create it?") from err
raise ImportError("\n\nMISSING FUNCTION --> We tried to import the "
"new_aliens_collection() function "
"from your classes.py file, but could not find it. "
"Did you misname or forget to create it?") from None


class ClassesTest(unittest.TestCase):
# Test Alien class exists and correctly initialised.

@pytest.mark.task(taskno=1)
def test_alien_has_correct_initial_coordinates(self):
"""Test thst the Alien class gets correctly initialised."""

alien = Alien(2, -1)
error = ("Expected object to be at position (2, -1) but instead "
f"found it initialized to position {(alien.x_coordinate, alien.y_coordinate)}.")
error_message = (f'Created a new Alien by calling Alien(2, -1). '
f'The Alien was initialized to position '
f'{(alien.x_coordinate, alien.y_coordinate)}, but the tests expected '
f'the object to be at position (2, -1)')

self.assertEqual((2, -1), (alien.x_coordinate, alien.y_coordinate), msg=error)
self.assertEqual((2, -1), (alien.x_coordinate, alien.y_coordinate), msg=error_message)

@pytest.mark.task(taskno=1)
def test_alien_has_health(self):
alien = Alien(0, 0)
error = ("Expected object's health to be 3 but instead found "
f"it had a health of {alien.health}.")
error_message = (f'Created a new Alien by calling Alien(0, 0). '
f'The new Alien has a health of {alien.health}, '
f'but the tests expect health = 3')

self.assertEqual(3, alien.health, msg=error)
self.assertEqual(3, alien.health, msg=error_message)

# Test instance variables are unique to specific instances.
@pytest.mark.task(taskno=1)
def test_alien_instance_variables(self):
"""Test instance variables are unique to specific instances."""

alien_one = Alien(-8, -1)
alien_two = Alien(2, 5)

coord_x_error = ("Expected alien_one and alien_two to have different x "
f"positions. Instead both x's were: {alien_two.x_coordinate}.")
coord_y_error = ("Expected alien_one and alien_two to have different y "
f"positions. Instead both y's were: {alien_two.y_coordinate}.")
coord_x_error = (f'Created two new Aliens by assigning '
f'alien_one = Alien(-8, -1) and alien_two = Alien(2, 5). '
f'Both Aliens x coordinates were {alien_two.x_coordinate}, '
f'but the tests expect alien_one and alien_two to have '
f'different x positions.')

coord_y_error = (f'Created two new Aliens by assigning '
f'alien_one = Alien(-8, -1) and alien_two = Alien(2, 5). '
f'Both Aliens y coordinates were {alien_two.y_coordinate}, '
f'but the tests expect alien_one and alien_two to have '
f'different y positions.')

self.assertFalse(alien_one.x_coordinate == alien_two.x_coordinate, msg=coord_x_error)
self.assertFalse(alien_one.y_coordinate == alien_two.y_coordinate, msg=coord_y_error)

# Test class methods work as specified.

@pytest.mark.task(taskno=2)
def test_alien_hit_method(self):
#There are two valid interpretations for this method/task.
#`self.health -= 1` and `self.health = max(0, self.health - 1)`
#The tests for this task reflect this ambiguity.
"""Test class methods work as specified.

There are two valid interpretations for this method/task.
`self.health -= 1` and `self.health = max(0, self.health - 1)`
The tests for this task reflect this ambiguity.

data = [(1, (2,)), (2, (1,)), (3, (0,)), (4, (0, -1)), (5, (0, -2)), (6, (0, -3))]
for variant, (iterations, result) in enumerate(data, 1):
"""

test_data = [1, 2, 3, 4, 5, 6]
result_data = [(2,), (1,), (0,), (0, -1), (0, -2), (0, -3)]

for variant, (iterations, expected) in enumerate(zip(test_data, result_data), start=1):
alien = Alien(2, 2)
with self.subTest(f'variation #{variant}', input=iterations, output=result):
error = ("Expected hit method to decrement health by 1. "
f"Health is {alien.health} when it should be {result}.")

with self.subTest(f'variation #{variant}',
iterations=iterations,
expected=expected):

for _ in range(iterations):
alien.hit()
self.assertIn(alien.health, result, msg=error)

error_message = (f'Called hit() {iterations} time(s) '
f'on a newly created Alien. The Aliens health '
f'is now {alien.health}, but the tests expected '
f'it to be in {expected} after decrementing 1 health '
f'point {iterations} time(s).')

self.assertIn(alien.health, expected, msg=error_message)


@pytest.mark.task(taskno=3)
def test_alien_is_alive_method(self):
alien = Alien(0, 1)
alive_error = "Alien is dead while health is greater than 0."
dead_error = "Alien is alive while health is less than or equal to 0."

alive_error = ('Created a new Alien and called hit(). '
'The function is_alive() is returning False (dead) '
'while alien.health is greater than 0.')

dead_error = ('Created a new Alien and called hit(). '
'The function is_alive() is returning True (alive) '
'while alien.health is less than or equal to 0.')

for _ in range(5):
alien.hit()
Expand All @@ -83,70 +121,92 @@ def test_alien_teleport_method(self):
alien = Alien(0, 0)
alien.teleport(-1, -4)

error = (
"Expected alien to be at position (-1, -4) but "
f"instead found it in position {(alien.x_coordinate, alien.y_coordinate)}.")
error_message = ('Called alien.teleport(-1,-4) on a newly created Alien. '
'The Alien was found at position '
f'{(alien.x_coordinate, alien.y_coordinate)}, but the '
'tests expected it at position (-1, -4).')

self.assertEqual((-1, -4), (alien.x_coordinate, alien.y_coordinate), msg=error)
self.assertEqual((-1, -4), (alien.x_coordinate, alien.y_coordinate), msg=error_message)

@pytest.mark.task(taskno=5)
def test_alien_collision_detection_method(self):
alien = Alien(7, 3)
error = "Expected collision_detection method to not be implemented."
error_message = ('Created a new Alien at (7,3) and called '
'alien.collision_detection(Alien(7, 2)). '
f'The method returned {alien.collision_detection(Alien(7, 2))}, '
'but the tests expected None. ')

self.assertIsNone(alien.collision_detection(Alien(7, 2)), msg=error_message)

self.assertIsNone(alien.collision_detection(Alien(7, 2)), msg=error)

# Test class variables are identical across instances
@pytest.mark.task(taskno=6)
def test_alien_class_variable(self):
alien_one = Alien(0, 2)
alien_two = Alien(-6, -1)
Alien.total_aliens_created = -2
"""Test class attribute/variables are identical across instances."""

alien_one, alien_two = Alien(0, 2), Alien(-6, -1)
Alien.health = 6

error_one = "Expected the total_aliens_created variable to be identical."
error_two = "Expected the health variable to be identical."
created_error_message = ('Created two new Aliens and requested the '
'total_aliens_created attribute for each one. '
f'Received {alien_one.total_aliens_created, alien_two.total_aliens_created} '
f'for total_aliens_created, but the tests expect '
f'the class attributes for each newly created Alien to be identical. ')

self.assertEqual(alien_two.total_aliens_created, alien_one.total_aliens_created, msg=error_one)
self.assertEqual(alien_two.health, alien_one.health, msg=error_two)
health_error_message = ('Created two new Aliens and requested the '
f'health attribute for each one. Received {alien_one.health, alien_two.health} '
'for health, but the tests expect the class '
'attributes for each newly created Alien to be identical. ')

self.assertEqual(alien_two.total_aliens_created,
alien_one.total_aliens_created,
msg=created_error_message)

self.assertEqual(alien_two.health,
alien_one.health,
msg=health_error_message)

# Test total_aliens_created increments upon object instantiation
@pytest.mark.task(taskno=6)
def test_alien_total_aliens_created(self):
"""Test total_aliens_created class variable increments upon object instantiation."""

Alien.total_aliens_created = 0
aliens = [Alien(-2, 6)]
error = ("Expected total_aliens_created to equal 1. Instead "
f"it equals: {aliens[0].total_aliens_created}.")

self.assertEqual(1, aliens[0].total_aliens_created, msg=error)
error_message = ('Created a new Alien and called total_aliens_created for it. '
f'{aliens[0].total_aliens_created} was returned, but '
'the tests expected that total_aliens_created would equal 1.')

self.assertEqual(1, aliens[0].total_aliens_created, msg=error_message)

aliens.append(Alien(3, 5))
aliens.append(Alien(-5, -5))

def error_text(alien, variable):
return (
"Expected all total_aliens_created variables to be "
"equal to number of alien instances (i.e. 3). Alien "
f"number {alien}'s total_aliens_created variable "
f"is equal to {variable}.")
return ('Created two additional Aliens for the session.'
f"Alien number {alien}'s total_aliens_created variable "
f"is equal to {variable}, but the tests expected all "
'total_aliens_created variables for all instances to be '
'equal to number of alien instances created (i.e. 3).')

tac_list = [alien.total_aliens_created for alien in aliens]
self.assertEqual(3, aliens[0].total_aliens_created, msg=error_text(1, aliens[0]))
self.assertEqual(3, aliens[1].total_aliens_created, msg=error_text(2, aliens[1]))
self.assertEqual(3, aliens[2].total_aliens_created, msg=error_text(3, aliens[2]))

self.assertEqual(3, tac_list[0], msg=error_text(1, tac_list[0]))
self.assertEqual(3, tac_list[1], msg=error_text(2, tac_list[1]))
self.assertEqual(3, tac_list[2], msg=error_text(3, tac_list[2]))

# Test that the user knows how to create objects themselves
@pytest.mark.task(taskno=7)
def test_new_aliens_collection(self):
position_data = [(-2, 6), (1, 5), (-4, -3)]
obj_list = new_aliens_collection(position_data)
obj_error = "new_aliens_collection must return a list of Alien objects."
"""Test that the user knows how to create objects themselves."""

test_data = [(-2, 6), (1, 5), (-4, -3)]
actual_result = new_aliens_collection(test_data)

error_message = "new_aliens_collection() must return a list of Alien objects."

for obj, position in zip(obj_list, position_data):
self.assertIsInstance(obj, Alien, msg=obj_error)
for obj in actual_result:
self.assertIsInstance(obj, Alien, msg=error_message)

pos_error = (
f"Expected object to be at position {position} but "
f"instead found it initialized to position {(obj.x_coordinate, obj.y_coordinate)}.")
for position, obj in zip(test_data, actual_result):
position_error = (f'After calling new_aliens_collection({test_data}), '
f'found {obj} initialized to position {(obj.x_coordinate, obj.y_coordinate)}, '
f'but the tests expected {obj} to be at position {position} instead.')

self.assertEqual(position, (obj.x_coordinate, obj.y_coordinate), msg=pos_error)
self.assertEqual(position, (obj.x_coordinate, obj.y_coordinate), msg=position_error)