Цю фічу вони підрізали у стдлібного unittest. Але навіщо, якщо у pytest є такий зручний маркер parametrize?
Бо parametrize корисний лише коли дані для теста відомі ще до того як тест почався, якщо ж щоб отримати ці дані треба спочатку зробити виклик у апі, чи у БД, то зробити це через paramtrize не вийде.
Я часто на ці обмеження натикався і або тягнув якийсь сторонній плагін який реалізовував схожу функціональність, або, що частіше, просто доводилось писати декілька однотипних тестів.
Приклад:
def test_math(subtests):
for a, b, result in [(1, 2, 3), (2, 2, 4), (5, 5, 11)]:
with subtests.test(msg=f"{a}+{b}"):
assert a + b == result
Тепер якщо один підкейс падає — весь тест не валиться, а репорт покаже всі помилки окремо.
Приклад у цьому виді безглуздий, бо саме тут краще зробити як і раніш:
import pytest
@pytest.mark.parametrize(
"a, b, result",
[
(1, 2, 3),
(2, 2, 4),
(5, 5, 11),
]
)
def test_math(a, b, result):
assert a + b == result
Але якщо для отримання значень a, b або result треба робити якісь обчислення, котрі неможливо виконати до початку теста - тоді subtests стане дуже в нагоді.
Лінки:
- https://docs.pytest.org/en/stable/how-to/subtests.html
- https://github.com/pytest-dev/pytest/issues/1367
- https://docs.pytest.org/en/stable/example/parametrize.html
- https://docs.python.org/3.4/library/unittest.html#distinguishing-test-iterations-using-subtests