使用测试平台测试Google App Engine时InvalidModuleError() [英] InvalidModuleError() when using Testbed to Unit Test Google App Engine

查看:125
本文介绍了使用测试平台测试Google App Engine时InvalidModuleError()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图为由多个模块组成的Google App Engine应用程序编写Python单元测试时遇到了一些错误。



我一直遵循 https://cloud.google.com/appengine上提供的指导/ docs / python / tools / localunittesting



首先我得到以下内容:


错误:root:AssertionError('No api proxy for servicesmodules',)


但是我确定这是因为我没有正确初始化Testbed并需要单独调用:

  self.testbed.init_modules_stub( )

尽管已经有人打电话了:

  self.testbed.init_all_stubs()

这似乎很奇怪我,但不是主要问题......现在我已经死了ved过去的错误,而是我越来越︰


错误:root:InvalidModuleError()


代码非常简单。以下是测试用例的相关部分:

  def setUp(self):
self.testbed = testbed.Testbed ()
self.testbed.activate()
self.testbed.init_all_stubs
self.testbed.init_modules_stub()

def test_should_submit_a_task(self):
post_content ='{bucket:/ test /,filename,test,operation:read}'
request = webapp2.Request.blank('/ path / to /模块/方法',POST = post_content)
response = request.get_response(main.application)

self.assertEquals(response.status_int,200)



<$>

从被测代码中引发错误的行如下所示: p $ p $ host = get_hostname(queue)

我可以看到'队列'已被正确初始化为模块的名称。



get_hostname()状态下的google_appengine中的注释:



引发:
Inv



所以出于某种原因,我的模块版本是无效的。



是否有必要在代码被测试时手动将模块版本传递给get_hostname()?



或者我没有以某种方式初始化测试平台确保模块的版本是有效的?



编辑:我一直在研究这个问题,并通过Google App Engine代码添加到 request_info.py 中的 _LocalFakeDispatcher 类。该课程设置了一些用于测试的默认设置。问题是,我的测试在这里到达,试图确定模块是否有效,但它不匹配该存根中的默认值之一,因此最终返回无效模块错误。



是否有某种方法可以覆盖此调度程序中的默认值,以便使用期望的模块名称和版本进行填充?



见:

  class _LocalFakeDispatcher(Dispatcher):


def __init __(self,
module_names = None,
module_name_to_versions = None,
module_name_to_default_versions = None,
module_name_to_version_to_hostname =无):
super(_LocalFakeDispatcher,self).__ init __()
如果module_names是None:
module_names = ['default']
如果module_name_to_versions是None :
module_name_to_versions = {'default':['1']}
等...

非常感谢

R。



$ gcloud --version Google Cloud SDK 0.9。 44

应用2015.01.15
应用引擎转到达尔win-x86_64 1.9.17
app-engine-java 1.9.17
app-engine-managed-vms 2014.11.03
app-engine-python 1.9.17

解决方案

需要调用 init_modules_stub 的SDK(以及 testbed / __ init __。py );它已被添加到当前版本的 init_all_stubs 中(不确定何时完全),所以升级应该可以让您免除显式调用的需要。但正如你所说,并非主要问题。



但是在更重要的问题上 - 通过灯光,你没有做错任何事情,因为没有文件说你应该做任何特别的事情来初始化模块的存根。



幸运的是,解决方法并非太糟糕。具体来说,您可以在单元测试代码的早期阶段进行初始化:

  from google.appengine.api import request_info 

#编辑每个模块的all_versions&需要测试的版本
all_versions = {'default':[1],'andsome':[2],'others':[1]}
def_versions = {m:all_versions [m] [0 ] for m in all_versions}
m2h = {m:{def_versions [m]:'localhost:8080'} for def_versions}

request_info._local_dispatcher = request_info._LocalFakeDispatcher(
module_names = list(all_versions),
module_name_to_versions = all_versions,
module_name_to_default_versions = def_versions,
module_name_to_version_to_hostname = m2h)

假设这些是你想要的模块名称和版本!



是的,它应该绝对更容易(测试平台或某些模块应该公开一个执行此操作的函数 - 理想情况是解析适当的 yaml 文件,但至少明确的论点),非常重要的是,它应该被很好的记录。

成为第一个auth或者五年前的测试平台第一版的前身,我个人非常抱歉没有留意它(抱歉 - 我在此期间忙于非常不同的工作! - 但是,作为单元测试的狂热分子,我应该在这方面花费大约20%的时间)。

请打开关于揭示这个很好的功能请求记录它,感谢,这是为了耐心和你的出色的侦探工作,以确定问题的症结所在!


I’ve been wrestling with a couple of errors when trying to write some Python unit tests for a Google App Engine app that consists of a number of modules.

I have been following the guidance given on https://cloud.google.com/appengine/docs/python/tools/localunittesting

To begin with I was getting the following:

ERROR:root:AssertionError('No api proxy found for service "modules"’,)

However I determined that this was because I had not initialised Testbed correctly and needed a separate call to:

self.testbed.init_modules_stub()

This is despite already calling:

self.testbed.init_all_stubs()

This seems odd to me, but is not the main problem ... Now I've moved past that error, and instead I'm getting:

ERROR:root:InvalidModuleError()

The code is quite straightforward. Here's the relevant parts of the Test case:

def setUp(self):
    self.testbed = testbed.Testbed()
    self.testbed.activate()
    self.testbed.init_all_stubs
    self.testbed.init_modules_stub()

def test_should_submit_a_task(self):
    post_content = '{ "bucket": "/test/", "filename", "test", "operation": "read" }'
    request = webapp2.Request.blank('/path/to/module/method', POST=post_content)
    response = request.get_response(main.application)

    self.assertEquals(response.status_int, 200)

The line from the code under test where the error is thrown is as follows:

     host = get_hostname(queue)

I can see that 'queue' has been correctly initialised with the name of the module.

The comments in google_appengine from get_hostname() state:

"Raises: InvalidModuleError if the given moduleversion is invalid."

So for some reason my moduleversion is invalid.

So, is it it necessary to manually pass a module version to get_hostname() when the code is under test?

Or have I failed to initialise the testbed in some way to ensure that the module's version is valid?

EDIT: I've continued to work on this and have traced through the Google App Engine code to the class _LocalFakeDispatcher in request_info.py . That class sets up some defaults for use in testing. The problem is, my test arrives here trying to determine if the module is valid, but it doesn't match one of the defaults in this stub, and so an Invalid Module Error is eventually returned.

Is there some way I can override the defaults in this dispatcher to set it up populated with the expected module names and versions?

See:

class _LocalFakeDispatcher(Dispatcher):
  """A fake Dispatcher implementation usable by tests."""

  def __init__(self,
               module_names=None,
               module_name_to_versions=None,
               module_name_to_default_versions=None,
               module_name_to_version_to_hostname=None):
    super(_LocalFakeDispatcher, self).__init__()
    if module_names is None:
      module_names = ['default']
    if module_name_to_versions is None:
      module_name_to_versions = {'default': ['1']}
 etc. ...

Many thanks

R.

$gcloud --version Google Cloud SDK 0.9.44

app 2015.01.15 app-engine-go-darwin-x86_64 1.9.17 app-engine-java 1.9.17 app-engine-managed-vms 2014.11.03 app-engine-python 1.9.17 etc.

解决方案

The issue with needing to call init_modules_stub is connected to what release of the SDK (and thus of testbed/__init__.py) you have; that's been added to init_all_stubs in the current release (not sure when exactly) so an upgrade should let you remove the need for the explicit call. But as you say, not the main problem.

But on to the more substantial problem -- by my lights you've done nothing wrong, because no documentation says you should do anything in particular to initialize the modules' stub.

Fortunately, a work-around isn't too terrible. Specifically, you could have, early in your unit-test code, the initialization:

from google.appengine.api import request_info

# edit all_versions per modules & versions thereof needing tests
all_versions = {'default':[1], 'andsome':[2], 'others':[1]}
def_versions = {m:all_versions[m][0] for m in all_versions}
m2h = {m:{def_versions[m]:'localhost:8080'} for m in def_versions}

request_info._local_dispatcher = request_info._LocalFakeDispatcher(
    module_names = list(all_versions),
    module_name_to_versions = all_versions,
    module_name_to_default_versions = def_versions,
    module_name_to_version_to_hostname = m2h)

assuming of course that these are the module names and versions you want!

Yes, it should definitely be easier (the testbed or some module should expose a function doing this -- ideally by parsing appropriate yaml files, but at least with explicit arguments) and, very importantly, it should be well documented.

Having been the first author of a precursor of testbed's first version five years ago, I personally apologize for not keeping an eye on it (sorry -- I was busy with very different jobs in the meantime! -- but, being a fanatic about unit-testing, I should have used some 20% time on this).

Please do open a feature request about exposing this nicely and documenting it, and thanks both for your patience and for your excellent "detective work" identifying the crux of the problem!

这篇关于使用测试平台测试Google App Engine时InvalidModuleError()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆