Створення модульних тестів: базові тести
Тепер давайте напишемо кілька тестів, щоб переконатися, що наша функція працює правильно. Ми використовуватимемо unittestмодуль Python. Створіть новий файл з назвою test_key_of_max.pyта додайте наступний код:
import unittest
from key_of_max import key_of_max ## Import our function
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
if __name__ == '__main__':
unittest.main()
Пояснення:
-
import unittestІмпортує платформу тестування.
-
from key_of_max import key_of_maxІмпортує функцію, яку ми хочемо протестувати.
-
class TestKeyOfMax(unittest.TestCase):Визначає клас тестів . Класи тестів групують пов’язані тести разом.
-
def test_basic_case(self):Визначає метод тестування . Кожен метод тестування перевіряє певний аспект нашої функції. Назви методів тестування повинні починатися з test_.
-
self.assertEqual(...)Це твердження . Воно перевіряє, чи два значення рівні. Якщо вони не рівні, перевірка не проходить. У цьому випадку ми перевіряємо, чи key_of_max({'a': 4, 'b': 0, 'c': 13})повертає 'c', що й повинно бути.
-
def test_another_case(self):Додано ще один тестовий випадок для перевірки ключа максимального значення, яке може бути неунікальним.
-
if __name__ == '__main__': unittest.main()Ця стандартна ідіома Python запускає тести, коли ви виконуєте скрипт безпосередньо (наприклад, python3 test_key_of_max.py).
Запустіть тести з терміналу:. python3 test_key_of_max.pyВи повинні побачити вивід, який вказує на те, що обидва тести пройдено успішно.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Тестування порожнього словника (граничний випадок)
Давайте додамо тест спеціально для випадку порожнього словника. Додайте цей метод до вашого TestKeyOfMaxкласу в test_key_of_max.py:
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
-
self.assertIsNone(...)Це твердження перевіряє, чи значення саме None. Це важливо, оскільки self.assertEqual(..., None)може передаватися як значення, які обчислюються як None, але насправді не є None. assertIsNoneє більш суворим.
Знову запустіть тести ( python3 test_key_of_max.py). Усі три тести (два базові тести та тест порожнього словника) тепер мають бути успішними.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
Тестування з усіма від’ємними значеннями
Як остаточний тест, розглянемо випадок, коли всі значення у словнику є від’ємними. Додайте цей метод до TestKeyOfMax:
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
Цей тест гарантує, що наша функція правильно визначає найменше від’ємне значення (яке в цьому випадку є максимальним) та повертає пов’язаний з ним ключ.
Виконайте тести ще раз ( python3 test_key_of_max.py). Усі чотири тести мають бути успішними. Це дає нам високу впевненість у тому, що наша функція працює правильно.
Тепер ваш повний test_key_of_max.pyвигляд має бути таким:
import unittest
from key_of_max import key_of_max
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
if __name__ == '__main__':
unittest.main()
Знову запустіть тести ( python3 test_key_of_max.py). Усі чотири тести мають бути успішними. Це дає нам високу впевненість у тому, що наша функція працює правильно.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
Висновок
Ми створили просту, але потужну функцію key_of_max(), яка дозволяє швидко знаходити ключ із найбільшим значенням у словнику Python. Під час розробки ми крок за кроком врахували всі важливі деталі: обробку порожніх словників, перевірку випадків із повторюваними значеннями та навіть тестування з від’ємними числами. Завдяки модульним тестам ми переконалися, що функція працює стабільно у всіх сценаріях.
Такий підхід не лише навчає правильно мислити в термінах чистого й надійного коду, а й демонструє, як варто будувати маленькі, але ефективні утиліти, які роблять роботу з даними у Python швидшою та зрозумілішою.
Якщо ви прагнете покращити свої навички у Python — цей приклад чудово показує, що навіть проста функція може навчити мислити як справжній розробник.