Hopp til innhold

Юнит-тестирование и валидация

Skip to content

Это машинный перевод текста, который может содержать ошибки!

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

Но как мы можем быть уверены, что код работает должным образом, если не тестируем его?

Что такое модульное тестирование (Unit Testing)?

Модульное тестирование — это метод автоматического и систематического тестирования небольших частей нашего кода. В Python мы используем модуль с именем pytest для написания и запуска тестов. «Единица» (unit) — это наименьшая тестируемая часть приложения, часто отдельная функция или метод. При использовании pytest важно соблюдать правильные соглашения об именах, чтобы pytest мог найти наши тесты, например, называть файлы тестов с префиксом test_, а функции тестов — также с префиксом test_.

Пример модульного теста:

def test_add():
    assert 0.3 + 0.3 + 0.3 == 0.9

Запускается вводом команды pytest в терминале.

Интересный факт

Код выше даст ошибку, потому что в Python выражение .3+.3+.3 равно 0.8999999999!

Easy Задание 1 — Установка pytest

Установите pytest в вашей виртуальной среде. Для этого выполните следующую команду в терминале:

pip install pytest

Easy Задача 2 — Напишите тест

Создайте новый файл в папке вашего проекта с именем test_data.py. В этом файле вам нужно написать тест для класса Person, который вы создали в предыдущем модуле. Тест должен проверять, что объект Person может быть создан со значениями, которые соответствуют требованиям к корректности данных (valid values).

Пример того, как может выглядеть этот тест:

from main import Person

def test_person_working():
    bob_kaare = Person(name="Bob Kåre",
                       eye_color=EyeColor.BLUE,
                       phone_number=PhoneNumber("12345678"),
                       email=Email("bob_kaare@example.com"))
    assert bob_kaare.name == "Bob Kåre"
    assert bob_kaare.eye_color == EyeColor.BLUE

Этот тип тестирования называется «happy path» (проверка сценария успешного выполнения), поскольку мы проверяем, что всё работает должным образом при вводе корректных значений, и он не особенно полезен.

Medium Задача 3 — Тестирование валидации

Создайте несколько тестов в test_person.py, которые проверяют корректность работы валидации в Email и PhoneNumber. Протестируйте как допустимые, так и недопустимые значения. Здесь необходимо использовать функцию pytest под названием raises, которая проверяет выброс определенной ошибки.

import pytest

def test_exception():
    with pytest.raises(KeyError):
        my_dict = {"a": 1, "b": 2}
        value = my_dict["c"]  # Это вызовет исключение KeyError

Tip

Вы можете создавать столько функций, сколько хотите, при условии что имя функции начинается с test_.

Решение: Пример теста для недействительного электронного адреса
from main import Email

import pytest

def test_invalid_email():
    with pytest.raises(ValueError):
        email = Email("not-an-email")

Зачем это нужно?

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

Видео: Почему тесты защищают код от новых ошибок

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

Используя, например, программное обеспечение такое как Jest или Selenium, можно автоматически тестировать веб-сайты, обеспечивая тем самым корректную работу всех компонентов после каждого изменения кода. Мы ведь хотим знать, что «регистрация пользователей», «оплата» и «авторизация» работают должным образом, верно?

Подумайте над следующими сценариями

Что происходит (или должно произойти), если..:

  • Пользователь пытается зарегистрироваться по электронной почте, которая уже используется?
  • У пользователя дата рождения в будущем?
  • Пользователь вводит имя «jOHN dOE»?

A software tester walks into a bar...

Hard Задание 4 - Автоматическое тестирование (CI)

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

Создайте файл с именем .github/workflows/pytest.yml в папке вашего проекта. В этот файл добавьте следующий код:

name: Pytest

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.11'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install pytest
        # Установите любые другие зависимости, необходимые вашему проекту
        pip install -r requirements.txt
    - name: Run tests with pytest
      run: pytest

Если вы правильно его добавили, теперь у вас в репозитории GitHub появится новая вкладка с названием «Actions». Здесь вы сможете видеть, как ваши тесты автоматически запускаются каждый раз при внесении изменений в код, а также получать уведомления о том, если какой-либо из тестов завершится ошибкой (красный крестик и по электронной почте).

Примечание о структуре файлов

Структура ваших файлов определит будет ли работать GitHub Actions или нет. Убедитесь, что папка .github находится в корневой директории вашего проекта, а также существует папка tests, где расположены ваши файлы тестов.

При необходимости вы можете изменить файл pytest.yml, чтобы указать правильную директорию.

Файлы с действиями (Actions) также можно использовать для тестирования вашего кода на нескольких версиях Python или операционных системах; они также позволяют автоматически собирать и публиковать ваше программное обеспечение, например, размещать веб-сайт или обновлять приложение в App Store или Google Play.

Покрытие кода

Существует также такое понятие, как «покрытие кода» (code coverage), которое помогает понять, какая часть вашего кода фактически тестируется. Это может быть полезно для определения того, достаточно ли у вас тестов или есть ли части кода, которые вообще не покрыты тестами.

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

Мем про модульное тестирование