I'm using testbed to unit test my google app engine app, and my app uses a taskqueue.
When I submit a task to a taskqueue during a unit test, it appears that the task is in the queue, but the task does not execute.
How do I get the task to execute during a unit test?
Another (cleaner) option to achieve this is to use the task queue stub within the testbed. To do this you first have to initialize the task queue stub by adding the following to your
setUp()
method:The tasks scheduler can be accessed using the following code:
The interface for working with the queue stub is as follows:
Also, as this uses App Engine SDK own facilities - it works just fine with the deferred library.
Using Saxon's excellent answer, I was able to do the same thing using testbed instead of gaetestbed. Here is what I did.
Added this to my
setUp()
:Then, in my test, I used the following:
Somewhere along the line, the POST parameters get base64 encoded so had to undo that to get it to work.
I like this better than Saxon's answer since I can use the official testbed package and I can do it all within my own test code.
EDIT: I later wanted to do the same thing with tasks submitted using the deferred library, and it took a bit of headbanging to figure it, so I'm sharing here to ease other people's pain.
If your taskqueue contains only tasks submitted with deferred, then this will run all of the tasks and any tasks queued by those tasks:
You might want to try the following code. Full explanation is here: http://www.geewax.org/task-queue-support-in-app-engines-ext-testbed/
The dev app server is single-threaded, so it can't run tasks in the background while the foreground thread is running the tests.
I modified TaskQueueTestCase in taskqueue.py in gaetestbed to add the following function:
For this to work, I also had to change the base class of TaskQueueTestCase from BaseTestCase to WebTestCase.
My tests then do something like this:
This therefore executes the task directly from the foreground unit test. This is not quite the same as in production (ie, the task will get executed 'some time later' on a separate request), but it works well enough for me.