Поиск по сайту:

Python unittest — пример модульного теста


Сегодня мы узнаем о модульном тестировании Python и рассмотрим примеры программ модульного тестирования Python. В предыдущем уроке мы узнали о функции zip в Python.

модульный тест Python

Модуль Python unittest используется для тестирования единицы исходного кода. Предположим, вам нужно протестировать свой проект. Вы знаете, какие данные вернет функция. После написания огромного кода вам нужно проверить его правильность вывода или нет. Обычно мы печатаем вывод и сопоставляем его с эталонным выходным файлом или проверяем вывод вручную. Чтобы уменьшить эту боль, Python представил модуль unittest. Используя этот модуль, вы можете проверить вывод функции с помощью простого кода. В этом руководстве мы обсудим базовое использование модуля модульного тестирования Python и напишем несколько тестовых примеров Python для тестирования функций класса.

Источник примера модульного теста Python

Прежде всего, нам нужно написать код для их модульного тестирования. У нас будет класс 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.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

Результат модульного теста Python и основные функции

Этот юнит-тест имеет 3 возможных результата. Они упомянуты ниже:

  1. ОК. Если все тестовые примеры пройдены, вывод показывает ОК.
  2. Ошибка: если какой-либо из тестовых случаев завершился неудачей и вызвал исключение AssertionError
  3. Ошибка: возникает любое исключение, кроме исключения 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

# This is the class we want to test. So, we need to import it
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

    # test case function to check the Person.set_name function
    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):
            # initialize a name
            name = 'name' + str(i)
            # store the name into the list variable
            self.user_name.append(name)
            # get the user id obtained from the function
            user_id = self.person.set_name(name)
            # check if the obtained user id is null or not
            self.assertIsNotNone(user_id)  # null user id will fail the test
            # store the user id to the list
            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")

    # test case function to check the Person.get_name function
    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 not exceed total length then verify the returned name
            if i < length:
                # if the two name not matches it will fail the test case
                self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
            else:
                print("Testing for get_name no user test")
                # if length exceeds then check the 'no such user' type message
                self.assertEqual('There is no such user', self.person.get_name(i))
        print("\nFinish get_name test\n")


if __name__ == '__main__':
    # begin the 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. Чтобы узнать больше, прочитайте официальную документацию. Для любого дальнейшего запроса, пожалуйста, используйте поле для комментариев. :)