Skip to content

Commit

Permalink
merged tests per task
Browse files Browse the repository at this point in the history
  • Loading branch information
ReTeam Labs committed May 6, 2020
1 parent 1f3e4f4 commit d94ac84
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 75 deletions.
29 changes: 5 additions & 24 deletions tests/pytest.ini
Original file line number Diff line number Diff line change
@@ -1,34 +1,15 @@
[pytest]
addopts = --json-report -v --tb=short
markers =
task_1_regular_class_exists
task_1_regular_class_implementation

task_2_overriding_text

task_3 : generic mark for task 3
task_4 : generic mark for task 4
abstract_classes_exist : specific mark for both task 3 and 4
abstract_isdue_exists : specific mark for for both task 3 and 4

task_3_DeadlinedMetaReminder
task_4_DeadlinedReminder
task_5_concrete_subclass_stub

task_6_is_due

task_7_iter

task_8_signature
task_8_adding

task_9_correct_imports
task_9_add_reminder_third_parameter
task_9_add_reminder_date
task_9_add_reminder_incorrect

task_8_update_interface
task_9_accept_class
task_10_subclasshook
task_10_add_reminder_evening

task_11_add_reminder_isinstance

task_12_polite_reminder_touchup
task_12_registration
task_12_register_polite_reminder
104 changes: 53 additions & 51 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

# This is for generality of task of implementation the concrete class
CONCRETE_CLASS_NAME = 'DateReminder'
ABSTRACT_METHOD_NAME = 'is_due'

class DummyReminder:
def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -53,17 +54,15 @@ def backup_reminders_csv():

# === TASK 1 ========================================================================

@pytest.mark.task_1_regular_class_exists
def test_task_1_regular_class_exists():
@pytest.mark.task_1_regular_class_implementation
def test_task_1_regular_class_implementation():
assert hasattr(reminder, 'PoliteReminder'), \
'You should implement class `PoliteReminder` in reminder.py'
assert inspect.isclass(reminder.PoliteReminder), \
'`PoliteReminder` is not a class'
assert issubclass(reminder.PoliteReminder, reminder.PrefixedReminder), \
'`PoliteReminder` should inherit from `PrefixedReminder`'

@pytest.mark.task_1_regular_class_implementation
def test_task_1_regular_class_implementation():
polite_reminder = reminder.PoliteReminder('test_string')
assert hasattr(polite_reminder, 'prefix'), \
'No `prefix` property on `PoliteReminder`. Did you inherit from `PrefixedReminder`?'
Expand All @@ -82,19 +81,13 @@ def test_task_2_overriding_text():

# === TASK 3-4 ======================================================================

@pytest.mark.task_3
@pytest.mark.task_4
def test_deadlined_module_exists():
@pytest.mark.task_3_DeadlinedMetaReminder
def test_task_3_DeadlinedMetaReminder():
assert DEADLINED_REMINDERS_IMPORTED, \
'Could not find module `deadlined_reminders`. Check the name is correct...'


@pytest.mark.abstract_classes_exist
@pytest.mark.parametrize('class_name', [
pytest.param('DeadlinedMetaReminder', marks=pytest.mark.task_3),
pytest.param('DeadlinedReminder' , marks=pytest.mark.task_4)
])
def test_abstract_classes_exist(class_name):
# this is a vestige of parametrized tests
class_name = 'DeadlinedMetaReminder'
assert hasattr(dr, class_name), \
f'Could not find class `{class_name}` in `deadlined_reminders.py`'

Expand All @@ -105,23 +98,44 @@ def test_abstract_classes_exist(class_name):
assert type(cls) == ABCMeta, f'{class_name} should be an Abstract Base Class'
assert issubclass(cls, Iterable), f'{class_name} should inherit from `collections.abc.Iterable`'

if class_name == 'DeadlinedReminder':
assert ABC in cls.__mro__, 'Class `DeadlinedReminder` should inherit from `ABC`'
# --- CHECK METHOD ----------------------------
assert hasattr(cls, ABSTRACT_METHOD_NAME),\
f'Could not find `{ABSTRACT_METHOD_NAME}` in `{class_name}`'
assert ABSTRACT_METHOD_NAME in cls.__abstractmethods__,\
f'Method {ABSTRACT_METHOD_NAME} is not abstract in class {class_name}'

params = inspect.signature(cls.is_due).parameters
assert 'self' in params,\
f'`{ABSTRACT_METHOD_NAME}()` should be a method. Did you forget `self`?'


@pytest.mark.abstract_isdue_exists
@pytest.mark.parametrize('class_name', [
pytest.param('DeadlinedMetaReminder', marks=pytest.mark.task_3),
pytest.param('DeadlinedReminder' , marks=pytest.mark.task_4)
])
def test_abstract_isdue_exists(class_name, method_name='is_due'):
@pytest.mark.task_4_DeadlinedReminder
def test_task_4_DeadlinedReminder():
assert DEADLINED_REMINDERS_IMPORTED, \
'Could not find module `deadlined_reminders`. Check the name is correct...'

class_name = 'DeadlinedReminder'
assert hasattr(dr, class_name), \
f'Could not find class `{class_name}` in `deadlined_reminders.py`'

cls = getattr(dr, class_name)
assert hasattr(cls, method_name), f'Could not find `{method_name}` in `{class_name}`'
assert method_name in cls.__abstractmethods__,\
f'Method {method_name} is not abstract in class {class_name}'
assert inspect.isclass(cls), f'`{class_name}` is not a class'

assert inspect.isabstract(cls), f'{class_name} should be abstract'
assert type(cls) == ABCMeta, f'{class_name} should be an Abstract Base Class'
assert issubclass(cls, Iterable), f'{class_name} should inherit from `collections.abc.Iterable`'

assert ABC in cls.__mro__, 'Class `DeadlinedReminder` should inherit from `ABC`'

# --- CHECK METHOD ----------------------------
assert hasattr(cls, ABSTRACT_METHOD_NAME),\
f'Could not find `{ABSTRACT_METHOD_NAME}` in `{class_name}`'
assert ABSTRACT_METHOD_NAME in cls.__abstractmethods__,\
f'Method {ABSTRACT_METHOD_NAME} is not abstract in class {class_name}'

params = inspect.signature(cls.is_due).parameters
assert 'self' in params, f'`{method_name}()` should be a method. Did you forget `self`?'
assert 'self' in params,\
f'`{ABSTRACT_METHOD_NAME}()` should be a method. Did you forget `self`?'


# === TASK 5 & 6 & 7 ================================================================
Expand Down Expand Up @@ -225,8 +239,8 @@ def test_task_7_iter():

# === TASK 8 ========================================================================

@pytest.mark.task_8_signature
def test_task_8_signature():
@pytest.mark.task_8_update_interface
def test_task_8_update_interface(backup_reminders_csv):
add_reminder_params = inspect.signature(database.add_reminder).parameters
assert len(add_reminder_params) >= 2,\
'`database.add_reminder()` should take two parameters'
Expand All @@ -238,10 +252,6 @@ def test_task_8_signature():
assert add_reminder_params['date'].default is inspect.Parameter.empty,\
'`date` should not have a default value in `database.add_reminder()`'

@pytest.mark.task_8_adding
def test_task_8_adding(backup_reminders_csv):
# the following only applies before extending add_reminder with a class
add_reminder_params = inspect.signature(database.add_reminder).parameters
if len(add_reminder_params) > 2:
return

Expand All @@ -265,8 +275,9 @@ def test_task_8_adding(backup_reminders_csv):

# === TASK 9 ========================================================================

@pytest.mark.task_9_correct_imports
def test_task_9_correct_imports():
@pytest.mark.task_9_accept_class
def test_task_9_accept_class(backup_reminders_csv):
# --- correct_imports ---------------------------------------------
assert not hasattr(database, 'PoliteReminder'),\
'You should no longer import `PoliteReminder` in `database`'
assert not hasattr(database, 'DateReminder'),\
Expand All @@ -275,24 +286,18 @@ def test_task_9_correct_imports():
assert hasattr(database, 'DeadlinedReminder'),\
'You should import `DeadlinedReminder` in `database`'


@pytest.mark.task_9_add_reminder_third_parameter
def test_task_9_add_reminder_third_parameter():
# --- add_reminder_third_parameter --------------------------------
signature = inspect.signature(database.add_reminder)
params = list(signature.parameters)
assert len(params) == 3,\
'You should pass a third parameter to `add_reminder`'
assert params[2] == 'ReminderClass',\
'The third parameter should be `ReminderClass`'


@pytest.mark.task_9_add_reminder_date
def test_task_9_add_reminder_date(backup_reminders_csv):
# --- add_reminder_date -------------------------------------------
database.add_reminder('test_reminder', '1/1/2020', dr.DateReminder)


@pytest.mark.task_9_add_reminder_incorrect
def test_task_9_add_reminder_incorrect(backup_reminders_csv):
# --- add_reminder_incorrect --------------------------------------
# NOTE: pytest.raises(TypeError) does not work here as we want custom message
# for the other exceptions, which would bubble up otherwise
error_message = 'You should only allow conforming classes in `add_reminder`.'\
Expand All @@ -308,7 +313,7 @@ def test_task_9_add_reminder_incorrect(backup_reminders_csv):
# === TASK 10 ========================================================================

@pytest.mark.task_10_subclasshook
def test_app_opening_subclasshook():
def test_app_opening_subclasshook(backup_reminders_csv):
DeadlinedReminder = dr.DeadlinedReminder
assert '__subclasshook__' in DeadlinedReminder.__dict__,\
'Could not find `__subclasshook__` onto `DeadlinedReminder`'
Expand All @@ -326,8 +331,7 @@ def test_app_opening_subclasshook():
'`__subclasshook__` gives wrong result for class that '\
' does not respect the protocol of `DeadlinedReminder`'

@pytest.mark.task_10_add_reminder_evening
def test_app_opening_add_reminder_evening(backup_reminders_csv):
# --- task_10_add_reminder_evening ---------------------------------
assert hasattr(app, 'EveningReminder'),\
'You did not import/use `EveningReminder` in `app.py`'

Expand Down Expand Up @@ -367,8 +371,8 @@ def test_app_opening_add_reminder_isinstance():

# === TASK 12 ========================================================================

@pytest.mark.task_12_polite_reminder_touchup
def test_registration_polite_reminder():
@pytest.mark.task_12_register_polite_reminder
def test_task_12_register_polite_reminder():
PoliteReminder = reminder.PoliteReminder
assert hasattr(PoliteReminder, '__iter__'),\
'You should add `__iter__` on PoliteReminder'
Expand All @@ -388,9 +392,7 @@ def test_registration_polite_reminder():
assert len(polite_reminder_iter) == 1,\
'`PoliteReminder.__iter__()` should return only one item in the list'


@pytest.mark.task_12_registration
def test_registration_works():
# --- task_12_registration ------------------------------------------
assert hasattr(app, 'PoliteReminder'),\
'You should import `PoliteReminder` in `app.py`'

Expand Down

0 comments on commit d94ac84

Please sign in to comment.