UnitTest – встроенный тестировщик Python

онлайн тренер по питону
Онлайн-тренажер Python 3 для начинающих

Теория без воды. Задачи с автоматической проверкой. Подсказки на русском языке. Работает в любом современном браузере.

начать бесплатно

Введение

Тестирование — ключевой элемент разработки качественного программного обеспечения. Python предоставляет встроенный модуль unittest, основанный на фреймворке xUnit, который обеспечивает полный набор инструментов для написания, группировки и запуска тестов.

UnitTest – встроенный тестировщик Python позволяет создавать повторяемые и изолированные модульные тесты, проверять бизнес-логику, контролировать работу функций и классов. Он включён в стандартную библиотеку и не требует дополнительных установок.

Основы использования UnitTest

Импорт модуля:

python
import unittest

Создание первого теста:

python
class TestMath(unittest.TestCase): def test_add(self): self.assertEqual(2 + 3, 5) if __name__ == '__main__': unittest.main()

Структура тестового класса

  • Все тестовые методы начинаются с test_

  • Наследование от unittest.TestCase обязательно

  • Можно использовать специальные методы:

python
def setUp(self): # вызывается перед каждым тестом def tearDown(self): # вызывается после каждого теста def setUpClass(cls): # один раз перед всеми тестами класса def tearDownClass(cls):# один раз после всех тестов класса

Ассерты и проверки

Наиболее часто используемые проверки:

python
self.assertEqual(a, b) self.assertNotEqual(a, b) self.assertTrue(x) self.assertFalse(x) self.assertIsNone(x) self.assertIsInstance(x, SomeClass) self.assertRaises(SomeException, func, *args)

Контекстный менеджер:

python
with self.assertRaises(ZeroDivisionError): 1 / 0

Запуск тестов

Из терминала

bash
python -m unittest python -m unittest test_module.py python -m unittest test_module.TestClass

Через unittest.main()

Используется в скриптах:

python
if __name__ == '__main__': unittest.main()

Группировка тестов и модульное тестирование

Создание набора тестов вручную:

python
def suite(): suite = unittest.TestSuite() suite.addTest(TestMath('test_add')) return suite runner = unittest.TextTestRunner() runner.run(suite())

Моки и патчинг функций

Модуль unittest.mock позволяет заменить поведение функций и объектов:

python
from unittest.mock import patch @patch('module.func') def test_mocked_func(mock_func): mock_func.return_value = 10 assert module.func() == 10

Можно подменять переменные окружения, запросы к API, базы данных.

Тестирование исключений

python
with self.assertRaises(ValueError): int("abc")

Подходит как для встроенных, так и для пользовательских исключений.

Изоляция тестов и фикстуры

  • setUp() и tearDown() — каждый тест

  • setUpClass() и tearDownClass() — один раз для класса

Это полезно для создания временных файлов, подключения к БД, очистки окружения.

Параметризация и шаблоны тестов

UnitTest не поддерживает параметризацию "из коробки", но можно использовать subTest():

python
def test_multiple(self): for a, b, result in [(1, 1, 2), (2, 2, 4)]: with self.subTest(a=a, b=b): self.assertEqual(a + b, result)

Интеграция с CI/CD и IDE

  • Поддерживается во всех популярных IDE (PyCharm, VS Code)

  • Используется во многих CI-системах: GitHub Actions, GitLab CI, Jenkins

Пример в GitHub Actions:

yaml
- name: Run UnitTest run: python -m unittest discover

Сравнение с Pytest и другими фреймворками

Характеристика unittest pytest nose
Встроен в Python Да Нет Нет
Синтаксис Более формальный Лаконичный Похож на Pytest
Параметризация Через subTest() Простая @parametrize Поддерживается
Поддержка Mock Да (unittest.mock) Да (pytest-mock) Частично
Порог вхождения Средний Низкий Средний

Расширения и дополнительные возможности

  • unittest.skip, unittest.skipIf, expectedFailure

  • Патчинг через patch.object, patch.dict, patch.multiple

  • Создание базовых классов для переиспользования кода

Пример:

python
@unittest.skip("Тест временно отключён") def test_temp(self): ...

Примеры тестирования API и функций

Простая бизнес-логика

python
class TestCalc(unittest.TestCase): def test_divide(self): self.assertEqual(10 / 2, 5)

Тестирование FastAPI через TestClient

python
from fastapi.testclient import TestClient from myapp import app class TestAPI(unittest.TestCase): def setUp(self): self.client = TestClient(app) def test_get_root(self): response = self.client.get("/") self.assertEqual(response.status_code, 200)

Часто задаваемые вопросы (FAQ)

1. Что такое UnitTest?
Это встроенный в Python модуль для создания и запуска модульных тестов.

2. Чем он отличается от Pytest?
UnitTest требует больше шаблонного кода, но не требует сторонних установок.

3. Поддерживает ли UnitTest mock-объекты?
Да, через unittest.mock.

4. Как запускать тесты?
Через python -m unittest, unittest.main() или в IDE.

5. Можно ли делать асинхронные тесты?
Да, но требует дополнительных обёрток или asyncio-тестов вручную.

6. Где хранить фикстуры?
В методах setUp(), setUpClass() или отдельных модулях.

Полный справочник по работе с unittest — стандартной библиотекой для тестирования в Python

Основы: структура теста

python
import unittest class TestMath(unittest.TestCase): def test_addition(self): self.assertEqual(2 + 2, 4) if __name__ == '__main__': unittest.main()

Запуск тестов

bash
python test_math.py

Или из командной строки:

bash
python -m unittest discover

Основные методы-утверждения (assert)

Метод Назначение
assertEqual(a, b) Проверка a == b.
assertNotEqual(a, b) Проверка a != b.
assertTrue(x) / assertFalse(x) Проверка булевых значений.
assertIs(a, b) / assertIsNot(a, b) Проверка идентичности объектов.
assertIsNone(x) / assertIsNotNone(x) Проверка None.
assertIn(a, b) / assertNotIn(a, b) Проверка наличия в контейнере.
assertRaises(exc, func, *args) Проверка, что вызывается исключение.
assertAlmostEqual(a, b) Проверка равенства с округлением.

Установка и очистка (фикстуры)

Метод Назначение
setUp() Выполняется перед каждым тестом.
tearDown() Выполняется после каждого теста.
setUpClass() Один раз перед всеми тестами в классе.
tearDownClass() Один раз после всех тестов.
python
class TestExample(unittest.TestCase): @classmethod def setUpClass(cls): print("Start of test class") def setUp(self): self.data = [1, 2, 3] def test_length(self): self.assertEqual(len(self.data), 3) def tearDown(self): self.data.clear()

Группировка тестов

python
def suite(): suite = unittest.TestSuite() suite.addTest(TestMath('test_addition')) return suite unittest.TextTestRunner().run(suite())

Проверка исключений

python
def divide(a, b): return a / b class TestErrors(unittest.TestCase): def test_zero_division(self): with self.assertRaises(ZeroDivisionError): divide(1, 0)

Моки и патчи

Для подмены зависимостей используется unittest.mock.

python
from unittest.mock import patch @patch("module.function") def test_mocked(mock_func): mock_func.return_value = 10 assert mock_func() == 10

Запуск из терминала с параметрами

bash
python -m unittest test_module.TestClass.test_method

Пример: полный тестовый файл

python
import unittest def add(a, b): return a + b class TestCalc(unittest.TestCase): def test_add(self): self.assertEqual(add(2, 3), 5) def test_add_negative(self): self.assertEqual(add(-1, -1), -2) if __name__ == '__main__': unittest.main()

Когда использовать unittest

  • Для встроенного решения без зависимостей.

  • Для автоматического запуска и отчётности.

  • Когда важно разделение на тестовые классы, методы и наборы.

  • Для интеграции с CI/CD (GitHub Actions, Jenkins и др

Заключение

UnitTest – встроенный тестировщик Python остаётся надёжным, понятным и гибким решением для модульного тестирования. Он подходит как для новичков, так и для опытных разработчиков, обеспечивает интеграцию с IDE и CI/CD, поддерживает моки и фикстуры. Это отличное решение для начала тестирования в любом Python-проекте.