Мануальное тестирование в Django

Лавина изменений в коде

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

Выход один: досконально проверять проект после каждого обновления, каждый раз убеждаясь, что всё работает, как ожидалось. Вы уже делали это: каждый раз перед ревью вы проверяли работоспособность проекта. Сдаётся мне, джентльмены, это было тестирование!

Сценарии тестирования

Тестирование — это отдельная профессия. Специально обученные люди-тестировщики проигрывают все возможные сценарии поведения программы и пользователя и ищут ошибки в работе проекта. Ручная проверка называется мануальное тестирование (от англ. manual: «ручное»).

Вот простейший сценарий тестирования формы авторизации:

  • пользователь вводит правильный логин и пароль и входит на сайт;
  • пользователь вводит неправильный логин и пароль, получает отказ и видит приглашение восстановить пароль;
  • пользователь вводит правильный email в форму восстановления доступа и получает письмо со ссылкой на форму изменения пароля;
  • пользователь вводит неправильный email в форму восстановления доступа и получает сообщение «такой email не найден».

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

По итогам работы тестировщик составляет отчёт (test-report), в котором описывает, какие случаи проверены. Это увлекательная работа, сродни рыбалке или исследованию лабиринтов; но она требует усидчивости и аккуратности.

Тестирование через пользовательский интерфейс

В прошлом спринте вы сделали форму для публикации поста. Протестируйте её. Запустите локально проект Yatube.

  1. Выйдите из учётной записи, если вы были авторизованы. Зайдите на страницу http://127.0.0.1:8000/create/.
    Ожидаемое поведение: при попытке входа на страницу http://127.0.0.1:8000/create/ неавторизованный пользователь перенаправлен на страницу авторизации http://127.0.0.1:8000/auth/login/?next=/create/.

Тестирование кода

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

def movie_quotes(name):
    """Возвращает цитаты известных персонажей из фильмов."""
    quotes = {
        'Элли': 'Тото, у меня такое ощущение, что мы не в Канзасе!',
        'Шерлок': 'Элементарно, Ватсон!',
        'Дарт Вейдер': 'Я — твой отец.',
        'Thomas A. Anderson': 'Меня. Зовут. Нео!',
    }
    # Метод словаря get() возвращает значение для указанного ключа.
    # Если запрошенный ключ не найден — get() вернёт значение,
    # указанное вторым аргументом.
    return quotes.get(name, 'Персонаж пока не известен миллионам.') 

Варианты вызова и ожидаемые результаты:

print(movie_quotes('Элли'))
# Ожидаемый результат: 'Тото, у меня такое ощущение, что мы не в Канзасе!'

print(movie_quotes('Шерлок'))
# Ожидаемый результат: 'Элементарно, Ватсон!'

print(movie_quotes('Дарт Вейдер'))
# Ожидаемый результат: 'Я — твой отец.'

print(movie_quotes('Леонид Тощев'))
# Ожидаемый результат: 'Персонаж пока не известен миллионам.' 

Отлично, вы опять провели мануальное тестирование.Oops, I do it again! В своё время это случается с каждым разработчиком.

Чтобы не заставлять других разработчиков вызывать функцию и сравнивать результаты с ожидаемыми, результаты мануального тестирования можно сохранить в Docstring.

Документируй это: Docstring и Doctest

Docstring — это строковая переменная, которую размещают сразу за объявлением модуля, функции, класса или метода. Docstring принято обрамлять в три пары двойных кавычек (РЕР257). Доступ к этой переменной можно получить так: имя_функции.__doc__.

В docstring кратко описывают объект, к которому относится эта переменная. В ней же при необходимости сохраняют результаты проведённых тестов.

Сохраните код из листинга в файл расширением .py.

def movie_quotes(name):
    """Возвращает цитаты известных персонажей из фильмов

    >>> movie_quotes('Элли')
    'Тото, у меня такое ощущение, что мы не в Канзасе!'

    >>> movie_quotes('Шерлок')
    'Элементарно, Ватсон!'

    >>> movie_quotes('Дарт Вейдер')
    'Люк, я — твой отец.'

    >>> movie_quotes('Леонид Тощев')
    'Персонаж пока не известен миллионам.'
    """
    quotes = {
        'Элли': 'Тото, у меня такое ощущение, что мы не в Канзасе!',
        'Шерлок': 'Элементарно, Ватсон!',
        'Дарт Вейдер': 'Люк, я — твой отец.',
    }
    return quotes.get(name, 'Персонаж пока не известен миллионам.') 

В docstring функции добавлено описание результатов проведённого тестирования.Посмотрите на эти смешные ёлочки >>>: они тут не просто так. В Python есть стандартная библиотека doctest; при запуске она ищет в docstring эти ёлочки и исполняет инструкции, следующие за ними; затем doctest сравнивает полученный результат с ожидаемым, указанным на следующей за инструкцией строке в docstring.

Теперь код под контролем: можно без опасений редактировать, расширять или рефакторить функцию, и если в результате изменений она перестанет возвращать ожидаемые результаты — разработчик немедленно узнает об этом. И не нужно будет заново вручную тестировать функцию и сверять полученные результаты с ожидаемыми.

Запустите doctest для файла с функцией movie_quotes(): выполните команду python3 -m doctest <название файла.py> из директории с вашим файлом.

Можно настроить и автоматический запуск тестирования: нужно импортировать doctest в код и добавить вызов теста.

# Код с докстрингами
...
if __name__ == '__main__':
    import doctest
    doctest.testmod() 

Теперь doctest будет запускаться автоматически при выполнении файла.

python3 <название файла.py>
# Сначала будет выполнен doctest, а затем - код файла 

Если команда выполнена, но ничего не произошло — значит, все работает правильно, результаты теста, сохранённые в docstring, подтверждены.Сломайте код (например, измените географию) и заново запустите doctest.В консоли появится сообщение об ошибке:

<адрес и имя файла>line 6, in tmp.movie_quotes
Failed example:
    movie_quotes('Элли')
Expected:
    'Тото, у меня такое ощущение, что мы не в Канзасе!'
Got:
    'Тото , у меня такое ощущение, что мы не в Симбирске!'
**********************************************************************
1 items had failures:
   1 of   4 in tmp.movie_quotes
***Test Failed*** 1 failures. 

Doctest обнаружил расхождение с ожидаемым результатом и указал на него.Это самый простой способ работы с doctest. Но этот пакет способен на большее; все его возможности описаны в документации: https://docs.python.org/3/library/doctest.html.

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





Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: