2013-06-27 3 views
4

Я столкнулся с этой странной проблемой случайного сбоя unittests. Я в основном тестирования синдикацииDjango Unittests Fail Randomly

Вот соответствующая часть моего кода:

class ObjectFeedTests(PuppyTestCase): 

    def test_object_feeds(self): 
     site = Site.objects.get_or_create(id=site_id)[0] 

     #Some preprocessing and initialization 

     with self.settings(ROOT_URLCONF='myapp.urls.something'): 

      #Some more preprocessing is done here 

      show = ShowFactory.create(slug=show_slug, title=show_name, 
             site=site) 

      for feed_name, entry_points in OBJECT_FEEDS.items(): 

       factory = default_factories[model] #fetches the correct factory 

       if feed_name == "podcast": 
        instance = factory.create(show=show, slug="podcasts") 
       else: 
        instance = factory.create() 

       #Creates the instance with the factory correctly 

       for feed_type in ['rss', 'atom']: 

        with self.settings(SITE_ID=site.id): 
         class_url_pattern = feed_class().get_url_pattern() 

        slug_of_note = '%s/%s' % (show_slug, instance.slug) 
        presumed_url = '/%s/%s/%s' % (FEED_URL_PREFIXES[feed_type], 
              feed_name, slug_of_note) 

        with self.settings(SITE_ID=site.id): 
         response = self.client.get(presumed_url, 
             {'password': '****'}) 

        self.assertContains(response, '<?xml', 
         msg_prefix="%s %s feed raised a 404 \ 
         or wasn't XML (tried %s)" \ 
          % (feed_name, feed_type, presumed_url)) 

       # End of our loop. We'll delete the object 
       # so that we're not hung up by unique_together constraints 
       instance.delete() 

Фабрика:

class ShowFactory(factory.Factory): 
    FACTORY_FOR = Show 

    title = factory.Sequence(lambda name: 'My Show {0}'.format(name)) 
    slug = factory.Sequence(lambda name: 'my-show-{0}'.format(name)) 
    creator = factory.SubFactory(UserFactory) 
    last_editor = factory.SubFactory(UserFactory) 
    site = factory.SubFactory(SiteFactory) 
    status = STATUS_CHOICES.PUBLISHED 

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

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

Я рассматривал using this, но результаты остались прежними.

Пожалуйста, дайте мне знать, если есть более подробная информация, которую я мог бы предоставить.

Вот StackTrace из строя:

====================================================================== 
FAIL: test_object_feeds (tests.syndication_tests.ObjectFeedTests) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "tests/cases.py", line 44, in run 
    testMethod() 
    File "tests/syndication_tests.py", line 370, in test_object_feeds 
    presumed_url)) 
    File "/usr/local/virtualenvs/lib/python2.6/site-packages/django/test/testcases.py", line 622, in assertContains 
    " (expected %d)" % (response.status_code, status_code)) 
AssertionError: 404 != 200 : people rss feed raised a 404        or wasn't XML (tried /feeds/show/test-show-0): Couldn't retrieve content: Response code was 404 (expected 200) 

---------------------------------------------------------------------- 

Ran 5 tests in 10.613s 

FAILED (failures=1) 
Destroying test database for alias 'default'... 

В следующий раз, когда я запустить его,

====================================================================== 
FAIL: test_object_feeds (tests.syndication_tests.ObjectFeedTests) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "tests/cases.py", line 44, in run 
    testMethod() 
    File "tests/syndication_tests.py", line 370, in test_object_feeds 
    presumed_url)) 
    File "/usr/local/virtualenvs/lib/python2.6/site-packages/django/test/testcases.py", line 622, in assertContains 
    " (expected %d)" % (response.status_code, status_code)) 
AssertionError: 404 != 200 : channels rss feed raised a 404        or wasn't XML (tried /feeds/show/test-show-1): Couldn't retrieve content: Response code was 404 (expected 200) 

---------------------------------------------------------------------- 
Ran 5 tests in 3.483s 

FAILED (failures=1) 
Destroying test database for alias 'default'... 
+1

Глупый вопрос, но что тест говорят в это выход? Почему он терпит неудачу? –

+0

@limelights Только что обновил вопрос с помощью stacktrace – karthikr

+0

По какой-то причине вещь, которую вы получаете, недействительна XML, что довольно очевидно. Ваш тест выглядит хорошо, и я не вижу причин, почему это не сработает. –

ответ

2

Пожалуйста, простите меня за то констатировал очевидное. Наиболее распространенной причиной случайного отказа является то, что одно из ваших тестов не срывалось должным образом. Это происходит случайно, потому что порядок выполнения тестов не является детерминированным. Попробуйте запустить неудавшийся тест самостоятельно, а не запустить весь набор тестов. Если он проходит каждый раз, то это определенно вызвано некоторыми другими тестами.

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

+0

Спасибо за ваш ответ. Можете ли вы подробнее рассказать о том, что вы имеете в виду? – karthikr

+0

Это будет зависеть от вашего тестового бегуна. Например, я использую django-нос, который позволяет мне выполнить REUSE_DB = 1 ./manage.py тест и сэкономить несколько секунд в начале и конце вашего набора тестов, повторно используя тестовую базу данных с последнего запуска. –

+0

Спасибо. Думаю, ваше направление на светильники заставило меня подумать, что у меня могут быть проблемы с данными в светильниках. Я попробую это – karthikr