2015-04-15 12 views
36

Zaktualizowałem projekt Django 1.7 do Django 1.8, a teraz dostaję błędy po uruchomieniu testów (które są podklasami django.test.TestCase).Aktualizacja do Django 1.8 - AttributeError: django.test.TestCase nie ma atrybutu "cls_atomics"

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' 

Jeśli debuguję test, mogę bez problemu przejść przez wszystkie wiersze, ale po ostatniej linii zostanie zgłoszony wyjątek.

To jest przykład testu:

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) 

Moja okolica:

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 

Jak mogę rozwiązać ten problem?

+0

Czy można tu wkleić zamrożenie pip? – lapinkoira

+0

@lapinkoira wykonał to – habakuk

+1

mmm Czy mogę zobaczyć uruchomioną wersję testową? – lapinkoira

Odpowiedz

60

Wierzę, że powodem jest to, że twoja metoda klasy setUpClass(cls) nie wywołuje super. Z tego powodu, django.tests.TestCase.setUpClass nie nazywa i

cls.cls_atomics = cls._enter_atomics() 

nie nazywa, naturalnie powoduje cls_atomics być niezdefiniowana.

Powinieneś dodać super(ATestTests, cls).setUpClass() do swojego setUpClass.

+0

To jest to. Jeśli dodaję połączenie do klasy bazowej, to działa ponownie (czy wspomniałem, że działało z django 1.7 ...). Nie potrzebuję też wywołania 'django.setup()'. – habakuk

+0

Myślałem, że nie potrzebuję 'django.setup()', ale nadal potrzebuję go w niektórych przypadkach, w przeciwnym razie dostaję wyjątek, że model nie jest instancjonowany. – habakuk

-1

Oto kompletny kod z wezwaniem do klasy bazowej (jako sugerowane przez @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) 
3

miałem podobny problem, gdzie TestCase używany setUpClass ale nie ma metody tearDownClass. Moje testy przechodzą kiedy dodać pustego jednego:

@classmethod 
def tearDownClass(cls): 
    pass 

ja też nie nazywaj django.setup.

+0

Po tej odpowiedzi może dojść do problemów z rozłączeniem, w którym znajdują się resztki obiektów i dane, które w inny sposób nie zostały oczyszczone. Może to powodować niespójności w zestawie testów, szczególnie jeśli działasz równolegle. – Jordan

+0

@Jordan - Tak, jeśli tworzysz jakieś trwałe obiekty, powinieneś dodać rzeczywisty kod "oczyszczenia" do zagłębienia, zgadzam się. – Matt

13

Dla Django 1.8+ należy używać TestCase.setUpTestData zamiast 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') 

Dokumentacja to here.

+0

To rozwiązało mój problem. Dzięki! –

Powiązane problemy