Skip to content

Unittest Fixture

Fixture

Fixture - это методы, которые выполняются перед и после выполнения тестового случая. Unittest предоставляет несколько методов fixture:

  • setUp: выполняется перед выполнением каждого тестового случая.
  • tearDown: выполняется после выполнения каждого тестового случая.
  • setUpClass: выполняется перед выполнением всех тестовых случаев в классе.
  • tearDownClass: выполняется после выполнения всех тестовых случаев в классе.
python
from unittest import TestCase

class TestExample(TestCase):
    def setUp(self):
        print("setUp")

    def tearDown(self):
        print("tearDown")

    def test_example(self):
        print("test_example")
        self.assertEqual(2 + 2, 4)

    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    @classmethod
    def tearDownClass(cls):
        print("tearDownClass")

Другой пример кода:

python
import unittest

class TestWithFixtures(unittest.TestCase):

  @classmethod
  def setUpClass(cls) -> None:
    """Вызывается один раз перед всеми тестами в классе."""
    print("setUpClass")

  def setUp(self) -> None:
    """Вызывается перед каждым тестовым методом."""
    print("setUp")
    self.data = [1, 2, 3]

  def test_sum(self) -> None:
    """Тестирование суммы элементов списка."""
    self.assertEqual(sum(self.data), 6)

  def test_length(self) -> None:
    """Тестирование длины списка."""
    self.assertEqual(len(self.data), 3)

  def tearDown(self) -> None:
    """Вызывается после каждого тестового метода."""
    print("tearDown")
    del self.data

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

Упражнения

  1. Тестирование функции: Напишите тестовый случай для функции, которая вычисляет площадь круга.
  2. Тестирование класса: Напишите тестовый случай для класса, который представляет собой банковский счет.
  3. Использование fixture: Напишите тестовый случай, который использует fixture для инициализации данных.
  4. Тестирование исключений: Напишите тестовый случай, который проверяет, что функция выбрасывает исключение при неверных входных данных.
  5. Тестирование метода: Напишите тестовый случай для метода, который сортирует список чисел.
  6. Тестирование класса с несколькими методами: Напишите тестовый случай для класса, который имеет несколько методов, и проверьте, что все они работают корректно.
  7. Использование параметрического тестирования: Напишите тестовый случай, который использует параметрическое тестирование для проверки функции с разными входными данными.
  8. Тестирование файла: Напишите тестовый случай, который проверяет содержимое файла.

1. Тестирование строки

Название: TestStringMethods

Задача: Напишите класс TestStringMethods, наследующийся от unittest.TestCase, который будет содержать тесты для следующих методов строки:

  • upper(): Проверяет, что строка преобразуется в верхний регистр.
  • lower(): Проверяет, что строка преобразуется в нижний регистр.
  • split(): Проверяет, что строка разбивается на список слов.
  • strip(): Проверяет, что строка очищается от пробелов в начале и конце.
python
import unittest

class TestStringMethods(unittest.TestCase):

  def test_upper(self) -> None:
    self.assertEqual("hello".upper(), "HELLO")

  def test_lower(self) -> None:
    self.assertEqual("HELLO".lower(), "hello")

  def test_split(self) -> None:
    self.assertEqual("hello world".split(), ["hello", "world"])

  def test_strip(self) -> None:
    self.assertEqual("  hello  ".strip(), "hello")

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

2. Тестирование списка

Название: TestListMethods

Задача: Напишите класс TestListMethods, наследующийся от unittest.TestCase, который будет содержать тесты для следующих операций со списком:

  • Добавление элемента в список.
  • Удаление элемента из списка.
  • Проверка наличия элемента в списке.
  • Проверка длины списка.
python
import unittest

class TestListMethods(unittest.TestCase):

  def setUp(self) -> None:
    self.my_list = [1, 2, 3]

  def test_append(self) -> None:
    self.my_list.append(4)
    self.assertEqual(self.my_list, [1, 2, 3, 4])

  def test_remove(self) -> None:
    self.my_list.remove(2)
    self.assertEqual(self.my_list, [1, 3])

  def test_contains(self) -> None:
    self.assertTrue(1 in self.my_list)

  def test_length(self) -> None:
    self.assertEqual(len(self.my_list), 3)

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

3. Тестирование словаря

Название: TestDictMethods

Задача: Напишите класс TestDictMethods, наследующийся от unittest.TestCase, который будет содержать тесты для следующих операций со словарем:

  • Добавление пары ключ-значение.
  • Получение значения по ключу.
  • Удаление пары ключ-значение.
  • Проверка наличия ключа в словаре.
python
import unittest

class TestDictMethods(unittest.TestCase):

  def setUp(self) -> None:
    self.my_dict = {"a": 1, "b": 2}

  def test_add(self) -> None:
    self.my_dict["c"] = 3
    self.assertEqual(self.my_dict, {"a": 1, "b": 2, "c": 3})

  def test_get(self) -> None:
    self.assertEqual(self.my_dict.get("a"), 1)

  def test_remove(self) -> None:
    del self.my_dict["b"]
    self.assertEqual(self.my_dict, {"a": 1})

  def test_contains(self) -> None:
    self.assertTrue("a" in self.my_dict)

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

4. Fixture с файлами

Название: TestFileOperationsЗадача: Напишите класс TestFileOperations, который будет тестировать операции с файлами. Используйте setUp для создания временного файла и tearDown для его удаления. Протестируйте запись и чтение данных из файла.

python
import unittest
import os

class TestFileOperations(unittest.TestCase):

  def setUp(self) -> None:
    """Создание временного файла перед каждым тестом."""
    self.filename = "test_file.txt"
    with open(self.filename, "w") as f:
      f.write("Hello, world!")

  def test_read_file(self) -> None:
    """Тестирование чтения данных из файла."""
    with open(self.filename, "r") as f:
      content = f.read()
    self.assertEqual(content, "Hello, world!")

  def test_write_file(self) -> None:
    """Тестирование записи данных в файл."""
    with open(self.filename, "w") as f:
      f.write("New content.")
    with open(self.filename, "r") as f:
      content = f.read()
    self.assertEqual(content, "New content.")

  def tearDown(self) -> None:
    """Удаление временного файла после каждого теста."""
    os.remove(self.filename)

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

5. TestSuite для разных классов

Название: CombineTestSuites

Задача: Создайте два тестовых класса: TestMathFunctions (для тестирования математических функций) и TestStringManipulations (для тестирования манипуляций со строками). Напишите несколько тестов для каждого класса и создайте TestSuite, который объединит тесты из обоих классов. Запустите тесты с помощью TestRunner.

python
import unittest

class TestMathFunctions(unittest.TestCase):

  def test_add(self) -> None:
    self.assertEqual(2 + 3, 5)

  def test_subtract(self) -> None:
    self.assertEqual(5 - 2, 3)

class TestStringManipulations(unittest.TestCase):

  def test_reverse(self) -> None:
    self.assertEqual("hello"[::-1], "olleh")

  def test_length(self) -> None:
    self.assertEqual(len("python"), 6)

def create_combined_suite() -> unittest.TestSuite:
  """Создание комбинированного набора тестов."""
  suite = unittest.TestSuite()
  suite.addTest(unittest.makeSuite(TestMathFunctions))
  suite.addTest(unittest.makeSuite(TestStringManipulations))
  return suite

if __name__ == '__main__':
  runner = unittest.TextTestRunner()
  test_suite = create_combined_suite()
  runner.run(test_suite)

6. Использование setUpClass и tearDownClass

Название: TestDatabaseConnection

Задача: Напишите класс TestDatabaseConnection, который будет тестировать подключение к базе данных. Используйте setUpClass для установки соединения с базой данных (например, создание временной in-memory базы данных) и tearDownClass для закрытия соединения и удаления базы данных. Напишите несколько тестов, которые будут выполнять запросы к базе данных.

python
import unittest
# Для примера будем использовать sqlite3 для in-memory базы данных
import sqlite3

class TestDatabaseConnection(unittest.TestCase):

  @classmethod
  def setUpClass(cls) -> None:
    """Установка соединения с базой данных перед всеми тестами."""
    cls.conn = sqlite3.connect(":memory:")  # Создание in-memory базы данных
    cls.cursor = cls.conn.cursor()
    cls.cursor.execute("CREATE TABLE users (id INT, name TEXT)")

  def test_insert_user(self) -> None:
    """Тестирование вставки пользователя в базу данных."""
    self.cursor.execute("INSERT INTO users VALUES (1, 'John Doe')")
    self.conn.commit()
    self.cursor.execute("SELECT * FROM users WHERE id=1")
    result = self.cursor.fetchone()
    self.assertEqual(result, (1, 'John Doe'))

  def test_select_user(self) -> None:
    """Тестирование выборки пользователя из базы данных."""
    self.cursor.execute("INSERT INTO users VALUES (2, 'Jane Smith')")
    self.conn.commit()
    self.cursor.execute("SELECT * FROM users WHERE name='Jane Smith'")
    result = self.cursor.fetchone()
    self.assertEqual(result, (2, 'Jane Smith'))

  @classmethod
  def tearDownClass(cls) -> None:
    """Закрытие соединения с базой данных после всех тестов."""
    cls.conn.close()

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

Contacts: teffal@mail.ru