Как проверить унаследованные методы класса в pytest


house.py:

class House:
    def is_habitable(self):
        return True

    def is_on_the_ground(self):
        return True

conftest.py:

import pytest
from house import House


@pytest.fixture(scope='class')
def house():
    return House()

test_house.py:

class TestHouse:
    def test_habitability(self, house):
        assert house.is_habitable()

    def test_groundedness(self, house):
        assert house.is_on_the_ground()
До этого момента все проходит проверку.

Теперь я добавляю подкласс и переопределяю метод в house.py:

class House:
    def is_habitable(self):
        return True

    def is_on_the_ground(self):
        return True


class TreeHouse(House):
    def is_on_the_ground(self):
        return False

Я также добавляю новое приспособление для этого класса в conftest.py:

import pytest
from house import House
from house import TreeHouse


@pytest.fixture(scope='class')
def house():
    return House()


@pytest.fixture(scope='class')
def tree_house():
    return TreeHouse()

Я добавляю новый тестовый класс для tree house в test_house.py:

class TestHouse:
    def test_habitability(self, house):
        assert house.is_habitable()

    def test_groundedness(self, house):
        assert house.is_on_the_ground()


class TestTreeHouse:
    def test_groundedness(self, tree_house):
        assert not tree_house.is_on_the_ground()
На этом этапе код работает, но есть случаи, которые не проверяются. Например, чтобы быть полным, мне нужно было бы снова проверить методы, унаследованные от House в TreeHouse.

Переписывание же тестов из TestHouse не будет сухим.

Как проверить унаследованный метод TreeHouse (в данном случае is_habitable) без дублирования кода?

Я хотел бы что-то вроде повторного тестирования TreeHouse с теми же тестами, через которые проходит его суперкласс, но не для методов / свойств, которые являются новыми или переопределенными.

После некоторых исследований я наткнулся на противоречивые источники. И после того, как покопался в pytest документация я не могу понять, что относится к этому сценарию.

Меня интересует pytest способ сделать это. Пожалуйста, обратитесь к документам и объясните, как это применимо здесь.

2 3

2 ответа:

Один из способов сделать это-использовать имя фикстуры house для всех методов тестирования (даже если это тестирование TreeHouse), и переопределить его значение в каждом тестовом контексте :

class TestTreeHouse(TestHouse):
    @pytest.fixture
    def house(self, tree_house):
        return tree_house

    def test_groundedness(self, house):
        assert not house.is_on_the_ground()

Также обратите внимание, что TestTreeHouse наследуется от TestHouse. Поскольку pytest просто перечисляет методы классов (то есть нет никакой "регистрации", сделанной, скажем, с @pytest.test() декоратором), все тесты, определенные в TestHouse, будут обнаружены в подклассах его, без какого-либо дальнейшего вмешательства.

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