I'll start using django-rq in my project.
Django integration with RQ, a Redis based Python queuing library.
What is the best practice of testing django apps which is using RQ?
For example, if I want to test my app as a black box, after User makes some actions I want to execute all jobs in current Queue, and then check all results in my DB. How can I do it in my django-tests?
Intro to Testing in Django. Types of tests. Unit and integration are the two main types of tests: Unit Tests are isolated tests that test one specific function. Integration Tests, meanwhile, are larger tests that focus on user behavior and testing entire applications.
The simplest way of using RQ with Django is to use django-rq. Follow the instructions in the README. In order to use RQ together with Django, you have to start the worker in a “Django context”. Possibly, you have to write a custom Django management command to do so.
Free Bonus: Click here to get access to a free Django Learning Resources Guide (PDF) that shows you tips and tricks as well as common pitfalls to avoid when building Python + Django web applications. Unit Tests are isolated tests that test one specific function.
Django is a high level framework to build scalable web applications. Django is used by companies like Google, Facebook, Pinterest, Nasa etc... Code quality is very important in software engineering. We've many types of tests but in this tutorial i will cover two of them :
I separated my rq
tests into a few pieces.
rq
's test suite should cover this).Code being tested:
def handle(self, *args, **options):
uid = options.get('user_id')
# @@@ Need to exclude out users who have gotten an email within $window
# days.
if uid is None:
uids = User.objects.filter(is_active=True, userprofile__waitlisted=False).values_list('id', flat=True)
else:
uids = [uid]
q = rq.Queue(connection=redis.Redis())
for user_id in uids:
q.enqueue(mail_user, user_id)
My tests:
class DjangoMailUsersTest(DjangoTestCase):
def setUp(self):
self.cmd = MailUserCommand()
@patch('redis.Redis')
@patch('rq.Queue')
def test_no_userid_queues_all_userids(self, queue, _):
u1 = UserF.create(userprofile__waitlisted=False)
u2 = UserF.create(userprofile__waitlisted=False)
self.cmd.handle()
self.assertItemsEqual(queue.return_value.enqueue.mock_calls,
[call(ANY, u1.pk), call(ANY, u2.pk)])
@patch('redis.Redis')
@patch('rq.Queue')
def test_waitlisted_people_excluded(self, queue, _):
u1 = UserF.create(userprofile__waitlisted=False)
UserF.create(userprofile__waitlisted=True)
self.cmd.handle()
self.assertItemsEqual(queue.return_value.enqueue.mock_calls, [call(ANY, u1.pk)])
I just found django-rq
, which allows you to spin up a worker in a test environment that executes any tasks on the queue and then quits.
from django.test impor TestCase
from django_rq import get_worker
class MyTest(TestCase):
def test_something_that_creates_jobs(self):
... # Stuff that init jobs.
get_worker().work(burst=True) # Processes all jobs then stop.
... # Asserts that the job stuff is done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With