Pytest-django: cls.setUpClass() -> TypeError: 'NoneType' object is not callable

Created on 4 Jul 2018  路  7Comments  路  Source: pytest-dev/pytest-django

    @pytest.fixture(autouse=True, scope='class')
    def _django_setup_unittest(request, django_db_blocker):
        """Setup a django unittest, internal to pytest-django."""
        if django_settings_is_configured() and is_django_unittest(request):
            request.getfixturevalue('django_test_environment')
            request.getfixturevalue('django_db_setup')

            django_db_blocker.unblock()

            cls = request.node.cls

            # implement missing (as of 1.10) debug() method for django's TestCase
            # see pytest-dev/pytest-django#406
            def _cleaning_debug(self):
                testMethod = getattr(self, self._testMethodName)
                skipped = (
                    getattr(self.__class__, "__unittest_skip__", False) or
                    getattr(testMethod, "__unittest_skip__", False))

                if not skipped:
                    self._pre_setup()
                super(cls, self).debug()
                if not skipped:
                    self._post_teardown()

            cls.debug = _cleaning_debug

            _restore_class_methods(cls)
>           cls.setUpClass()
E           TypeError: 'NoneType' object is not callable

Maybe related to: https://github.com/pytest-dev/pytest-django/pull/598 ?!?

setup:

platform linux -- Python 3.6.5, pytest-3.6.2, py-1.5.4, pluggy-0.6.0 -- /usr/local/bin/python
plugins: django-3.3.2, cov-2.5.1, celery-4.2.0

Think it's related to the upgrade:

pytest-django==3.3.0 -> 3.3.2
pytest==3.6.1 -> 3.6.2

EDIT: I test the down grade to pytest-django==3.3.0 and pytest==3.6.1 and the test runs fine.

bug

Most helpful comment

It is caused by 8a526433a4c601a3e17ce0c90d231dd91a7e7b5b.

Used the following test:

class TestUnittestMethods:
    def test_setUpClass_new(self, django_testdir):
        django_testdir.create_test_module('''
            from django.test import testcases

            class BaseCMSTestCase:
                pass

            class CMSTestCase(BaseCMSTestCase, testcases.TestCase):
                pass

            class FooBarTestCase(testcases.TestCase):
                @classmethod
                def setUpClass(cls):
                    super().setUpClass()

            class TestContact(CMSTestCase, FooBarTestCase):

                def test_noop(self):
                    pass
        ''')

        result = django_testdir.runpytest_subprocess('-v')
        result.stdout.fnmatch_lines([
            "*test_noop PASSED*",
        ])
        assert result.ret == 0

/cc @adamchainz

All 7 comments

I've looked into this further. I come to the simplified test code to reproduce the error:

from django.test import testcases
from cms.test_utils.testcases import CMSTestCase

class FooBarTestCase(testcases.TestCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()

class TestContact(CMSTestCase, FooBarTestCase):

    def test_noop(self):
        print("OK?!?")
        return

I don't have time to investigate any further right now :(

It is caused by 8a526433a4c601a3e17ce0c90d231dd91a7e7b5b.

Used the following test:

class TestUnittestMethods:
    def test_setUpClass_new(self, django_testdir):
        django_testdir.create_test_module('''
            from django.test import testcases

            class BaseCMSTestCase:
                pass

            class CMSTestCase(BaseCMSTestCase, testcases.TestCase):
                pass

            class FooBarTestCase(testcases.TestCase):
                @classmethod
                def setUpClass(cls):
                    super().setUpClass()

            class TestContact(CMSTestCase, FooBarTestCase):

                def test_noop(self):
                    pass
        ''')

        result = django_testdir.runpytest_subprocess('-v')
        result.stdout.fnmatch_lines([
            "*test_noop PASSED*",
        ])
        assert result.ret == 0

/cc @adamchainz

625 appears to fix it, but it's not really clear to me currently.

Hm!

It seems that pytest fix this?!?

Because the combination seems to work:

pytest-django==3.3.2
pytest==3.6.3

On the other side: i didn't see any related information for this in https://github.com/pytest-dev/pytest/blob/master/CHANGELOG.rst#pytest-363-2018-07-04

I'm not sure pytest could have fixed this upstream, because it's entirely code within pytest-django that is affected.

@jedie
Interesting.. would be nice if you could git-bisect it to e.g. a pytest commit, if you really think it is related to it.

(also make sure to not accidentally use #625, of course ;))

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rlskoeser picture rlskoeser  路  7Comments

aljosa picture aljosa  路  8Comments

asfaltboy picture asfaltboy  路  5Comments

scherrey picture scherrey  路  6Comments

ryankask picture ryankask  路  5Comments