web-dev-qa-db-fra.com

Mise à jour vers Django 1.8 - AttributeError: Django.test.TestCase n'a pas d'attribut 'cls_atomics'

J'ai mis à jour un projet Django 1.7 vers Django 1.8 et j'obtiens maintenant des erreurs lorsque j'exécute les tests (qui sont des sous-classes de 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'

Si je débogue à travers le test, je peux parcourir toutes les lignes sans problème, mais après la dernière ligne, l'exception est levée.

Ceci est un exemple de test:

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)

Mon environnement:

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

Comment puis-je réparer cela?

57
habakuk

Je crois que la raison en est que votre méthode de classe setUpClass(cls) n'appelle pas super. Pour cette raison, Django.tests.TestCase.setUpClass N'est pas appelé et

cls.cls_atomics = cls._enter_atomics()

n'est pas appelé, ce qui rend naturellement cls_atomics indéfini.

Vous devez ajouter super(ATestTests, cls).setUpClass() à votre setUpClass.

96
Jorge Leitão

Pour Django 1.8+, vous devez utiliser TestCase.setUpTestData au lieu de 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') 

La documentation est ici .

27
seddonym

J'ai eu un problème similaire lorsqu'un TestCase utilisait setUpClass mais n'avait pas de méthode tearDownClass. Mes tests réussissent lorsque j'en ajoute un vide:

@classmethod
def tearDownClass(cls):
    pass

Je n'appelle pas non plus Django.setup.

6
Matt