我已经使用 pytest 一段时间了,并学会了喜欢参数化和固定装置。我第一次想测试一些具有分支继承结构的类。当然,我想为子类重用测试用例。假设我有以下包结构:
mock
├── pkg
│ ├── child.py
│ ├── grandchild.py
│ └── parent.py
└── tests
├── test_child.py
├── test_grandchild.py
└── test_parent.py
如中所述这个问题 https://stackoverflow.com/questions/46040478/how-to-test-a-class-inherited-methods-in-pytest我可以使用固定装置来提供正在测试的类的实例。但是,当我从另一个测试模块中的一个测试模块导入测试类时,(a)感觉这不是 pytest 方式,(b)pytest 将运行导入类的所有测试方法,并作为继承的测试类的一部分再次运行它们。比如说文件test_child.py
包含以下内容:
from test_parent import TestParent
class TestChild(TestParent):
def test_foo(self):
pass
def test_bar(self):
pass
这会导致 pytest 运行测试方法TestParent
一次(由于在模块中导入)加上另一次作为TestChild
(由于其方法被继承)。
所以我看到两种方法:(1)不要继承基测试类,而只是创建一个固定装置,以便当前实例同时用于TestParent
and TestChild
, 本质上:
import pytest
from pkg.child import Child
from test_parent import TestParent
@pytest.fixture(scope="class")
def instance():
return Child()
class TestChild(object):
def test_foo(self, instance):
pass
def test_bar(self, instance):
pass
(2) 我看到的另一种方法是不导入任何测试类,而只是创建一个参数化的装置test_parent.py
这会将所有相关类的实例插入到这些测试方法中。就像是:
import pytest
from pkg.parent import Parent
from pkg.child import Child
from pkg.grandchild import GrandChild
@pytest.fixture(scope="class", params=[Parent, Child, GrandChild])
def instance(request):
return request.param()
class TestParent(object):
def test_base(self, instance):
pass
考虑一下,我更喜欢选项(2),因为它避免了导入,我什至可以完全跳过测试课程。但还有更好的方法吗?