我有一个场景,能够在py.test中对基础测试类进行子类化,这将使我们的测试环境具有很强的可扩展性。我遇到的问题是我无法覆盖基类的属性并在参数化装饰器中使用它们。
import pytest
class TestBase():
l = [2,3]
@pytest.mark.parametrize('p', l)
def testOne(self, p):
assert p == p
class TestSubClass(TestBase):
l = [1, 2, 3, 4]
class TestSubClass2(TestBase):
l = [3, 5]
在此方案中,TestSubClass
和TestSubClass2
始终使用l
中的列表TestBase
运行,因为装饰器查找l
的范围是本地的范围。
我无法使用self.l
,因为在评估装饰器时self
不存在(没有实例)。
我可以解决这个问题并在测试用例中手动执行参数化,但后来我丢失了py.test的单独报告。例如
import pytest
class TestBase()
def testOne(self):
for p in self.l:
assert p == p
class TestSubClass(TestBase):
l = [1, 2, 3, 4]
class TestSubClass2(TestBase):
l = [3, 5]
如何对基类进行子类化并为每个子类自定义参数化?
答案 0 :(得分:0)
我有一个轻微可怕的解决方案:
代码:
import pytest
class TestBase():
l = [1, 2, 3, 4, 5]
@pytest.mark.parametrize('p', l)
def testOne(self, p):
if p not in self.l:
pytest.skip("%d not supported on %s" % (p, self.__class__.__name__))
assert p == p
class TestSubClass(TestBase):
l = [1, 2]
class TestSubClass2(TestBase):
l = [3, 5]
和相应的输出:
py.test -v -rsf test_sample.py::TestSubClass
===================================== test session starts ======================================
platform darwin -- Python 2.7.9 -- py-1.4.26 -- pytest-2.6.4 --
collected 5 items
test_sample.py::TestSubClass::testOne[1] PASSED
test_sample.py::TestSubClass::testOne[2] PASSED
test_sample.py::TestSubClass::testOne[3] SKIPPED
test_sample.py::TestSubClass::testOne[4] SKIPPED
test_sample.py::TestSubClass::testOne[5] SKIPPED
=================================== short test summary info ====================================
SKIP [1] test_sample.py:10: 4 not supported on TestSubClass
SKIP [1] test_sample.py:10: 3 not supported on TestSubClass
SKIP [1] test_sample.py:10: 5 not supported on TestSubClass
============================= 2 passed, 3 skipped in 0.01 seconds ==============================
这种方法会带来一些可怕的后果: