pytest-dev / pytest-django

A Django plugin for pytest.
https://pytest-django.readthedocs.io/
Other
1.39k stars 344 forks source link

liveserver attribute error #101

Closed jgarzautexas closed 10 years ago

jgarzautexas commented 10 years ago

Hello, I am trying to setup a local server fixture, and keep getting a Attribute error (AttributeError: 'NoneType' object has no attribute 'find')

conftest.py

@pytest.fixture(scope="session", autouse=True) def local_server(request, live_server): print "in server *****" @request.addfinalizer def fin(): pass return

Traceback message

/usr/lib/python2.6/site-packages/pytest_django-2.6.2-py2.6.egg/pytest_django/live_server_helper.py:50: AttributeError ___ ERROR at setup of TestEnrollment.test_get_user_enrollment_list ____

request = <SubRequest 'live_server' for <Function 'test_get_user_enrollment_list'>>

@pytest.fixture(scope='session')
def live_server(request):
    """Run a live Django server in the background during tests

    The address the server is started from is taken from the
    --liveserver command line option or if this is not provided from
    the DJANGO_LIVE_TEST_SERVER_ADDRESS environment variable.  If
    neither is provided ``localhost:8081,8100-8200`` is used.  See the
    Django documentation for it's full syntax.

    NOTE: If the live server needs database access to handle a request
          your test will have to request database access.  Furthermore
          when the tests want to see data added by the live-server (or
          the other way around) transactional database access will be
          needed as data inside a transaction is not shared between
          the live server and test code.
    """
    skip_if_no_django()
    addr = request.config.getvalue('liveserver')
    if not addr:
        addr = os.getenv('DJANGO_TEST_LIVE_SERVER_ADDRESS')
    if not addr:
        addr = 'localhost:8081,8100-8200'
  server = live_server_helper.LiveServer(addr)

/usr/lib/python2.6/site-packages/pytest_django-2.6.2-py2.6.egg/pytest_django/fixtures.py:218:


self = <LiveServer listening at http://localhost:None>, addr = 'localhost:8081,8100-8200'

def __init__(self, addr):
    try:
        from django.test.testcases import LiveServerThread
    except ImportError:
        pytest.skip('live_server tests not supported in Django < 1.4')
    from django.db import connections

    connections_override = {}
    for conn in connections.all():
        # If using in-memory sqlite databases, pass the connections to
        # the server thread.
        if (conn.settings_dict['ENGINE'] == 'django.db.backends.sqlite3'
                and conn.settings_dict['NAME'] == ':memory:'):
            # Explicitly enable thread-shareability for this connection
            conn.allow_thread_sharing = True
            connections_override[conn.alias] = conn

    try:
        from django.test.testcases import _StaticFilesHandler
        static_handler_kwargs = {'static_handler': _StaticFilesHandler}
    except ImportError:
        static_handler_kwargs = {}

    host, possible_ports = parse_addr(addr)
    self.thread = LiveServerThread(host, possible_ports,
                                   connections_override=connections_override,
                                   **static_handler_kwargs)
    self.thread.daemon = True
    self.thread.start()
    self.thread.is_ready.wait()
    if self.thread.error:
      raise self.thread.error

E AttributeError: 'NoneType' object has no attribute 'find'

blueyed commented 10 years ago

Can you fix the format of the issues text, please? (indent the code and traceback by 4 spaces)

I am not sure, but the autouse=True might be problematic here.

jgarzautexas commented 10 years ago

Sorry about that, hopefully this will help. I simplified the code to make a test function call the liver_server fixture provided by pytest-django. Here is my platform.platform linux2 -- Python 2.6.6 -- py-1.4.20 -- pytest-2.5.2 -- /usr/bin/python. Using Django 1.4.10

def test_server(live_server):
    print live_server

    assert 1, True

Traceback 
request = <SubRequest 'live_server' for <Function 'test_server'>>

@pytest.fixture(scope='session')
def live_server(request):
    """Run a live Django server in the background during tests

    The address the server is started from is taken from the
    --liveserver command line option or if this is not provided from
    the DJANGO_LIVE_TEST_SERVER_ADDRESS environment variable.  If
    neither is provided ``localhost:8081,8100-8200`` is used.  See the
    Django documentation for it's full syntax.

    NOTE: If the live server needs database access to handle a request
          your test will have to request database access.  Furthermore
          when the tests want to see data added by the live-server (or
          the other way around) transactional database access will be
          needed as data inside a transaction is not shared between
          the live server and test code.
    """
    skip_if_no_django()
    addr = request.config.getvalue('liveserver')
    if not addr:
        addr = os.getenv('DJANGO_TEST_LIVE_SERVER_ADDRESS')
    if not addr:
        addr = 'localhost:8081,8100-8200'
  server = live_server_helper.LiveServer(addr)

/usr/lib/python2.6/site-packages/pytest_django-2.6.2-py2.6.egg/pytest_django/fixtures.py:218: 

self = <LiveServer listening at http://localhost:None>, addr = 'localhost:8081,8100-8200'

    def __init__(self, addr):
        try:
            from django.test.testcases import LiveServerThread
    except ImportError:
        pytest.skip('live_server tests not supported in Django < 1.4')
    from django.db import connections

    connections_override = {}
    for conn in connections.all():
        # If using in-memory sqlite databases, pass the connections to
        # the server thread.
        if (conn.settings_dict['ENGINE'] == 'django.db.backends.sqlite3'
                and conn.settings_dict['NAME'] == ':memory:'):
            # Explicitly enable thread-shareability for this connection
            conn.allow_thread_sharing = True
            connections_override[conn.alias] = conn

    try:
        from django.test.testcases import _StaticFilesHandler
        static_handler_kwargs = {'static_handler': _StaticFilesHandler}
    except ImportError:
        static_handler_kwargs = {}

    host, possible_ports = parse_addr(addr)
    self.thread = LiveServerThread(host, possible_ports,
                                   connections_override=connections_override,
                                   **static_handler_kwargs)
    self.thread.daemon = True
    self.thread.start()
    self.thread.is_ready.wait()
    if self.thread.error:
       raise self.thread.error
E           AttributeError: 'NoneType' object has no attribute 'find'

/usr/lib/python2.6/site-packages/pytest_django-2.6.2-    py2.6.egg/pytest_django/live_server_helper.py:50: AttributeError
blueyed commented 10 years ago

It is still unclear to me where the error is coming from:

AttributeError: 'NoneType' object has no attribute 'find'

Is it thrown via the following code? What is the line causing the error? raise self.thread.error?

    if self.thread.error:
       raise self.thread.error
E           AttributeError: 'NoneType' object has no attribute 'find'

Can you add a import ipdb; ipdb.set_trace() above the if self.thread.error and then inspect what self.thread.error is? (here is some ipdb guide: http://georgejhunt.com/olpc/pydebug/pydebug/ipdb.html - you would basically e.g. get/print type(self.thread) and type(self.thread.error).

For reference, the code used in Django's LiveServer (which is adopted here) looks the same: https://github.com/django/django/blob/master/django/test/testcases.py#L1206-1215

Apart from that, it might help if you have a reproducible test case. The live_server fixture is working for me and your simple test case works, too.

jgarzautexas commented 10 years ago

Thanks for the feedback. I tried in a virtualenv on my Mac and it worked. The issue still persists using vagrant, so I am going to troubleshoot further.