Сегодня мы изучим о Python unittest и просмотрим примеры программ тестирования на Python. В предыдущем уроке мы узнали о функции zip в Python.
Python unittest
Модуль unittest в Python используется для тестирования блока исходного кода. Предположим, вам нужно протестировать свой проект. Вы знаете, какие данные функция должна вернуть. После написания большого кода вам нужно проверить, верен ли результат или нет. Обычно мы выводим результат и сравниваем его с эталонным файлом вывода или проверяем результат вручную. Чтобы уменьшить это бремя, в Python введен модуль unittest. С помощью этого модуля вы можете проверить вывод функции с помощью простого кода. В этом учебнике мы обсудим основное использование модуля Python unittest и напишем несколько тестовых случаев для проверки функций класса.
Пример исходного кода Python Unit Test
Сначала нам нужно написать некоторый код для модульного тестирования их. У нас будет класс Python. Основная цель класса – хранить и извлекать имя человека. Таким образом, мы пишем функцию set_name()
для сохранения данных и функцию get_name()
для извлечения имени из класса.
class Person:
name = []
def set_name(self, user_name):
self.name.append(user_name)
return len(self.name) - 1
def get_name(self, user_id):
if user_id >= len(self.name):
return 'There is no such user'
else:
return self.name[user_id]
if __name__ == '__main__':
person = Person()
print('User Abbas has been added with id ', person.set_name('Abbas'))
print('User associated with id 0 is ', person.get_name(0))
Мы назвали файл класса Person.py
. И вывод вышеприведенного кода будет следующим.
$ python3.6 Person.py
User Abbas has been added with id 0
User associated with id 0 is Abbas
$
Структура модуля Python unittest
Теперь давайте узнаем, как писать код для модульного тестирования. Индивидуальный тест-кейс создается путем наследования от unittest.TestCase
. Путем переопределения или добавления соответствующих функций мы можем добавить логику тестирования. Следующий код будет успешным, если a равно b.
import unittest
class Testing(unittest.TestCase):
def test_string(self):
a = 'some'
b = 'some'
self.assertEqual(a, b)
def test_boolean(self):
a = True
b = True
self.assertEqual(a, b)
if __name__ == '__main__':
unittest.main()
Как запустить модуль python unittest
Если вы используете среду разработки PyCharm, вы можете просто нажать ctrl+shift+F10, чтобы запустить модуль unittest. В противном случае вы можете использовать командную строку для запуска этого модуля. Например, мы назвали файл для модульного тестирования как Basic_Test.py
. Таким образом, команда для запуска модуля python unittest будет: $python3.6 -m unittest Basic_Test.Testing
Если вы хотите увидеть подробный вывод, то команда будет; $python3.6 -m unittest -v Basic_Test.Testing
Используя PyCharm, мы получаем следующий вывод.
Результаты модульного тестирования Python и базовые функции
Этот модульный тест имеет 3 возможных результата. Они перечислены ниже:
- OK: Если все тестовые случаи пройдены успешно, вывод показывает OK.
- Ошибка: Если хотя бы один из тестовых случаев не пройден и вызвано исключение AssertionError
- Ошибка: Если возникло исключение, отличное от исключения AssertionError.
Есть несколько функций в модуле unittest. Они перечислены ниже.
Method | Checks that |
---|---|
assertEqual(a,b) | a==b |
assertNotEqual(a,b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a,b) | a is b |
assertIs(a,b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsInstance(a, b) | not isinstance(a, b) |
Пример модульного тестирования в Python
Сейчас пришло время написать юнит-тесты для нашего исходного класса Person
. В этом классе мы реализовали две функции – get_name()
и set_name()
. Теперь мы будем тестировать эти функции, используя unittest
. Мы разработали два тестовых случая для этих функций. Взгляните на следующий код, вам будет легко понять.
import unittest
# Это класс, который мы хотим протестировать. Поэтому нам нужно его импортировать
import Person as PersonClass
class Test(unittest.TestCase):
"""
The basic class that inherits unittest.TestCase
"""
person = PersonClass.Person() # instantiate the Person Class
user_id = [] # variable that stores obtained user_id
user_name = [] # variable that stores person name
# Функция тестового случая для проверки функции Person.set_name
def test_0_set_name(self):
print("Start set_name test\n")
"""
Any method which starts with ``test_`` will considered as a test case.
"""
for i in range(4):
# Инициализация имени
name = 'name' + str(i)
# Сохранение имени в переменной списка
self.user_name.append(name)
# Получение идентификатора пользователя из функции
user_id = self.person.set_name(name)
# Проверка, является ли полученный идентификатор пользователя пустым или нет
self.assertIsNotNone(user_id) # null user id will fail the test
# Сохранение идентификатора пользователя в список
self.user_id.append(user_id)
print("user_id length = ", len(self.user_id))
print(self.user_id)
print("user_name length = ", len(self.user_name))
print(self.user_name)
print("\nFinish set_name test\n")
# Функция тестового случая для проверки функции Person.get_name
def test_1_get_name(self):
print("\nStart get_name test\n")
"""
Any method that starts with ``test_`` will be considered as a test case.
"""
length = len(self.user_id) # total number of stored user information
print("user_id length = ", length)
print("user_name length = ", len(self.user_name))
for i in range(6):
# Если длина не превышает общую длину, то проверяем возвращенное имя
if i < length:
# Если два имени не совпадают, тест не пройден
self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
else:
print("Testing for get_name no user test")
# Если длина превышает, то проверяем сообщение типа 'нет такого пользователя'
self.assertEqual('There is no such user', self.person.get_name(i))
print("\nFinish get_name test\n")
if __name__ == '__main__':
# Запуск unittest.main()
unittest.main()
Обратите внимание, что модуль unittest выполняет тестовые функции в порядке их имен, а не в порядке их определения. И так как мы хотим, чтобы наш тест set_name выполнился первым, мы назвали наши тестовые функции как test_0_set_name
и test_1_get_name
.
Пример вывода модульного теста Python
Ниже приведены изображения, демонстрирующие вывод, созданный нашей программой модульного тестирования – как в обычном режиме, так и в подробном режиме.
$ python3.6 -m unittest -v PersonTest.Test
test_0_set_name (PersonTest.Test) ... Start set_name test
user_id length = 4
[0, 1, 2, 3]
user_name length = 4
['name0', 'name1', 'name2', 'name3']
Finish set_name test
ok
test_1_get_name (PersonTest.Test) ...
Start get_name test
user_id length = 4
user_name length = 4
Testing for get_name no user test
Testing for get_name no user test
Finish get_name test
ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
$
Это все, что касается руководства по модульному тестированию Python. Чтобы узнать больше, прочтите Официальную документацию. По любым дополнительным вопросам используйте форму комментариев. 🙂
Source:
https://www.digitalocean.com/community/tutorials/python-unittest-unit-test-example