Подтвердить что ты не робот

Обновление до Django 1.8 - AttributeError: django.test.TestCase не имеет атрибута 'cls_atomics'

Я обновил проект Django 1.7 до Django 1.8 и теперь получаю ошибки при запуске тестов (подклассы django.test.TestCase).

Traceback (most recent call last):
  File "env\lib\site-packages\django\test\testcases.py", line 962, in tearDownClass
cls._rollback_atomics(cls.cls_atomics)
  AttributeError: type object 'SomeTests' has no attribute 'cls_atomics'

Если я отлаживаю тест, я могу пройти через все строки без проблем, но после последней строки генерируется исключение.

Это пример теста:

import django
import unittest
from django.test import TestCase
import logging
import sys
from builtins import classmethod, isinstance

class ATestTests(TestCase):

    @classmethod
    def setUpClass(cls):
        django.setup()
        logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)


    def setUp(self):
        self._app = Application(name="a")


    def testtest(self):

        self.assertIsNotNone(self._app)

Моя среда:

astroid==1.3.4
colorama==0.3.3
defusedxml==0.4.1
Django==1.8
django-extensions==1.5.2
django-filter==0.9.2
djangorestframework==3.0.5
djangorestframework-xml==1.0.1
eight==0.3.0
future==0.11.4
logilab-common==0.63.2
Markdown==2.5.2
pylint==1.4.1
python-dateutil==2.4.1
python-mimeparse==0.1.4
six==1.9.0
xmltodict==0.9.2

Как я могу это исправить?

4b9b3361

Ответ 1

Я считаю, что причина в том, что ваш метод класса setUpClass(cls) не вызывает супер. Из-за этого django.tests.TestCase.setUpClass не вызывается и

cls.cls_atomics = cls._enter_atomics()

не вызывается, что вызывает cls_atomics undefined.

Вы должны добавить super(ATestTests, cls).setUpClass() к вашему setUpClass.

Ответ 2

Для Django 1.8+ вы должны использовать TestCase.setUpTestData вместо TestCase.setUpClass.

class MyTests(TestCase):

    @classmethod
    def setUpTestData(cls):
        # Set up data for the whole TestCase
        cls.foo = Foo.objects.create(bar="Test")

    def test1(self):
        self.assertEqual(self.foo.bar, 'Test') 

Документация здесь.

Ответ 3

У меня была аналогичная проблема, когда a TestCase использовал setUpClass, но не имел метода tearDownClass. Мои тесты проходят, когда я добавляю пустой:

@classmethod
def tearDownClass(cls):
    pass

Я также не называю django.setup.

Ответ 4

Вот полный код с вызовом базового класса (как предложено @J. C. Leitão):

import django
import unittest
from django.test import TestCase
import logging
import sys
from builtins import classmethod

class ATestTests(TestCase):

    @classmethod
    def setUpClass(cls):
        super(ATestTests, cls).setUpClass()
        django.setup()
        logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)

    def setUp(self):
        self._app = Application(name="a")

    def testtest(self):

        self.assertIsNotNone(self._app)