Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run a Celery worker that connects to the Django Test DB

BACKGROUND: I'm working on a project that uses Celery to schedule tasks that will run at a certain time in the future. These tasks push the state of the Final State Machine forward. Here's an example:

  • A future reminder is scheduled to be sent to the user in 2 days.
  • When that scheduled task runs, an email is sent, and the FSM is advanced to the next state
  • The next state is to schedule a reminder to run in another two days
  • When this task runs, it will send another email, advance state
  • Etc...

I'm currently using CELERY_ALWAYS_EAGER as suggested by this SO answer

The problem with using that technique in tests, is that the task code, which is meant to run in a separate thread is running in the same one as the one that schedules it. This causes the FSM state to not be saved properly, and making it hard to test. I haven't been able to determine what exactly causes it, but it seems like at the bottom of the call stack you are saving to the current state, but as you return up the call stack, a previous state is being saved. I could possibly spend more time determining what is going wrong when the code is not running how it should, but it seems more logical to try to get the code running how it should and make sure it's doing what it should.

QUESTION: I would therefore like to know if there is a way to run a full on celery setup that django can use during a test run. If it could be run automagically, that would be ideal, but even some manual intervention would be better than having to test behavior by hand. I'm thinking something could be possible if I set a break in the tests, run the celery worker to connect to the test DB, continue the django tests. Has anyone tried something like this before?

like image 895
Andres Avatar asked Dec 17 '13 15:12

Andres


1 Answers

What you are trying to do is not unit testing but rather functional / integration testing.

I would recommend to use some BDD framework (Behave, Lettuce) and run BDD tests from a CI server (TravisCI or Jenkins) against external server (staging environment for example).

So, the process could be:

  1. Push changes to GitHub
  2. GitHub launches build on CI server
  3. CI server runs unit tests
  4. CI server deploys to integration environment (or staging, if you don't have integration)
  5. CI server runs integration end to end tests against the new deployed code
  6. If all succeeds, this build will be promoted to "can be deploy to production" or something like that
like image 52
Richard Knop Avatar answered Nov 20 '22 11:11

Richard Knop