GAE: проверка загрузки больших двоичных объектов с помощью тестового стенда и веб-теста

Я использую blobstore с моим приложением Google App Engine, и все работает нормально на рабочем сервере и сервере разработки. Однако тестирование с помощью тестового стенда и webtest не работает...

В моих тестах блоб существует, так как я могу получить к нему доступ следующим образом:

blob = self.blobstore_stub.storage._blobs[key]

Когда я пытаюсь загрузить большой двоичный объект в своих тестах, как это

response = self.app.get("/blob-download/2")

мой обработчик загрузки blobstore никогда не вызывается, и я получаю ошибку 404 (но ссылка работает на серверах dev или prod).

Я подозреваю, что это ошибка тестового стенда или веб-теста...

Любые идеи относительно того, что я могу делать неправильно, или если это ошибка с тестовым стендом / веб-тестом, что может быть хорошим решением, чтобы я мог протестировать эту часть моего кода?


Вот некоторая информация о том, как я настраиваю свои тесты.

import unittest
from webtest import TestApp
from google.appengine.ext import db, testbed
from google.appengine.api import users
from google.appengine.api import apiproxy_stub_map

class ExampleTests(unittest.TestCase):

    def setUp(self):
        self.testbed = testbed.Testbed()
        self.testbed.setup_env(app_id="stv")
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_taskqueue_stub()
        self.testbed.init_mail_stub()
        self.testbed.init_blobstore_stub()
        self.app = TestApp(main.application)
        apiproxy_stub_map.apiproxy.GetStub("datastore_v3").Clear()
        self.taskqueue_stub = apiproxy_stub_map.apiproxy.GetStub('taskqueue')
        self.mail_stub = apiproxy_stub_map.apiproxy.GetStub('mail')
        self.blobstore_stub = apiproxy_stub_map.apiproxy.GetStub('blobstore')

   def testBlob(self):
        # create blob using files.blobstore.create
        response = self.app.get("/blob-download/2") # This returns 404
        self.assertEqual(response.body, "content of blob") # This fails

Это соответствующая часть app.yaml:

handlers:
- url: /.*
  script: main.application

Это соответствующая часть main.py:

application = webapp2.WSGIApplication(
    [
     ('/blob-download/([^/]+)?', views.BlobDownload),
    ]

person gaefan    schedule 15.02.2012    source источник


Ответы (1)


Трудно сказать о маршрутизации, не имея доступных маршрутов из main.application и app.yaml.

Я подозреваю, что вы настроили «/blob-download» в app.yaml, о котором веб-тест не знает, он знает только о маршрутизации, которую вы настроили в main.application.

update: Теперь, когда app.yaml не является причиной, давайте двигаться дальше. Что может помочь, так это увидеть своего обработчика. Ответы службы Blobstore обрабатываются не так, как обычные ответы. Вы, как разработчик, добавляете ключ большого двоичного объекта в качестве заголовка к ответу. Серверная часть App Engine проверяет этот конец заголовка и, если находит, берет на себя обслуживание большого двоичного объекта. Вы можете ознакомиться с реализацией dev_appserver здесь: http://code.google.com/p/googleappengine/source/browse/trunk/python/google/appengine/tools/dev_appserver_blobstore.py#214.

Это означает, что вы не можете на самом деле протестировать обслуживание больших двоичных объектов без обработки запросов dev_appserver или appserver, что означает, что testbed + webtest вам здесь не помогут (хотя это не объясняет 404).

Что вы можете сделать, так это запустить полный сквозной тест, например, с помощью gaedriver: http://code.google.com/p/gaedriver/

person schuppe    schedule 16.02.2012
comment
Привет Шуппе, спасибо за ваш ответ. Я не думаю, что это проблема, но я обновил свой вопрос, добавив более подробную информацию о app.yaml и main.py. - person gaefan; 16.02.2012
comment
@schuppe, как вообще можно определить что-то в app.yaml, не сопоставляя его с обработчиком в main.application? вы можете отправить все в main.application, но это сопоставление должно быть более конкретным. - person aschmid00; 16.02.2012
comment
@ aschmid00 aschmid00 Я хотел проверить, был ли у Джеффа другой обработчик, определенный в app.yaml, который обрабатывал запросы к «/blob-download/» до того, как main.application доберется до него. Шаблоны, определенные в app.yaml, оцениваются в том порядке, в котором они появляются. Если бы у него был определенный обработчик для чего-то, что соответствует '/blob-download/' перед возможным универсальным '.*'-main, это было бы простым объяснением. Но с обновлением Джеффа похоже, что это не так. - person schuppe; 16.02.2012
comment
@schuppe я понимаю, но я предполагаю (и надеюсь на это), что если бы он обрабатывал /blob-download с другим обработчиком, он бы знал об этом также, потому что он говорит, что приложение работает в разработке и производстве. тесты не делают. - person aschmid00; 16.02.2012
comment
@schuppe, я не понимаю, что вы имеете в виду, говоря, что вы, как разработчик, добавляете ключ большого двоичного объекта в качестве заголовка к ответу, поскольку я этого не делаю. Я обслуживаю большие двоичные объекты, как описано здесь: code.google.com/appengine. /docs/python/blobstore/. Кроме того, мой обработчик загрузки больших двоичных объектов никогда не вызывается. Это основная проблема, которую я пытаюсь решить, и я обновил свой вопрос, чтобы попытаться сделать это более ясным. - person gaefan; 17.02.2012
comment
@Jeff Используя self.send_blob(blob_info), вы вызываете функцию, которая помещает ключ большого двоичного объекта в заголовки ответа: code.google.com/p/googleappengine/source/browse/trunk/python/. В любом случае, можете ли вы также предоставить свою тестовую функцию? - person schuppe; 17.02.2012
comment
@schuppe, в тестовой функции не так много интересного ... запрос большого двоичного объекта приводит к ошибке 404, но я обновил свой вопрос, указав соответствующие подробности о тесте, который вызовет эту проблему. - person gaefan; 18.02.2012
comment
@kekito, я почти уверен, что в вашей настройке маршрутизации или обработке запросов что-то не так, потому что я мог заставить работать базовый пример. Он слишком длинный, чтобы поместиться здесь (pastebin.com/FQFH1Rx6), но в основном это урезанная версия то, что вы предоставили, плюс добавлен код, чтобы заполнить пробелы. Сам тест не проходит, но обработчик вызывается точно. Извините, что не могу больше помочь. - person schuppe; 21.02.2012
comment
@schuppe, спасибо, что собрал это вместе. Однако он не возвращает мне каплю, и вы не проверили ответ. Не могли бы вы попробовать это и сообщить мне, если тест не пройден?: pastebin.com/p8pY8BsE - person gaefan; 22.02.2012
comment
@Kekito Ваши тесты запускаются, но терпят неудачу, чего и следовало ожидать - точно так же, как тот, который я вставил. Почему? Как я объяснял ранее, ответы обслуживания Blobstore обрабатываются иначе, чем обычные ответы. Это означает, что вы не можете фактически протестировать обслуживание больших двоичных объектов без обработки запросов dev_appserver или appserver, что означает, что testbed + webtest вам здесь не помогут. По крайней мере, теперь вы знаете, что ошибка 404 связана с каким-то фрагментом вашего кода, потому что фрагменты пустяков возвращают 200. - person schuppe; 23.02.2012
comment
@schuppe, я вижу, ты намекаешь. Превращение 404 в 200, которое не возвращает большой двоичный объект, к сожалению, мало помогает, поскольку все дело в том, чтобы иметь возможность проверить мое использование хранилища больших двоичных объектов, что я, по-видимому, не могу сделать. :( - person gaefan; 24.02.2012