Python 如何在pytest中测试类层次结构?

Python 如何在pytest中测试类层次结构?,python,inheritance,pytest,Python,Inheritance,Pytest,我已经使用pytest一段时间了,并且学会了喜欢参数化和固定装置。第一次,我想测试一些具有分支继承结构的类。当然,我希望为子类重用测试用例。假设我有以下包结构: mock ├── pkg │   ├── child.py │   ├── grandchild.py │   └── parent.py └── tests ├── test_child.py ├── test_grandchild.py └── test_parent.py 如中所述,我可以使用fixtur

我已经使用pytest一段时间了,并且学会了喜欢参数化和固定装置。第一次,我想测试一些具有分支继承结构的类。当然,我希望为子类重用测试用例。假设我有以下包结构:

mock
├── pkg
│   ├── child.py
│   ├── grandchild.py
│   └── parent.py
└── tests
    ├── test_child.py
    ├── test_grandchild.py
    └── test_parent.py
如中所述,我可以使用fixture来提供被测试类的实例。但是,当我从一个测试模块导入一个测试类到另一个测试模块时,(a)感觉不是pytest方式,(b)pytest将运行导入类的所有测试方法,并作为继承测试类的一部分再次运行它们。例如,假设文件
test\u child.py
包含以下内容:

from test_parent import TestParent


class TestChild(TestParent):

    def test_foo(self):
        pass

    def test_bar(self):
        pass
这会导致pytest在
TestParent
中运行一次测试方法(由于在模块中导入),再运行一次作为
TestChild
的一部分(由于其方法被继承)

因此我看到了两种方法:(1)不继承基本测试类,只创建一个fixture,以便当前实例同时用于
TestParent
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\u parent.py
中创建一个参数化的fixture,将所有相关类的实例插入到这些测试方法中。比如:

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),因为它避免了导入,甚至可以完全跳过测试类。但是,有更好的方法吗?

您对
类TestChild(TestParent)的最初建议:
应该可以。只需避免以pytest收集的名称导入它。例如:

# test_parent.py
class TestParent:

    def test_parent(self):
        assert True

运行此:

> pytest -v
======================== test session starts =========================
platform linux -- Python 3.6.5rc1, pytest-3.5.0, py-1.5.3, pluggy-0.6.0 -- /home/flub/.virtualenvs/a713d56197da3b03/bin/python3
cachedir: .pytest_cache
rootdir: /tmp/sandbox, inifile:
collected 3 items                                                                                                                                                                                    

test_child.py::TestChild::test_child PASSED                     [ 33%]
test_child.py::TestChild::test_parent <- test_parent.py PASSED  [ 66%]
test_parent.py::TestParent::test_parent PASSED                  [100%]

=================== 3 passed in 0.01 seconds =========================
>pytest-v
=====================================测试会话开始=========================
平台linux——Python 3.6.5rc1、pytest-3.5.0、py-1.5.3、pluggy-0.6.0——/home/flub/.virtualenvs/a713d56197da3b03/bin/python3
cachedir:.pytest\u缓存
rootdir:/tmp/sandbox,文件:
收集了3个项目
test_child.py::TestChild::test_child通过[33%]
test\u child.py::TestChild::test\u parent
> pytest -v
======================== test session starts =========================
platform linux -- Python 3.6.5rc1, pytest-3.5.0, py-1.5.3, pluggy-0.6.0 -- /home/flub/.virtualenvs/a713d56197da3b03/bin/python3
cachedir: .pytest_cache
rootdir: /tmp/sandbox, inifile:
collected 3 items                                                                                                                                                                                    

test_child.py::TestChild::test_child PASSED                     [ 33%]
test_child.py::TestChild::test_parent <- test_parent.py PASSED  [ 66%]
test_parent.py::TestParent::test_parent PASSED                  [100%]

=================== 3 passed in 0.01 seconds =========================