Как использовать параметры тестов в `pytest`?

В pytest параметры тестов используются с помощью декоратора @pytest.mark.parametrize. Этот декоратор позволяет запускать один и тот же тест несколько раз, передавая ему разные наборы параметров. Он принимает два основных аргумента:
  • argnames: Строка с именами параметров, разделёнными запятыми, или список имён параметров.
  • argvalues: Список или кортеж значений для параметров. Каждый элемент в списке/кортеже соответствует одному набору параметров. Значения передаются в тест в соответствии с порядком имён параметров.
Пример: @pytest.mark.parametrize("input,expected", [(1, 2), (3, 4), (5, 6)]) В этом примере тест будет запущен трижды, сначала с input=1 и expected=2, затем с input=3 и expected=4, и наконец с input=5 и expected=6.

В pytest параметры тестов (parametrization) позволяют запускать один и тот же тестовый код с разными входными данными. Это особенно полезно для тестирования различных сценариев, граничных случаев или для обеспечения покрытия кода с разными наборами значений.

Основной способ параметризации в pytest – использование декоратора @pytest.mark.parametrize.

Синтаксис:

@pytest.mark.parametrize("argnames", argvalues)

Где:

  • argnames: строка или список строк, содержащий имена параметров, которые будут переданы в тестовую функцию. Если параметров несколько, их нужно указать через запятую (например, "input, expected").
  • argvalues: список значений (или кортежей значений, если параметров несколько) для каждого набора тестов. Каждый элемент списка argvalues будет использован как набор входных данных для одного запуска тестовой функции.

Пример:


 import pytest

 def add(x, y):
  return x + y

 @pytest.mark.parametrize("x, y, expected", [
  (1, 2, 3),
  (5, 5, 10),
  (0, -1, -1),
  (-1, -1, -2),
 ])
 def test_add(x, y, expected):
  assert add(x, y) == expected
  

В этом примере функция test_add будет запущена четыре раза. Каждый раз x, y и expected будут принимать значения из соответствующего кортежа в списке argvalues. Таким образом, тест проверяет, что функция add правильно складывает различные числа.

Другие возможности:

  • ids: Можно добавить параметр ids в @pytest.mark.parametrize, чтобы задать имена для каждого набора тестов. Это облегчает понимание результатов тестирования.
  • 
     @pytest.mark.parametrize("x, y, expected", [
      (1, 2, 3),
      (5, 5, 10),
     ], ids=["positive_numbers", "equal_numbers"])
     def test_add(x, y, expected):
      assert add(x, y) == expected
         
  • Маркировка параметризованных тестов: Можно применять маркеры к отдельным наборам параметров.
  • 
     import pytest
    
     def divide(x, y):
      return x / y
    
     @pytest.mark.parametrize(
      "x, y, expected",
      [
       (10, 2, 5),
       pytest.param(10, 0, float('inf'), marks=pytest.mark.xfail(reason="Division by zero")),
      ],
     )
     def test_divide(x, y, expected):
      assert divide(x, y) == expected
         
    В этом примере тест с делением на ноль помечен как xfail, чтобы указать, что ожидается сбой.
  • Параметризация с помощью функций: Вместо непосредственного указания значений в argvalues можно использовать функцию, которая будет генерировать эти значения. Это полезно для сложных случаев, когда требуется динамически создавать наборы входных данных.

Преимущества использования параметризации:

  • Сокращение дублирования кода: Избегаем написания нескольких похожих тестов.
  • Улучшение читаемости тестов: Параметры явно отображаются в тестовом коде.
  • Более полное покрытие тестами: Легко проверить различные сценарии с разными входными данными.

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

0