首页 > 解决方案 > 具有继承的pytest参数化夹具 - 子类没有属性

问题描述

我遇到了一个我无法理解的 pytest 参数化夹具的奇怪行为。

鉴于此 sample.py :

import pytest
import requests
import conftest

@pytest.mark.parametrize('handler_class', [conftest.Child])
def test_simple(my_fixture):
    try:
        requests.get("http://localhost:8000")
    except:
        pass

以及同一目录中的以下 conftest.py :

class Base(http.server.SimpleHTTPRequestHandler):
    def __init__(self, request, client_address, server):
        super().__init__(request, client_address, server)
        self.value = 0

    def do_GET(self):
        print(self.value)   # AttributeError: 'Child' object has no attribute 'value'
        self.send_error(500)

class Child(Base):
    def __init__(self, request, client_address, server):
        super().__init__(request, client_address, server)
        self.value = 1

@pytest.fixture
def my_fixture(handler_class):
    handler = handler_class
    httpd = http.server.HTTPServer(('', 8000), handler)
    http_thread = threading.Thread(target=httpd.serve_forever)
    http_thread.start()
    yield
    httpd.shutdown()

如果你跑

pytest -s 样本.py

有一个异常,“AttributeError: 'Child' object has no attribute 'value'” 为什么?Base 和 Child 类都有一个 value 属性。

标签: pythoninheritancepytest

解决方案


我的建议是在其他线程中print(self.value)的行之前到达该行self.value = 0,这就是发生此类错误的原因。您需要像这样重构代码:

class Base(http.server.SimpleHTTPRequestHandler):
    def __init__(self, request, client_address, server, value=0):
        self.value = value
        super().__init__(request, client_address, server)

    def do_GET(self):
        print(self.value)  # 1 when doing pytest -s sample.py
        self.send_error(500)

class Child(Base):
    def __init__(self, request, client_address, server):
        super().__init__(request, client_address, server, value=1)

推荐阅读