সেলারি ডকুমেন্টেশনে জ্যাঙ্গোর মধ্যে সিলারি টেস্টিংয়ের উল্লেখ রয়েছে তবে আপনি যদি জ্যাঙ্গো ব্যবহার না করে তবে সেলারি টাস্কটি কীভাবে পরীক্ষা করবেন তা ব্যাখ্যা করে না। তুমি এটা কিভাবে করো?
সেলারি ডকুমেন্টেশনে জ্যাঙ্গোর মধ্যে সিলারি টেস্টিংয়ের উল্লেখ রয়েছে তবে আপনি যদি জ্যাঙ্গো ব্যবহার না করে তবে সেলারি টাস্কটি কীভাবে পরীক্ষা করবেন তা ব্যাখ্যা করে না। তুমি এটা কিভাবে করো?
উত্তর:
সেখানে যেকোন ইউনিট লাইব ব্যবহার করে সিঙ্ক্রোনসিভ করে কাজগুলি পরীক্ষা করা সম্ভব। সেলারি কাজের সাথে কাজ করার সময় আমি সাধারণত 2 টি পৃথক পরীক্ষার সেশন করি do প্রথমটি (যেমন আমি বেলো পরামর্শ দিচ্ছি) সম্পূর্ণ সিঙ্ক্রোনাস এবং এটি এমন একটি হওয়া উচিত যা নিশ্চিত করে যে অ্যালগরিদম এটি করা উচিত does দ্বিতীয় সেশনে পুরো সিস্টেমটি (ব্রোকার সহ) ব্যবহার করে এবং নিশ্চিত করে যে আমার সিরিয়ালাইজেশন সমস্যা বা অন্য কোনও বিতরণ, যোগাযোগের সমস্যা নেই।
তাই:
from celery import Celery
celery = Celery()
@celery.task
def add(x, y):
return x + y
এবং আপনার পরীক্ষা:
from nose.tools import eq_
def test_add_task():
rst = add.apply(args=(4, 4)).get()
eq_(rst, 8)
আশা করি এইটি কাজ করবে!
celery.loader.import_default_modules()
।
আমি এটি ব্যবহার:
with mock.patch('celeryconfig.CELERY_ALWAYS_EAGER', True, create=True):
...
দস্তাবেজ: http://docs.celeryproject.org/en/3.1/configration.html#celery-always-eager
CELERY_ALWAYS_EAGER আপনাকে আপনার টাস্ক সিঙ্ক্রোনাস চালাতে দেয় এবং আপনার সেলারি সার্ভারের দরকার নেই।
ImportError: No module named celeryconfig
।
celeryconfig.py
কারও প্যাকেজে মডিউল বিদ্যমান। ডকস.সিলারিপ্রজেক্ট.আর.এন . / স্লেস্ট / বাজেটিং-স্টার্টড/ … দেখুন ।
add
মধ্যে ওপির প্রশ্ন থেকে কাজগুলি লঞ্চ করবেন তার পুরো উদাহরণ সরবরাহ করতে পারেন TestCase
?
CELERY_TASK_ALWAYS_EAGER
ইউনিট পরীক্ষার জন্য ব্যবহারকে নিরুৎসাহিত করে ।
আপনি ঠিক কী পরীক্ষা করতে চান তার উপর নির্ভর করে।
import unittest
from myproject.myapp import celeryapp
class TestMyCeleryWorker(unittest.TestCase):
def setUp(self):
celeryapp.conf.update(CELERY_ALWAYS_EAGER=True)
# conftest.py
from myproject.myapp import celeryapp
@pytest.fixture(scope='module')
def celery_app(request):
celeryapp.conf.update(CELERY_ALWAYS_EAGER=True)
return celeryapp
# test_tasks.py
def test_some_task(celery_app):
...
from celery import current_app
def send_task(name, args=(), kwargs={}, **opts):
# https://github.com/celery/celery/issues/581
task = current_app.tasks[name]
return task.apply(args, kwargs, **opts)
current_app.send_task = send_task
সিলারি 4 এর জন্য এটি এটি:
@override_settings(CELERY_TASK_ALWAYS_EAGER=True)
কারণ সেটিংসের নামগুলি পরিবর্তন করা হয়েছে এবং আপনি আপগ্রেড করতে পছন্দ করে থাকলে আপডেট করার প্রয়োজন রয়েছে, দেখুন
এর মতো সেলারি 3.0 , সেট করার একটা উপায় CELERY_ALWAYS_EAGER
মধ্যে জ্যাঙ্গো হল:
from django.test import TestCase, override_settings
from .foo import foo_celery_task
class MyTest(TestCase):
@override_settings(CELERY_ALWAYS_EAGER=True)
def test_foo(self):
self.assertTrue(foo_celery_task.delay())
সেলারি যেহেতু v4.0 , py.test রাজধানী হয় প্রদান করা মাত্র পরীক্ষার জন্য একটি সেলারি কর্মী শুরু করার জন্য এবং বন্ধ হয়ে যায় যখন সম্পন্ন হয়েছে:
def test_myfunc_is_executed(celery_session_worker):
# celery_session_worker: <Worker: gen93553@gnpill.local (running)>
assert myfunc.delay().wait(3)
Http://docs.celeryproject.org/en/latest/userguide/testing.html#py-test- এ বর্ণিত অন্যান্য ফিক্সারের মধ্যে , আপনি সেলাইর ডিফল্ট বিকল্পগুলিকে celery_config
এইভাবে পুনরায় সংজ্ঞা দিয়ে পরিবর্তন করতে পারেন :
@pytest.fixture(scope='session')
def celery_config():
return {
'accept_content': ['json', 'pickle'],
'result_serializer': 'pickle',
}
ডিফল্টরূপে, পরীক্ষাকর্মী একটি ইন-মেমরি ব্রোকার এবং ফলাফল ব্যাকএন্ড ব্যবহার করে। নির্দিষ্ট বৈশিষ্ট্যগুলি পরীক্ষা না করা হলে স্থানীয় রেডিস বা রেবিটএমকিউ ব্যবহার করার দরকার নেই।
পাইস্ট ব্যবহার করে রেফারেন্স ।
def test_add(celery_worker):
mytask.delay()
যদি আপনি ফ্লাস্ক ব্যবহার করেন তবে অ্যাপ্লিকেশন কনফিগারেশন সেট করুন
CELERY_BROKER_URL = 'memory://'
CELERY_RESULT_BACKEND = 'cache+memory://'
এবং ভিতরে conftest.py
@pytest.fixture
def app():
yield app # Your actual Flask application
@pytest.fixture
def celery_app(app):
from celery.contrib.testing import tasks # need it
yield celery_app # Your actual Flask-Celery application
আমার ক্ষেত্রে (এবং আমি আরও অনেককে ধরে নিই), আমি যা চেয়েছিলাম তা হ'ল পাইস্ট ব্যবহার করে কোনও কাজের অভ্যন্তরীণ যুক্তি পরীক্ষা করা।
টি এল; ডিআর; দূরে সবকিছু ঠাট্টা করা শেষ ( অপশন 2 )
উদাহরণ ব্যবহারের কেস :
proj/tasks.py
@shared_task(bind=True)
def add_task(self, a, b):
return a+b;
tests/test_tasks.py
from proj import add_task
def test_add():
assert add_task(1, 2) == 3, '1 + 2 should equal 3'
তবে, যেহেতু shared_task
সাজসজ্জাকারী সেলারি অভ্যন্তরীণ যুক্তিযুক্ত অনেকগুলি কাজ করে, এটি আসলে কোনও ইউনিট পরীক্ষা নয়।
সুতরাং, আমার জন্য, 2 টি বিকল্প ছিল:
বিকল্প 1: পৃথক অভ্যন্তরীণ যুক্তি
proj/tasks_logic.py
def internal_add(a, b):
return a + b;
proj/tasks.py
from .tasks_logic import internal_add
@shared_task(bind=True)
def add_task(self, a, b):
return internal_add(a, b);
এটি দেখতে খুব অদ্ভুত দেখাচ্ছে এবং এটিকে কম পঠনযোগ্য করে তোলা ব্যতীত এটির অনুরোধের অংশ হ'ল বৈশিষ্ট্যগুলি ম্যানুয়ালি নিষ্কাশন করতে এবং পাস করতে হবে, উদাহরণস্বরূপ task_id
আপনার প্রয়োজনের ক্ষেত্রে এটি যুক্তিটিকে আরও শুদ্ধ করে তোলে।
বিকল্প 2:
সেলারি ইন্টার্নালগুলি উপহাস করে
tests/__init__.py
# noinspection PyUnresolvedReferences
from celery import shared_task
from mock import patch
def mock_signature(**kwargs):
return {}
def mocked_shared_task(*decorator_args, **decorator_kwargs):
def mocked_shared_decorator(func):
func.signature = func.si = func.s = mock_signature
return func
return mocked_shared_decorator
patch('celery.shared_task', mocked_shared_task).start()
যা আমাকে অনুরোধের অবজেক্টটিকে আবার উপহাস করার অনুমতি দেয় (আবার, যদি আপনাকে অনুরোধ থেকে আইডির মতো জিনিসগুলি বা পুনরায় চেষ্টা কাউন্টারের প্রয়োজন হয়)।
tests/test_tasks.py
from proj import add_task
class MockedRequest:
def __init__(self, id=None):
self.id = id or 1
class MockedTask:
def __init__(self, id=None):
self.request = MockedRequest(id=id)
def test_add():
mocked_task = MockedTask(id=3)
assert add_task(mocked_task, 1, 2) == 3, '1 + 2 should equal 3'
এই সমাধান অনেক বেশি ম্যানুয়াল, কিন্তু, আমার নিয়ন্ত্রণ আমি আসলে প্রয়োজন দেয় ইউনিট পরীক্ষা, নিজেকে পুনরাবৃত্তি ছাড়া, এবং সেলারি সুযোগ হারানো ছাড়া।