Как проверить унаследованные методы класса в 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 способ сделать это. Пожалуйста, обратитесь к документам и объясните, как это применимо здесь.
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 для передачи нескольких аргументов одному и тому же тесту, в этом случае аргументом, скорее всего, будет тестируемый класс.