Автор оригинала: Pankaj Kumar.
В этой статье мы рассмотрим модуль Python unittest и некоторые из его распространенных вариантов использования.
Но прежде давайте разберемся, зачем нам вообще нужен этот модуль.
Почему вы должны использовать модуль unittest?
Когда вы работаете с большими базами кода, разработка приложений часто подразделяется на два этапа.
- Этап разработки
- Фаза тестирования
Фаза 1-это ваша фаза разработки , на которой вы создаете свою основную идею в приложение с голыми костями.
Но этого недостаточно, если вы действительно хотите использовать его регулярно. Возможно, были ситуации, которые вы, возможно, пропустили, что на самом деле может привести к неожиданной работе вашей программы.
Чтобы свести к минимуму такие ошибки, существует еще одна фаза , называемая Фазой тестирования , которая направлена на тестирование различных возможных сценариев для вашего приложения и проверку его правильной работы.
Часто, если у вас нет установленной структуры для этого этапа, вам может потребоваться проверить все сценарии вручную, что утомительно.
Чтобы уменьшить хлопоты разработчика, мы можем использовать модуль Python unittest
и решить именно эту проблему с помощью автоматического тестирования.
Виды тестирования
Для приложения существует два типа тестов:
- Интегрированные тесты
- Модульные тесты
Интегрированные тесты – это те тесты, которые проверяют, правильно ли работают модули приложения друг с другом.
Модульные тесты – это те, которые проверяют небольшие компоненты в приложении.
Хотя мы можем писать как интеграционные тесты, так и модульные тесты, интеграционные тесты сильно зависят от вашего приложения и могут объединять несколько модульных тестов.
Учитывая все это, давайте теперь посмотрим, как мы можем использовать этот модуль!
Модуль Python unittest
Этот модуль встроен в вашу установку Python 3+ , поэтому нет необходимости устанавливать его с помощью pip .
Вы можете импортировать модуль, введя:
import unittest
Методы Python unittest
Этот модуль имеет несколько методов, с помощью которых вы можете выполнять модульные тесты.
Наиболее распространенные из них перечислены в таблице ниже.
Метод | Проверка утверждений |
assertEqual(a,b) | a |
assertNotEqual(a,b) | a |
assertTrue(x) | bool(x) истинно |
assertFalse(x) | bool(x) является ложным |
assert Is(a,b) | a – это b |
утверждение Не Является(a, b) | а-это не бытие |
assertIsNone(x) | x – это Нет |
assertIsNotNone(x) | x-это не ничто |
утверждение(a, b) | a в b |
assertNotIn(a, b) | а не в б |
assert IsInstance(a, b) | isinstance(a, b) |
утверждать не IsInstance(a, b) | не isinstance(a, b) |
Написание модульного теста
Нам нужна программа для применения тестов. Так что давайте напишем его!
Я напишу программу, которая просто попытается проверить сумму элементов в списке. Для этого мы напишем модульный тест программу.
Как, чтобы написать отдельный тестовый случай, нам нужно унаследовать unittest.TestCase
class, а затем переопределить его с помощью некоторых конкретных методов.
Я буду называть свой класс MyTestClass
.
import unittest def list_sum(my_list): # Sums the elements of the list return sum(my_list) class MyTestClass(unittest.TestCase): def test_list(self): # Checks if the sum of the below list is as expected my_list = [1, 2, 3, 4, 5] self.assertEqual(list_sum(my_list), 15, "Should be 15") def test_string(self): # Checks if the string is 'Hello from AskPython' my_str = 'Hi' self.assertEqual(my_str, 'Hello from AskPython', "Should be 'Hello from AskPython'") if __name__ == '__main__': # Main module unittest.main()
ПРИМЕЧАНИЕ : Чтобы написать метод тестирования, мы должны префикс имени метода с test_
. Таким образом, любой метод тестирования должен иметь вид test_xyz()
Я пишу метод test_list ()
, который проверяет, равна ли сумма элементов в списке 15, и аналогично другой метод для проверки данной строки.
Я использую метод unittest ‘s assertEqual ()
, который запустит модульный тест и проверит, выполняется ли это утверждение.
Теперь давайте выполним этот файл с помощью Python.
user@AskPython $ python my_test.py .F ====================================================================== FAIL: test_string (__main__.MyTestClass) ---------------------------------------------------------------------- Traceback (most recent call last): File "my_test.py", line 16, in test_string self.assertEqual(my_str, 'Hello from AskPython', "Should be 'Hello from AskPython'") AssertionError: 'Hi' != 'Hello from AskPython' - Hi + Hello from AskPython : Should be 'Hello from AskPython' ---------------------------------------------------------------------- Ran 2 tests in 0.000s FAILED (failures=1)
Как видите, первый тест прошел, а второй провалился, так как строки не совпадают.
Теперь вы написали свой первый метод модульного тестирования!
Запуск модульных тестов в приложении
Теперь давайте запустим unittests в другой программе, так как вы не будете писать все свое приложение в файле unittest!
Давайте напишем простую прикладную программу и проведем на ней модульные тесты.
Я буду писать программу, которая действует как очень простая база данных для хранения имен и отметок студентов.
Сохраните приведенный ниже файл как test_example.py
как мы будем ссылаться на него в нашем следующем фрагменте кода.
class MyClass: # Database of {'Name': 'Marks'} dict pairs db = dict() num_students = 0 def add_db(self, name, marks): self.db[name] = marks self.num_students += 1 def rm_db(self, name): # Removes key value pair corresponding # to student name if name in self.db: del self.db[name] else: return f'Student with Name:{name} not in Database' def get_marks(self, name): if name in self.db: return self.db[name] else: return f'Student with Name:{name} not in Database' if __name__ == '__main__': my_class = MyClass() my_class.add_db('John', 47) my_class.add_db('Mary', 34) print(my_class.get_marks('John'))
Рекомендуемый метод выполнения модульных тестов
Это обычная практика, чтобы держать модули тестирования отдельно от основного приложения.
Поэтому мы будем импортировать unittest
модуль только на этапе тестирования .
Python позволяет нам сделать это, указав параметр -m MODULE_NAME
. Итак, наша команда будет:
python -m unittest -v my_test.py
Мы будем использовать опцию -v
verbose для отображения всех полезных сообщений.
Теперь вам не нужно писать import unittest
в вашем приложении!
Чтобы запустить модульные тесты, мы должны написать тестовый файл для нашей программы, аналогичный тому, который мы делали раньше. Мы также импортируем Мой класс
, который мы создали ранее, сославшись на файл test_example.py
что мы спасли раньше.
import unittest from test_example import MyClass import random class MyTest(unittest.TestCase): # Init the MyClass class my_class = MyClass() # Database to verify test cases database = dict() def test_case_1(self): print("\n\nRunning Test 1....\n\n") name = 'John Doe' marks = 50 self.database[name] = marks self.my_class.add_db(name, marks) self.assertEqual(self.database, self.my_class.db) print(self.database) print("\n\nFinished Test 1\n\n") def test_case_2(self): print("\n\nRunning Test 2....\n\n") for i in range(5): name = '' for j in range(6): name += chr(random.randint(97, 97+25)) marks = random.randint(0, 100) self.database[name] = marks # Insert to MyClass Database self.my_class.add_db(name, marks) # Now check if both databases have the same key:value pairs self.assertEqual(self.database, self.my_class.db) print(self.database) print("\n\nFinished Test 2\n\n") if __name__ == '__main__': # Run the main unittest code unittest.main()
Теперь, когда мы написали тесты отдельно, давайте проверим, работает ли это.
python -m unittest run_tests.py
Это действительно работает, так как оба наших теста прошли!
Обратите внимание, что наша окончательная тестовая база данных содержит записи как из Test1, так и из Test2, поэтому можно манипулировать механизмом тестирования на основе вашей программы!
Вывод
Надеюсь, теперь вы понимаете, как можно использовать модуль Python unittest
для проверки работоспособности на этапе тестирования. Если у вас есть какие-либо вопросы, пожалуйста, упомяните их в разделе комментариев ниже!
Рекомендации
- Статья JournalDev о модуле Python unittest
- Настоящая статья на Python на Python unittest