Pytest эквивалент тестов на основе/производных классов в стиле unittest

Вопрос или проблема

У меня есть старый набор тестов на Python, который использует класс-based подход unittest для тестирования, и я пытаюсь преобразовать его так, чтобы использовать pytest. Пример этого показан ниже, где определяется базовый класс с обобщенными тестами, а затем производные классы устанавливают атрибуты класса, которые используются тестами. Это довольно большие классы с множеством тестов и множеством атрибутов класса, которые управляют тестами производных классов. Мои основные вопросы следующие:

1.) Следует ли вообще использовать классы с pytest?

2.) Существует ли определенный шаблон для этого? т.е. “Когда вы видите базовые/производные тесты, подумайте о таком подходе в pytest”

class Base:
  val_1 = None
  val_2 = None
  val_3 = None
  val_4 = 5
  val_5 = 0

  def test_1(self):
  def test_2(self):


class Test1(Base):
  val_1 = 1
  val_2 = 2
  val_3 = 3

class Test2(Base):
  val_1 = 2
  val_2 = 3
  val_3 = 4

class Base2(Base):
  val_4 = 0
  val_5 = 0

  def test_3(self):
  def test_4(self):

class Test3(Base2):
  val_1 = 1
  val_2 = 2
  val_3 = 3

Ответ или решение

Конвертация тестов из unittest в pytest может потребовать изменения подхода к их организации. Вопросы, которые вы задаете, важны для понимания best practices при использовании pytest. Давайте рассмотрим их по порядку.

1.) Следует ли использовать классы в pytest?

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

2.) Какова лучшая практика для организации базовых и производных тестов в pytest?

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

Ниже приведен пример, который иллюстрирует подход к переписыванию ваших тестов с использованием pytest и параметризации:

import pytest

@pytest.mark.parametrize("val_1, val_2, val_3, val_4, val_5", [
    (1, 2, 3, 5, 0),  # Test1
    (2, 3, 4, 5, 0),  # Test2
    (1, 2, 3, 0, 0),  # Test3 with Base2
])
def test_example(val_1, val_2, val_3, val_4, val_5):
    # Здесь вы можете добавить логику теста, например:
    assert val_1 + val_2 + val_3 == val_4 + val_5  # Пример тестового условия

# Пример использования дополнительной фикстуры, если требуется:
@pytest.fixture(params=[1, 2])
def setup_val(request):
    return request.param

def test_with_fixture(setup_val):
    # Логика теста с использованием фикстуры
    assert setup_val in [1, 2]

Заключение

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

Желаю удачи в перенастройке вашего тестового набора на pytest!

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

Капча загружается...