I've watched quite a few videos and read a couple of articles on unit testing and I've tried my best to make this test case as good as possible. In which areas can it still be improved?
I should probably add that SM2Scheduler is an implementation of the SM2 algorithm, which is used in flashcard software such as Anki and Mnemosyne.
import datetime
import os
import pathlib
import sys
import unittest
# Resolve the relative import error
path_to_this_file = pathlib.Path(__file__)
path_to_srsalgorithms = path_to_this_file.parents[1]
sys.path.append(str(path_to_srsalgorithms))
from sm2 import SM2Scheduler
class TestSM2Scheduler(unittest.TestCase):
def setUp(self):
self.scheduler = SM2Scheduler()
def test_init_last_review_date_is_today(self):
last_review_date = self.scheduler.last_review_date
today = datetime.date.today()
self.assertEqual(last_review_date, today)
def test_init_new_card_is_to_be_seen_today(self):
days_until_next_review = self.scheduler.days_until_next_review
self.assertEqual(days_until_next_review, 0)
def test_init_new_card_has_not_been_reviewed_yet(self):
number_of_repetitions = self.scheduler.number_of_repetitions
self.assertEqual(number_of_repetitions, 0)
def test_init_default_easiness_factor_is_2_point_5(self):
easiness_factor = self.scheduler.easiness_factor
self.assertEqual(easiness_factor, 2.5)
def test_feed_last_review_date_is_updated_after_repetition(self):
self.scheduler.feed(5)
last_review_date = self.scheduler.last_review_date
today = datetime.date.today()
self.assertEqual(last_review_date, today)
def test_feed_number_of_repetitions_is_set_to_0_if_card_rating_is_below_3(self):
self.scheduler.feed(2)
number_of_repetitions = self.scheduler.number_of_repetitions
self.assertEqual(number_of_repetitions, 0)
def test_feed_number_of_repetitions_is_incremented_if_card_rating_is_3_or_more(self):
self.scheduler.feed(3)
number_of_repetitions = self.scheduler.number_of_repetitions
self.assertEqual(number_of_repetitions, 1)
def test_get_date_due_for_review_returns_correct_date(self):
self.scheduler.days_until_next_review = 5
next_review_date = self.scheduler.get_date_due_for_review()
in_5_days = datetime.date.today() + datetime.timedelta(days=5)
self.assertEqual(next_review_date, in_5_days)
def test_get_new_easiness_factor_lowest_possible_easiness_factor_is_1_point_3(self):
self.scheduler.easiness_factor = 1.3
new_easiness_factor = self.scheduler._get_new_easiness_factor(0)
self.assertEqual(new_easiness_factor, 1.3)
def test_get_new_easiness_factor_calculates_correctly(self):
easiness_factor = self.scheduler._get_new_easiness_factor(0)
self.assertAlmostEqual(easiness_factor, 1.7)
easiness_factor = self.scheduler._get_new_easiness_factor(1)
self.assertAlmostEqual(easiness_factor, 1.96)
easiness_factor = self.scheduler._get_new_easiness_factor(2)
self.assertAlmostEqual(easiness_factor, 2.18)
easiness_factor = self.scheduler._get_new_easiness_factor(3)
self.assertAlmostEqual(easiness_factor, 2.36)
easiness_factor = self.scheduler._get_new_easiness_factor(4)
self.assertAlmostEqual(easiness_factor, 2.5)
easiness_factor = self.scheduler._get_new_easiness_factor(5)
self.assertAlmostEqual(easiness_factor, 2.6)
def test_get_new_days_until_next_review_card_is_to_be_seen_again_today_if_rating_is_below_3(self):
days_until_next_review = self.scheduler._get_new_days_until_next_review(2)
self.assertEqual(days_until_next_review, 0)
def test_get_new_days_until_next_review_card_is_to_be_seen_tomorrow_if_it_has_only_been_repeated_once(self):
self.scheduler.number_of_repetitions = 1
days_until_next_review = self.scheduler._get_new_days_until_next_review(3)
self.assertEqual(days_until_next_review, 1)
def test_get_new_days_until_next_review_card_is_to_be_seen_in_6_days_if_it_has_only_been_repeated_twice(self):
self.scheduler.number_of_repetitions = 2
days_until_next_review = self.scheduler._get_new_days_until_next_review(3)
self.assertEqual(days_until_next_review, 6)
def test_get_new_days_until_next_review_calculates_correctly(self):
self.scheduler.number_of_repetitions = 3
self.scheduler.days_until_next_review = 6
self.scheduler.easiness_factor = 2.5
days_until_next_review = self.scheduler._get_new_days_until_next_review(3)
self.assertEqual(days_until_next_review, 6*2.5)
if __name__ == '__main__':
unittest.main()
coverage.py
to spot branches you did not cover with tests. \$\endgroup\$