Рубрики
Без рубрики

Простое введение в тестовое развитие с помощью Python

Автор оригинала: FreeCodeCapm Team.

Дмитрий Расторгуев

Я являюсь самоучкой, начинающим разработчик, который может написать простые приложения. Но у меня есть признание, чтобы сделать. Невозможно вспомнить, как все взаимосвязано в моей голове.

Эта ситуация усугубляется, если я вернусь в код, который я написал через несколько дней. Оказывается, эта проблема может быть преодолена, следуя Тестовое развитие (TDD) Методология.

Что такое TDD и почему это важно?

В терминах Layman TDD рекомендует написание тестов, которые проверят функционал вашего кода до вашего письма фактического кода. Только когда вы довольны своими тестами и функциями, которые он проверяет, вы начинаете писать фактический код, чтобы удовлетворить условия, налагаемые тестом, который позволил бы им пройти.

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

Испытания также дают вам уверенность, когда вы начинаете рефакторист, так как вы более склонны к ошибкам из-за мгновенной обратной связи при выполнении тестов.

С чего начать?

Чтобы начать писать тесты в Python, мы будем использовать Неизвестный модуль Это поставляется с Python. Для этого мы создаем новый файл Mytests.py , который будет содержать все наши тесты.

Начнем с обычного «Hello World»:

import unittestfrom mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):        self.assertEqual(hello_world(), 'hello world')

Обратите внимание, что мы импортируем helloworld () Функция от MyCode файл. В файле mycode.py Первоначально мы просто включаем код ниже, который создает функцию, но не возвращает ничего на этом этапе:

def hello_world():    pass

Бег Python Mytests.py будет генерировать следующий вывод в командной строке:

F
====================================================================
FAIL: test_hello (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 7, in test_hello
self.assertEqual(hello_world(), 'hello world')
AssertionError: None != 'hello world'
--------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)

Это ясно указывает на то, что тест не удался, который ожидался. К счастью, мы уже написали тесты, поэтому мы знаем, что он всегда будет там, чтобы проверить эту функцию, которая дает нам уверенность в потенциальных ошибках в будущем.

Чтобы убедиться, что код пропускается, давайте изменим mycode.py к следующему:

def hello_world():    return 'hello world'

Бег Python Mytests.py Снова мы получаем следующий вывод в командной строке:

.
--------------------------------------------------------------------
Ran 1 test in 0.000s
OK

Поздравляю! Вы только что написали свой первый тест. Давайте теперь перейдем к немного сложнее. Мы создадим функцию, которая позволила бы нам создать пользовательский числовой Понимание списка в питоне.

Начнем с написания теста на функцию, которая создаст список определенной длины.

В файле Mytests.py Это будет метод test_custom_num_list :

import unittestfrom mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):        self.assertEqual(hello_world(), 'hello world')        def test_custom_num_list(self):        self.assertEqual(len(create_num_list(10)), 10)

Это проверит, что функция create_num_list Возвращает список длины 10. Давайте создадим функцию create_num_list в mycode.py :

def hello_world():    return 'hello world'
def create_num_list(length):    pass

Бег Python Mytests.py будет генерировать следующий вывод в командной строке:

E.
====================================================================
ERROR: test_custom_num_list (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 14, in test_custom_num_list
self.assertEqual(len(create_num_list(10)), 10)
TypeError: object of type 'NoneType' has no len()
--------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (errors=1)

Это как ожидалось, так давайте пойдем вперед и измените функцию create_num_list в mytest.py Для того, чтобы пройти тест:

def hello_world():    return 'hello world'
def create_num_list(length):    return [x for x in range(length)]

Выполнение Python Mytests.py На командной строке демонстрирует, что второй тест также прошел:

..
--------------------------------------------------------------------
Ran 2 tests in 0.000s
OK

Давайте теперь создадим пользовательскую функцию, которая преобразует каждое значение в списке, как это: const * (x) ^ power Отказ Сначала давайте напишем тест на это, используя метод test_custom_func_ Это будет принимать значение 3, как X, возьмите его до мощности 3 и умножить на постоянную 2, что привело к значению 54:

import unittestfrom mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):        self.assertEqual(hello_world(), 'hello world')
def test_custom_num_list(self):        self.assertEqual(len(create_num_list(10)), 10)        def test_custom_func_x(self):        self.assertEqual(custom_func_x(3,2,3), 54)

Давайте создадим функцию custom_func_x В файле mycode.py :

def hello_world():    return 'hello world'
def create_num_list(length):    return [x for x in range(length)]
def custom_func_x(x, const, power):    pass

Как и ожидалось, мы получим неудачу:

F..
====================================================================
FAIL: test_custom_func_x (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 17, in test_custom_func_x
self.assertEqual(custom_func_x(3,2,3), 54)
AssertionError: None != 54
--------------------------------------------------------------------
Ran 3 tests in 0.000s
FAILED (failures=1)

Обновление функции custom_func_x Чтобы пройти тест, у нас есть следующее:

def hello_world():    return 'hello world'
def create_num_list(length):    return [x for x in range(length)]
def custom_func_x(x, const, power):    return const * (x) ** power

Запустив тесты снова, мы получаем пропуск:

...
--------------------------------------------------------------------
Ran 3 tests in 0.000s
OK

Наконец, давайте создадим новую функцию, которая будет включать custom_func_x функция в списке понимание. Как обычно, давайте начнем с написания теста. Обратите внимание, что просто наверняка, мы включаем два разных случая:

import unittestfrom mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):        self.assertEqual(hello_world(), 'hello world')
def test_custom_num_list(self):        self.assertEqual(len(create_num_list(10)), 10)
def test_custom_func_x(self):        self.assertEqual(custom_func_x(3,2,3), 54)
def test_custom_non_lin_num_list(self):        self.assertEqual(custom_non_lin_num_list(5,2,3)[2], 16)        self.assertEqual(custom_non_lin_num_list(5,3,2)[4], 48)

Теперь давайте создадим функцию custom_non_lin_num_list в mycode.py :

def hello_world():    return 'hello world'
def create_num_list(length):    return [x for x in range(length)]
def custom_func_x(x, const, power):    return const * (x) ** power
def custom_non_lin_num_list(length, const, power):    pass

Как и прежде, мы получим неудачу:

.E..
====================================================================
ERROR: test_custom_non_lin_num_list (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 20, in test_custom_non_lin_num_list
self.assertEqual(custom_non_lin_num_list(5,2,3)[2], 16)
TypeError: 'NoneType' object has no attribute '__getitem__'
--------------------------------------------------------------------
Ran 4 tests in 0.000s
FAILED (errors=1)

Для того, чтобы пройти тест, давайте обновим mycode.py Файл к следующему:

def hello_world():    return 'hello world'
def create_num_list(length):    return [x for x in range(length)]
def custom_func_x(x, const, power):    return const * (x) ** power
def custom_non_lin_num_list(length, const, power):    return [custom_func_x(x, const, power) for x in range(length)]

Продолжая тесты на последнее время, проезжаем все они!

....
--------------------------------------------------------------------
Ran 4 tests in 0.000s
OK

Поздравляю! Это завершает это введение в тестирование в Python. Убедитесь, что вы проверяете ресурсы ниже для получения дополнительной информации о тестировании в целом.

Код доступен здесь на Github Отказ

Полезные ресурсы для дальнейшего обучения!

Веб-ресурсы

Ниже приведены ссылки на некоторые из библиотек, ориентирующихся на тестирование в Python

25.3. Unittest – Framework для тестирования подразделений – Python 2.7.14 Документация Конструкция тестирования блока Python, иногда называемая «Pyunit», – это версия языковой формы Python Junit, Кент … docs.ython.org Pytest: поможет вам написать лучшие программы – Pтойская документация Рамка позволяет легко написать небольшие тесты, кроме весов для поддержки сложных функциональных испытаний для приложений и … docs.pytest.org Добро пожаловать в гипотезу! – Гипотеза 3.45.2 Документация Он работает, создавая случайные данные, соответствующие вашу спецификацию и проверяя, что ваша гарантия все еще держит в этом … HYPOTHESESES.READTHEDOCS.IO Unittest2 1.1.0: Указатель пакета Python Новые функции в Unittest Backported в Python 2.4+. pypi.python.org.

YouTube видео

Если вы предпочитаете не читать, я рекомендую смотреть следующие видео на YouTube.