Giter Club home page Giter Club logo

nosegae's Introduction

NoseGAE: Nose for Google App Engine Testing

PyPI Downloads License Build Status

Installing

NoseGAE is available from the cheeseshop and can be installed easiest via pip install nosegae. While the library is actively maintained, no new features are being added at this time so development has stagnated. If you want to work on the library, or just like to clone and install you can use your choice of python setup.py install or python setup.py develop or even the pip equiv.

Overview

NoseGAE is a nose plugin that makes it easier to write functional and unit tests for Google App Engine applications.

  1. What does it do?
    1. Functional tests
    2. Unit tests
  2. Configuring the TestBed
    1. Class Based Tests
    2. Function Tests
    3. Doctest
  3. Changes in 0.5.2
  4. Changes in 0.4.0

What does it do?

NoseGAE sets up the GAE development environment before your test run. This means that you can easily write functional tests for your application without having to actually start the dev server and test over http. The plugin also configures and initializes a TestBed instance, your application_id based off your app.yaml, and sets the proper paths using dev_appserver.fix_sys_path().

Functional tests

Consider the simple hello world application in examples/helloworld:

import webapp2
from jinja2 import Environment


class Hello(webapp2.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        env = Environment()
        template = env.from_string("Hello {{ greeting }}!")
        self.response.out.write(template.render(greeting='world'))

app = webapp2.WSGIApplication([('/', Hello)], debug=True)

And a simple functional test suite examples/helloworld/test.py for the application:

from webtest import TestApp
import unittest
import helloworld

app = TestApp(helloworld.app)


class HelloWorldTest(unittest.TestCase):
    def test_index(self):
        """Tests that the index page for the application

        The page should be served as: Content-Type: text/plain
        The body content should contain the string: Hello world!
        """
        response = app.get('/')
        self.assertEqual(response.content_type, 'text/plain')
        self.assertIn('Hello world!', response.body)

Without NoseGAE, the test fails.

helloworld$ nosetests --logging-level=ERROR
E
======================================================================
ERROR: Failure: ImportError (No module named webapp2)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/Josh/Developer/Github/jj/lib/python2.7/site-packages/nose-1.3.4-py2.7.egg/nose/loader.py", line 414, in loadTestsFromName
    addr.filename, addr.module)
  File "/Users/Josh/Developer/Github/jj/lib/python2.7/site-packages/nose-1.3.4-py2.7.egg/nose/importer.py", line 47, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "/Users/Josh/Developer/Github/jj/lib/python2.7/site-packages/nose-1.3.4-py2.7.egg/nose/importer.py", line 94, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "/Users/Josh/Developer/Github/nosegae/examples/helloworld/test.py", line 2, in <module>
    import helloworld
  File "/Users/Josh/Developer/Github/nosegae/examples/helloworld/helloworld.py", line 1, in <module>
    import webapp2
ImportError: No module named webapp2

----------------------------------------------------------------------
Ran 1 test in 0.075s

FAILED (errors=1)

With NoseGAE, they pass.

helloworld$ nosetests --logging-level=ERROR --with-gae
.
----------------------------------------------------------------------
Ran 1 test in 0.264s

OK

Unit tests

Functional tests are only one kind of test, of course. What if you want to write unit tests for your data models? Normally, you can't use your models at all outside of the dev environment, because the Google App Engine datastore isn't available. However, since the NoseGAE plugin sets up the development environment around your test run, you can use models directly in your tests.

Consider the examples/pets/models.py file that includes some doctests:

from google.appengine.ext import ndb

class Pet(ndb.Model):
    """The Pet class provides storage for pets.

    >>> # initialize testbed stubs
    >>> testbed.init_memcache_stub()
    >>> testbed.init_datastore_v3_stub()

    You can create a pet:
    >>> muffy = Pet(name=u'muffy', type=u'dog', breed=u"Shi'Tzu")
    >>> muffy # doctest: +ELLIPSIS
    Pet(name=u'muffy', type=u'dog', breed=u"Shi'Tzu", ...)
    >>> muffy_key = muffy.put()

    Once created, you can load a pet by its key:

    >>> muffy_key.get() # doctest: +ELLIPSIS
    Pet(name=u'muffy', type=u'dog', breed=u"Shi'Tzu", ...)

    Or by a query that selects the pet:

    >>> list(Pet.query(Pet.type == 'dog')) # doctest: +ELLIPSIS
    [Pet(name=u'muffy', ...)]

    To modify a pet, change one of its properties and ``put()`` it again.

    >>> muffy_2 = muffy
    >>> muffy_2.age = 10
    >>> muffy_key_2 = muffy_2.put()

    The pet's key doesn't change when it is updated.

    >>> bool(muffy_key == muffy_key_2)
    True
    """
    name = ndb.StringProperty(required=True)
    type = ndb.StringProperty(required=True, choices=("cat", "dog", "bird", "fish", "monkey"))
    breed = ndb.StringProperty()
    age = ndb.IntegerProperty()
    comments = ndb.TextProperty()
    created = ndb.DateTimeProperty(auto_now_add=True, required=True)

    def __repr__(self):
        return ("Pet(name=%r, type=%r, breed=%r, age=%r, "
                "comments=%r, created=%r)" %
                (self.name, self.type, self.breed, self.age,
                 self.comments, self.created))

Without NoseGAE, the doctests fail.

pets$ nosetests --with-doctest --logging-level=ERROR
F
======================================================================
FAIL: Doctest: models.Pet
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 2201, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for models.Pet
  File "/Users/Josh/Developer/Github/nosegae/examples/pets/models.py", line 4, in Pet

----------------------------------------------------------------------
File "/Users/Josh/Developer/Github/nosegae/examples/pets/models.py", line 15, in models.Pet
Failed example:
    muffy_key = muffy.put()
Exception raised:
    Traceback (most recent call last):
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 1289, in __run
        compileflags, 1) in test.globs
      File "<doctest models.Pet[2]>", line 1, in <module>
        muffy_key = muffy.put()
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/model.py", line 3379, in _put
        return self._put_async(**ctx_options).get_result()
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 325, in get_result
        self.check_success()
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 368, in _help_tasklet_along
        value = gen.throw(exc.__class__, exc, tb)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/context.py", line 810, in put
        key = yield self._put_batcher.add(entity, options)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/tasklets.py", line 371, in _help_tasklet_along
        value = gen.send(val)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/ndb/context.py", line 343, in _put_tasklet
        keys = yield self._conn.async_put(options, datastore_entities)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1801, in async_put
        return make_put_call(base_req, pbs, extra_hook)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1784, in make_put_call
        service_name=self._api_version)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1310, in _make_rpc_call
        rpc = self._create_rpc(config, service_name)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1205, in _create_rpc
        rpc = apiproxy_stub_map.UserRPC(service_name, deadline, callback)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 414, in __init__
        self.__rpc = CreateRPC(service, stubmap)
      File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 68, in CreateRPC
        assert stub, 'No api proxy found for service "%s"' % service
    AssertionError: No api proxy found for service "datastore_v3"
    

With NoseGAE, they pass.

pets$ nosetests --with-doctest --with-gae
.
----------------------------------------------------------------------
Ran 1 test in 0.228s

OK

Configuring the TestBed

NoseGAE automatically configures your TestBed instance for you and then enables any stubs that you may need for your tests to pass. There are two ways to enable and configure your stubs. The first and most flexible way is to directly initialize the stub(s) on the TestBed instance injected into your test case. The second, and simpler way, is to set the nosegae_* and optional nosegae_*_kwargs attributes on your test case and let NoseGAE configure them for you. The following three sections describe how to use the TestBed in your own tests.

Class Based Tests

The simplest of use cases is when your test class extends unittest.TestCase. The NoseGAE plugin injects an attribute named testbed to the instance of your test class and configures it based upon any attributes matching the convention nosegae_<stubname> and nosegae_<stubname>_kwargs.

This test uses the assigned testbed attribute to manually configure each test.

class MyTest(unittest.TestCase):
    def test_using_memcache(self):
        """Unit test using memcache"""
        from google.appengine.api import memcache
        self.testbed.init_memcache_stub()
        memcache.set('test', True, 30)
        self.assertTrue(memcache.get('test'))
    
    def test_using_taskqueue(self):
        """Unit test using the taskqueue"""
        self.testbed.init_taskqueue_stub(root_path='/path/to/app')
        from google.appengine.api import taskqueue
        task_url = '/some/task'
        taskqueue.add(url=task_url)
        taskqueue_stub = self.testbed.get_stub('taskqueue')
        tasks = taskqueue_stub.get_filtered_tasks(url=task_url)
        self.assertEqual(1, len(tasks))
        self.assertEqual(task_url, tasks[0].url)

The following test case shows how to write a test that uses the datastore stub based on the simple configuration method using nosegae_<stubname> and nosegae_<stubname>_kwargs.

class DataTest(unittest.TestCase):
    # enable the datastore stub
    nosegae_datastore_v3 = True
    
    def test_get_entity(self):
        """Naively tests that we can fetch an entity from the datastore"""
        entity = MyModel.query().get()
        self.assertIsNotNone(entity)
    

Function Tests

This test case uses the testbed instance assigned to the function to manually configure any needed stubs. See examples/function_manual_config.

def test_index():
    # test_index.testbed is assigned by the NoseGAE plugin
    test_index.testbed.init_taskqueue_stub(task_retry_seconds=42, root_path=os.path.dirname(__file__))
    # Assume the `/` route fires off a task queue and should pass without exceptions
    app = TestApp(helloworld.app)
    response = app.get('/')
    assert 'Hello world!' in str(response)

The following test shows how to use the simple method while passing kwargs to the taskqueue stub's initialization method. See examples/issue42_task-queue for full example code.

def test_index():
    # Assume the `/` route fires off a task queue and should pass without exceptions
    app = TestApp(app)
    response = app.get('/')
    assert 'Hello world!' in str(response)

# Enable any stubs needed as attributes off of the test function

# NoseGAE looks for queue.yaml in the root of the
# application when nosegae_taskqueue is True
test_index.nosegae_taskqueue = True

# ...or you can manually set the path and any additional arguments with the kwargs attribute
test_index.nosegae_taskqueue_kwargs = dict(task_retry_seconds=42, root_path=os.path.dirname(__file__))

Doctest

Doctests are a whole other beast. They still work but all TestBed configuration has to be done manually. NoseGAE uses the nose doctest plugin to inject a global variable named testbed into your doctest scope that contains the current active TestBed instance. See examples/pets/models.py for full example.

class Pet(ndb.Model):
    """The Pet class provides storage for pets.

    >>> # Initialize stubs using the injected testbed instance
    >>> testbed.init_memcache_stub()
    >>> testbed.init_datastore_v3_stub()

    You can create a pet:
    >>> muffy = Pet(name=u'muffy', type=u'dog', breed=u"Shi'Tzu")
    >>> muffy_key = muffy.put()
    """
    name = ndb.StringProperty(required=True)
    type = ndb.StringProperty(required=True, choices=("cat", "dog", "bird", "fish", "monkey"))
    breed = ndb.StringProperty()

Changes in 0.5.2

The 0.5.2 release introduces preliminary modules support by allowing multiple yaml or paths sent to the --gae-application command line option.

nosetests --with-gae \
          --gae-application='app.yaml,mobile_frontend.yaml,static_backend.yaml,dispatch.yaml'

Changes in 0.4.0

The 0.4.0 release is a major rewrite to support dev_appserver2. This release introduced two important changes listed below.

Sandbox is gone

Due to changes in the sandboxing mechanisms in dev_appserver2, it isn't possible for NoseGAE to simulate the deployed environment any longer. The sandboxing feature had to be removed since there is no longer any way to toggle it between noses own internal workings.

This means that certain tests may pass locally but the code in question will fail in production due to restricted modules and functions. As of now there is no workaround but pull requests are welcome!

Testbed is set up for you

The new plugin automatically sets up the initial google.appengine.ext.testbed.Testbed instance and injects it into your test cases for you.

nosegae's People

Contributors

gregpsycle avatar hello-josh avatar obmarg avatar sadovnychyi avatar soundtricker avatar yoannmtr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

nosegae's Issues

GAE 1.9.17 release will unfortunately break NoseGAE

Hi,

The old deprecated devappserver is finally going away and we noticed that your project is still depending on the internals of it:

old_dev_appserver.ClearAllButEncodingsModules
old_dev_appserver.FakeFile.SetAllowedPaths
old_dev_appserver.HardenedModulesHook
old_dev_appserver.LoadAppConfig
old_dev_appserver.SetupStubs
old_dev_appserver.SetupSharedModules

dev_appserver_main.DEFAULT_ARGS
dev_appserver_main.ARG_CLEAR_DATASTORE
dev_appserver_main.ARG_LOG_LEVEL
dev_appserver_main.ARG_DATASTORE_PATH
dev_appserver_main.ARG_HISTORY_PATH
[...]

Have you looked into porting it to dev_appserver2 ?

gbin from the Google App Engine SDK team.

Stubs are not activated for appengine_config

I've some api calls inside of appengine_config, and since it's imported before any stubs being activated – my tests fails.

I could probably activate them manually as a workaround, but maybe it's worth to move import appengine_config inside of startTest?

Or, maybe, it's just a bad idea to use any api there.

How to change path of GAE library?

The README states that

The plugin also includes an option for setting the path to the Google App Engine python library, if it is not in the standard location of /usr/local/google_appengine.

How do I set that option?

datastore date mismatch

Hi,

I have a test that writes some entries to the datastore and then deletes all the entries that have been written in the past 5 minutes based on a ndb.DateTimeProperty with auto_now_add set to True. If I run a test that writes to the datastore it will set the DateTimeProperty using the UTC time. However, if right after writing to the datastore, I use the datetime.datetime.now() function it will get the date based on my computers timezone (in my case, that's UTC + 2).

Test:

def test_gae(self):

        TaskTrack(id="Test id",
                  snapshot=self.snapshot.key,
                  process="Test",
                  queue="Queue name").put()

        get_query = TaskTrack.query(
            TaskTrack.process == "Test"
        ).fetch()

        print get_query
        print datetime.now()

This outputs:

[TaskTrack(key=Key('TaskTrack', 'Test id'), enqueued_at=datetime.datetime(2015, 2, 3, 9, 42, 13, 383950), process=u'Test', queue=u'Queue name', snapshot=Key('Snapshot', 20))]

2015-02-03 11:42:13.389502

As far as I can tell, using UTC is intended behavior for dev_appserver2.py and the environment should have inherited, but doesn't (please see below a piece of code from dev_appserver2.py). What am I missing?

def main():
  shutdown.install_signal_handlers()
  # The timezone must be set in the devappserver2 process rather than just in
  # the runtime so printed log timestamps are consistent and the taskqueue stub
  # expects the timezone to be UTC. The runtime inherits the environment.
  os.environ['TZ'] = 'UTC'
  if hasattr(time, 'tzset'):
    # time.tzet() should be called on Unix, but doesn't exist on Windows.
    time.tzset()
  options = PARSER.parse_args()
  dev_server = DevelopmentServer()
  try:
    dev_server.start(options)
    shutdown.wait_until_shutdown()
  finally:
    dev_server.stop()

This is my model:

class TaskTrack(BaseModel):
    enqueued_at = ndb.DateTimeProperty(auto_now_add=True)
    snapshot = ndb.KeyProperty(kind=Snapshot)
    process = ndb.StringProperty()
    queue = ndb.StringProperty(required=True)

Error when running tests while dev_appserver is running

Hello,

It used to be the case that my tests would run fine while the dev_appserver was running (i.e., my app is being served at localhost). Now, when dev_appserver is running, I get the error below and nose freezes so I have to kill the process.

$ nosetests -x tests/unit_tests.py
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/bin/nosetests", line 8, in
load_entry_point('nose==1.1.2', 'console_scripts', 'nosetests')()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose-1.1.2-py2.7.egg/nose/core.py", line 118, in init
*_extra_args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/main.py", line 94, in init
self.parseArgs(argv)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose-1.1.2-py2.7.egg/nose/core.py", line 135, in parseArgs
self.config.configure(argv, doc=self.usage())
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose-1.1.2-py2.7.egg/nose/config.py", line 339, in configure
self.plugins.begin()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose-1.1.2-py2.7.egg/nose/plugins/manager.py", line 94, in call
return self.call(_arg, *_kw)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/nose-1.1.2-py2.7.egg/nose/plugins/manager.py", line 162, in simple
result = meth(_arg, **kw)
File "build/bdist.macosx-10.6-intel/egg/nosegae.py", line 127, in begin
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 793, in start
self._dispatcher.start(options.api_host, apis.port, request_data)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 183, in start
_module.start()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/module.py", line 1185, in start
self._balanced_module.start()
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/wsgi_server.py", line 312, in start
self._start_all_fixed_port(host_ports)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/wsgi_server.py", line 349, in _start_all_fixed_port
raise BindError('Unable to bind %s:%s' % self.bind_addr)
google.appengine.tools.devappserver2.wsgi_server.BindError: Unable to bind localhost:8080

Nosegae won't run tests with @ndb.transactional(xg=True)

Hello,

I'm trying to run some tests that uses NDB transactions

If a certain method has this: @ndb.transactional() my tests will run

But if I put this @ndb.transactional(xg=True) this error is thrown:

Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/mock-2.0.0-py2.7.egg/mock/mock.py", line 1305, in patched
    return func(*args, **keywargs)
  File "/home/dyego/Documents/code-stuff/mod/pdbcontest2/src/tests/core/main/test_centraldistdraw.py", line 291, in test_get_savedatastore_savePart
    draw.saveDataStore(user, pincode, [1,2,3,4,5])
  File "/home/dyego/Downloads/google_appengine/google/appengine/ext/ndb/utils.py", line 197, in inner_wrapper
    return wrapped_decorator(func, args, kwds, **options)
  File "/home/dyego/Downloads/google_appengine/google/appengine/ext/ndb/model.py", line 3834, in transactional
    func, args, kwds, **options).get_result()
  File "/home/dyego/Downloads/google_appengine/google/appengine/ext/ndb/tasklets.py", line 383, in get_result
    self.check_success()
  File "/home/dyego/Downloads/google_appengine/google/appengine/ext/ndb/tasklets.py", line 427, in _help_tasklet_along
    value = gen.throw(exc.__class__, exc, tb)
  File "/home/dyego/Downloads/google_appengine/google/appengine/ext/ndb/context.py", line 991, in transaction
    transaction = yield parent._conn.async_begin_transaction(options, app)
  File "/home/dyego/Downloads/google_appengine/google/appengine/ext/ndb/tasklets.py", line 513, in _on_rpc_completion
    result = rpc.get_result()
  File "/home/dyego/Downloads/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
    return self.__get_result_hook(self)
  File "/home/dyego/Downloads/google_appengine/google/appengine/datastore/datastore_rpc.py", line 2040, in __begin_transaction_hook
    self.check_rpc_success(rpc)
  File "/home/dyego/Downloads/google_appengine/google/appengine/datastore/datastore_rpc.py", line 1373, in check_rpc_success
    raise _ToDatastoreError(err)
BadRequestError: transactions on multiple entity groups only allowed with the High Replication datastore

Is there a way to simply ignore this?

Thanks

raise AttributeError: 'ApplicationConfiguration' object has no attribute 'modules'

raise Exception with GAE sdk 1.9.17

Traceback (most recent call last):
  File "/home/travis/virtualenv/python2.7.9/bin/nosetests", line 11, in <module>
    sys.exit(run_exit())
  File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/nose/core.py", line 121, in __init__
    **extra_args)
  File "/opt/python/2.7.9/lib/python2.7/unittest/main.py", line 94, in __init__
    self.parseArgs(argv)
  File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/nose/core.py", line 145, in parseArgs
    self.config.configure(argv, doc=self.usage())
  File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/nose/config.py", line 346, in configure
    self.plugins.configure(options, self)
  File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/nose/plugins/manager.py", line 284, in configure
    cfg(options, config)
  File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/nose/plugins/manager.py", line 99, in __call__
    return self.call(*arg, **kw)
  File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/nose/plugins/manager.py", line 167, in simple
    result = meth(*arg, **kw)
  File "/home/travis/virtualenv/python2.7.9/lib/python2.7/site-packages/nosegae.py", line 93, in configure
    os.environ['CURRENT_VERSION_ID'] = configuration.modules[0].version_id
AttributeError: 'ApplicationConfiguration' object has no attribute 'modules'

A example, this is not my project, but got the same error message.
https://travis-ci.org/uwescience/myria-web

Investigate using thread locals to store testbed and stubs

I don't exactly like that I am attaching the testbed instance to the object/function that is being run. I am considering using thread-locals Flask style or maybe another solution depending on how nose handles threading / multiprocessing.

PyCharm

Is there a way to add this to Pycharm?

Suppressing DEBUG messages in output

Hi everyone,

This is a feature request or perhaps a request for help in case anyone knows a good solution...

I'm now getting a ton (thousands of lines) of DEBUG messages in my test output. A snippet is shown below. I think this started happening when I started using the GCS Python client library. It is really annoying to have to page up through the thousands of lines of debug messages to see why my tests are failing.

Does anyone know a way to suppress the DEBUG messages in the test output?

Jeff

$ nosetests -x tests/unit_tests.py
...........F
======================================================================
FAIL: testCreateAPI (tests.unit_tests.CountTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/.../tests/unit_tests.py", line 873, in testCreateAPI
    self.assertEqual(...)
AssertionError: ...
-------------------- >> begin captured logging << --------------------
root: DEBUG: all_pending: add <Future 105dbe5d0 created by eager_wrapper(api_utils.py:349) for tasklet do_request_async(storage_api.py:112); result (201, {'content-length': '0', 'content-type': 'text/plain', 'location': 'https://storage.googleapis.com//opavote/count/1/0.blt?upload_id=encoded_gs_file%3Ab3Bhdm90ZS9jb3VudC8xLzAuYmx0'}, '')>
root: DEBUG: nowevent: _help_tasklet_along
root: DEBUG: Sending None to initial generator do_request_async(storage_api.py:112)
root: DEBUG: all_pending: add <Future 105ded790 created by do_request_async(storage_api.py:128) for tasklet do_request_async(rest_api.py:158); result (201, {'content-length': '0', 'content-type': 'text/plain', 'location': '...?upload_id=encoded_gs_file%3Ab3Bhdm90ZS9jb3VudC8xLzAuYmx0'}, '')>
root: DEBUG: initial generator do_request_async(storage_api.py:112) yielded <Future 105ded790 created by do_request_async(storage_api.py:128) for tasklet do_request_async(rest_api.py:158); result (201, {'content-length': '0', 'content-type': 'text/plain', 'location': 'https://storage.googleapis.com//count/1/0.blt?upload_id=encoded_gs_file%3Ab3Bhdm90ZS9jb3VudC8xLzAuYmx0'}, '')>
root: DEBUG: <Future 105dbe5d0 created by eager_wrapper(api_utils.py:349) for tasklet do_request_async(storage_api.py:112); result (201, {'content-length': '0', 'content-type': 'text/plain', 'location': 'https://storage.googleapis.com//count/1/0.blt?upload_id=encoded_gs_file%3Ab3Bhdm90ZS9jb3VudC8xLzAuYmx0'}, '')> is now blocked waiting for <Future 105ded790 created by do_request_async(storage_api.py:128) for tasklet do_request_async(rest_api.py:158); result (201, {'content-length': '0', 'content-type': 'text/plain', 'location': 'https://storage.googleapis.com//count/1/0.blt?upload_id=encoded_gs_file%3Ab3Bhdm90ZS9jb3VudC8xLzAuYmx0'}, '')>
root: DEBUG: nowevent: _help_tasklet_along
...

Imports are not properly handled while running tests in parallel

Given a test case:

import unittest
import mock

class TestTest(unittest.TestCase):
  def test_test(self):
    print dir(__import__('google'))
    with mock.patch('google.appengine.api.urlfetch.fetch'):
      pass
$ nosetests --with-gae --processes=0
Ran 1 test in 0.187s
OK
$ nosetests --with-gae --processes=1
======================================================================
ERROR: test_test (test_test.TestTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/sadovnychyi/example/test_test.py", line 8, in test_test
    with mock.patch('google.appengine.api.urlfetch.fetch'):
  File "/usr/local/lib/python2.7/site-packages/mock.py", line 1252, in __enter__
    self.target = self.getter()
  File "/usr/local/lib/python2.7/site-packages/mock.py", line 1414, in <lambda>
    getter = lambda: _importer(target)
  File "/usr/local/lib/python2.7/site-packages/mock.py", line 1102, in _importer
    thing = _dot_lookup(thing, comp, import_path)
  File "/usr/local/lib/python2.7/site-packages/mock.py", line 1092, in _dot_lookup
    return getattr(thing, comp)
AttributeError: 'module' object has no attribute 'appengine'
-------------------- >> begin captured stdout << ---------------------
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'net']

I spend a lot of time trying to understand this error. Then cached that it appears only with multi process test runner. Any idea why its happening and how to fix it?

Unable to use app engine Modules with NoseGAE

Hi there,

I've been trying to use more than one app engine module with NoseGAE but it doesn't seem possible. when I run dev_appserver.py api-v1/ php-ancillary-services.yaml I am specifying firstly my project root and then my additional module, however I can't seem to find a way to do this in my functional tests? The error I am getting is..

  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/modules/modules.py", line 146, in _CheckAsyncResult
    raise mapped_error()
InvalidModuleError

I assume this is because noseGAE has no idea about my additional modules, but how would I let NoseGAE know about my additional modules? I tried changing some of the source for NoseGAE but I can't get it working. I don't think this'll be something I can get working myself so would appreciate any help.

nose wants to test vendored libraries

My app is based on appengine-flask-skeleton , which uses vendoring to place third-party libraries in lib. NoseGAE seems to search all those libraries for tests. They aren’t designed for nose-style test matching. What can I do to exclude them?

One example of this seems to be Flask’s make_test_environ_builder which seems to show up in the following run:

appengine-flask-skeleton nop$ nosetests --with-gae
EEE............EEEEEEEEEEEEEEEE................EE
======================================================================
ERROR: Creates a new test builder with some application defaults thrown in.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
TypeError: make_test_environ_builder() takes at least 1 argument (0 given)

I’ve attached the full log.
nosegae-on-skeleton.txt

App Engine SDK 1.9.17 removes old_dev_appserver.py

From the 1.9.17 Python release notes:

The old development appserver (old_dev_appserver.py) has been removed from the SDK

This causes nosetests --with-gae to fail:

from google.appengine.tools import old_dev_appserver as dev_appserver
ImportError: cannot import name old_dev_appserver

ImportError: cannot import name pem

I'm writting test case for my app hosted on Google app engine and when running the following command an import error occurs
nosetests -w tests --logging-level=ERROR --with-gae --gae-application=path_to_yaml_file --gae-lib-root=path_to_appengine

Following is the stacktrace of error message

Traceback (most recent call last): File "/home/daffodil/Desktop/museconnect/venv/local/lib/python2.7/site-packages/nose/loader.py", line 418, in loadTestsFromName addr.filename, addr.module) File "/home/daffodil/Desktop/museconnect/venv/local/lib/python2.7/site-packages/nose/importer.py", line 47, in importFromPath return self.importFromDir(dir_path, fqname) File "/home/daffodil/Desktop/museconnect/venv/local/lib/python2.7/site-packages/nose/importer.py", line 94, in importFromDir mod = load_module(part_fqname, fh, filename, desc) File "/home/daffodil/Desktop/museconnect/tests/api/test_groups.py", line 8, in <module> from main import app File "/home/daffodil/Desktop/museconnect/main.py", line 5, in <module> from apis import api_blueprint File "/home/daffodil/Desktop/museconnect/apis/__init__.py", line 4, in <module> from .clients import api as clients File "/home/daffodil/Desktop/museconnect/apis/clients.py", line 4, in <module> from model.museconnect import ( File "/home/daffodil/Desktop/museconnect/model/museconnect.py", line 2, in <module> from model.user import User File "/home/daffodil/Desktop/museconnect/model/user.py", line 10, in <module> from google.cloud import storage, exceptions File "/home/daffodil/Desktop/museconnect/venv/local/lib/python2.7/site-packages/google/cloud/storage/__init__.py", line 36,in <module> from google.cloud.storage.client import Client File "/home/daffodil/Desktop/museconnect/venv/local/lib/python2.7/site-packages/google/cloud/storage/client.py", line 19, in <module> from google.cloud.client import JSONClient File "/home/daffodil/Desktop/museconnect/venv/local/lib/python2.7/site-packages/google/cloud/client.py", line 18, in <module> from google.oauth2 import service_account File "/home/daffodil/Desktop/museconnect/appvendor/google/oauth2/service_account.py", line 77, in <module> from google.auth import _service_account_info File "/home/daffodil/Desktop/museconnect/appvendor/google/auth/_service_account_info.py", line 22, in <module> from google.auth import crypt File "/home/daffodil/Desktop/museconnect/appvendor/google/auth/crypt/__init__.py", line 39, in <module> from google.auth.crypt import rsa File "/home/daffodil/Desktop/museconnect/appvendor/google/auth/crypt/rsa.py", line 27, in <module> from google.auth.crypt import _python_rsa File "/home/daffodil/Desktop/museconnect/appvendor/google/auth/crypt/_python_rsa.py", line 25, in <module> from pyasn1_modules import pem ImportError: cannot import name pem

There are two pyasn1_modules... one in the google-cloud-sdk/platform/google_appengine/lib/ folder and other in appvendor folder of my app directory. The later one has pem.py file but the first one doesn't.

Prospective Search is no longer in the SDK

After a recent SDK update, I'm seeing ImportError: No module named prospective_search.prospective_search_stub from NoseGAE:

Traceback (most recent call last):
  File "/Users/jason/dev/gain-filing/venv/lib/python2.7/site-packages/nose/case.py", line 133, in run
    self.runTest(result)
  File "/Users/jason/dev/gain-filing/venv/lib/python2.7/site-packages/nose/case.py", line 151, in runTest
    test(result)
  File "/usr/local/Cellar/python/2.7.12/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 393, in __call__
    return self.run(*args, **kwds)
  File "/usr/local/Cellar/python/2.7.12/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 304, in run
    result.startTest(self)
  File "/Users/jason/dev/gain-filing/venv/lib/python2.7/site-packages/nose/proxy.py", line 169, in startTest
    self.plugins.startTest(self.test)
  File "/Users/jason/dev/gain-filing/venv/lib/python2.7/site-packages/nose/plugins/manager.py", line 99, in __call__
    return self.call(*arg, **kw)
  File "/Users/jason/dev/gain-filing/venv/lib/python2.7/site-packages/nose/plugins/manager.py", line 167, in simple
    result = meth(*arg, **kw)
  File "/Users/jason/dev/gain-filing/venv/lib/python2.7/site-packages/nosegae.py", line 144, in startTest
    self._add_missing_stubs(testbed)
  File "/Users/jason/dev/gain-filing/venv/lib/python2.7/site-packages/nosegae.py", line 192, in _add_missing_stubs
    from google.appengine.api.prospective_search.prospective_search_stub import ProspectiveSearchStub
ImportError: No module named prospective_search.prospective_search_stub

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.