unittest – це вбудований модуль Python, який надає фреймворк для написання та запуску модульних тестів (unit testing). unittest входить у стандартну бібліотеку Python, тобто не потребує додаткових інсталяцій перед початком роботи.
Основні концепції що підтримуються фреймворком unittest
test fixture: являє собою підготовчі дії, необхідні для виконання одного або декількох тестів, і відповідно дії з очищення після їх виконання. Як приклад, створення тимчасових баз даних, каталогів, запуск серверного процесу, тощо.
test case: окрема одиниця (unit) тестування, що перевіряє певну реакцію на певний набір вхідних даних. unittest надає базовий клас TestCase, який можна використовувати для створення нових тестових кейсів.
test suite: сукупність тестових кейсів, використовується для об’єднання тестів, які повинні виконуватись разом.
test runner: компонент, відповідальний за організацію виконання тестів та надання результатів.
Базовий приклад використання unittest
Припустимо, що у нас є модуль util.py, що містить клас Calculations:
class Calculations:
def __init__(self, a, b):
self.a = a
self.b = b
def sum(self):
return self.a + self.b
def difference(self):
return self.a - self.bВ модулі test_util.py створимо тести для методів класу Calculations, використовуючи модуль unittest:
import unittest
from util import Calculations
class TestCalculations(unittest.TestCase):
def test_sum(self):
calculation = Calculations(1, 5)
self.assertEqual(calculation.sum(), 10, 'The sum is wrong.')
def test_difference(self):
calculation = Calculations(1, 5)
self.assertEqual(calculation.difference(), -4, 'The difference is wrong.')
if __name__ == '__main__':
unittest.main()Щоб використовувати unittest потрібно:
- створити клас тестів, що успадковує unittest.TestCase
- всередині тестового класу, визначити тестові методи котрі містять перевірки (ім’я таких методів повинно починатись з test_)
- використовувати спеціальні методи твердження assert*, для перевірки очікуваних результатів
- unittest.main() надає інтерфейс командного рядка до тестового скрипту
Щоб виконати ці тести, потрібно просто запустити модуль test_util.py на виконання:
python test_util.pyРезультат виглядає наступним чином:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OKСимвол крапки у результатах ".", означає що тест пройдено. Якщо до команди запуску додати опцію "-v", можна отримати більш детальний вивід про результат:
python test_util.py -vРезультат:
test_difference (__main__.TestCalculations) ... ok
test_sum (__main__.TestCalculations) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OKПовний перелік опцій командного рядка доступний за посиланням:
Методи assert* у unittest
Клас TestCase з модуля unittest, надає перелік методів для перевірки очікуваного результату. Розглянемо деякі з них:
assertEqual(first, second, msg=None) – перевіряє що first та second еквівалентні (подібно до виразу first == second)
assertNotEqual(first, second, msg=None) – перевірка що first та second не еквівалентні (тобто first != second)
assertTrue(expr, msg=None) – перевіряє що expr є істинним (тобто bool(expr) is True)
assertFalse(expr, msg=None) – перевіряє що expr є хибним
assertIs(first, second, msg=None) – перевіряє чи є first та second одним і тим самим об’єктом
assertIsNot(first, second, msg=None) – перевіряє що first та second не є одним і тим самим об’єктом
assertIsNone(expr, msg=None) та assertIsNotNone(expr, msg=None) – перевіряють що expr є None (або навпаки)
assertIn(member, container, msg=None) та assertNotIn(member, container, msg=None) – перевірити чи міститься (або ні) member у container (мається на увазі список, кортеж, тощо)
assertIsInstance(obj, cls, msg=None) та assertNotIsInstance(obj, cls, msg=None) – перевірити чи obj є екземпляром класу cls (або навпаки), подібно до функції isinstance(obj, cls)
assertRaises(exception, callable, *args, **kwds) – перевіряє, чи згенеровано exception під час виклику callable, тест буде пройдено якщо виключення згенеровано
Також зверніть увагу на опціональний атрибут msg у методах assert*, котрий дозволяє додати користувацьке повідомлення, що буде додано до результату якщо тест failed.
Методи setUp() та tearDown()
Клас unittest.TestCase містить методи setUp() та tearDown(), які запускаються перед/після кожного тесту, відповідно. Адаптуємо приклад вище, та винесемо ініціалізацію об’єкта класу Calculations, з тестових методів у метод setUp():
import unittest
from util import Calculations
class TestCalculations(unittest.TestCase):
def setUp(self):
self.calculation = Calculations(1, 5)
def test_sum(self):
self.assertEqual(self.calculation.sum(), 6, 'The sum is wrong.')
def test_difference(self):
self.assertEqual(self.calculation.difference(), -4, 'The difference is wrong.')
if __name__ == '__main__':
unittest.main()Підсумок
Наостанок, посилання на сторінку документації:
unittest – Unit testing framework Python