2014-04-09 9 views
6

में एक ही परीक्षण डेटाबेस का उपयोग करके मैं निम्नलिखित डीबी सेटिंग्स के साथ एक परीक्षण डेटाबेस का उपयोग कर pytests चला रहा हूँ।Django: एक अलग थ्रेड

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.postgresql_psycopg2', 
     'NAME': 'postgres', 
     'USER': 'something', 
     'PASSWORD': 'password', 

    }, 
} 

@ pytest.mark.django_db का उपयोग करना, अपने परीक्षण कार्यों एक डेटाबेस 'test_postgres' परीक्षण के लिए बनाया बुलाया एक्सेस करते हैं।

@pytest.mark.django_db 
def test_example(): 
    from django.db import connection 
    cur_ = connection.cursor() 
    print cur_.db.settings_dict 

आउटपुट:

{'ENGINE': 'django.db.backends.postgresql_psycopg2', 'AUTOCOMMIT': True, 'ATOMIC_REQUESTS': False, 'NAME': 'test_postgres', 'TEST_MIRROR': None,... 

लेकिन अगर मैं test_example अंदर एक धागा चलाएँ:

मुझे लगता है कि सूत्र में कर्सर का उपयोग कर रहा है डेटाबेस 'postgres' नाम दिया है कि देख सकते हैं जो है गैर परीक्षण डेटाबेस। आउटपुट:

{'ENGINE': 'django.db.backends.postgresql_psycopg2', 'AUTOCOMMIT': True, 'ATOMIC_REQUESTS': False, 'NAME': 'postgres', 'TEST_MIRROR': None,... 

वहाँ मूल परीक्षण समारोह से मेरी धागा करने के लिए डेटाबेस कनेक्शन तर्क गुजरती हैं और अपने परीक्षण समारोह के रूप में एक ही डेटाबेस नाम ('test_postgres') का उपयोग करने के लिए अपने धागा दिनचर्या को बताने के लिए एक तरीका है?

उत्तर

1

मुझे मेरी समस्या का समाधान मिला।

सबसे पहले आप निम्न डेटाबेस सेटिंग के साथ परीक्षण (settings_pytest.py) के लिए एक अलग Django सेटिंग्स फ़ाइल तैयार:

DATABASES = { 
    'default': { 
     'ENGINE': 'django.db.backends.postgresql_psycopg2', 
     'NAME': 'test_database', 
     'TEST_NAME': 'test_database', 
     'USER': 'something', 
     'PASSWORD': 'password', 

    }, 
} 

सूचना है कि हम TEST_NAME को परिभाषित है, और यह नाम के समान होता है, जिससे माध्यम से चल रहे परीक्षण धावक या नहीं, हम एक ही डेटाबेस तक पहुंचेंगे।

py.test --reuse-db 

आप की जरूरत है:

sql> CREATE DATABASE test_database; 

manage.py syncdb --settings=settings_pytest 

manage.py migrate --settings=settings_pytest 

अंत में आप के साथ अपने परीक्षण चला सकते हैं:

अब आप और चलाने के लिए उस पर 'syncdb' और 'विस्थापित' पहली बार इस डेटाबेस बनाने की जरूरत है, निर्दिष्ट करें --reuse-db, डेटाबेस पुन: निर्माण कभी भी काम नहीं करेगा क्योंकि डिफ़ॉल्ट डेटाबेस परीक्षण डेटाबेस के समान है। यदि आपके डेटाबेस में बदलाव हैं तो आपको ऊपर दिए गए आदेशों के साथ मैन्युअल रूप से डेटाबेस को फिर से बनाना होगा।

परीक्षण के लिए, यदि आप डेटाबेस में रिकॉर्ड्स जोड़ रहे हैं जिसे आपको जन्मजात बाल प्रक्रिया द्वारा एक्सेस किया जाना है, तो सबसे अच्छा सजावटी के लिए लेनदेन = सही जोड़ना याद रखें। आपके सुझाव के लिए

def function_to_run(): 

    Model.objects.count() == 1 

@pytest.mark.django_db(transaction=True) 
def test_example(): 
    obj_ = Model() 
    obj_.save() 
    p = multiprocessing.Process(target=function_to_run) 
    p.start() 
0

आपके function_to_run() घोषणा में आप from django.db import connection कर रहे हैं। क्या आप वाकई सही परीक्षण डीबी सेटिंग्स का उपयोग करेंगे? मुझे संदेह है कि आप जिस सजावटी का उपयोग कर रहे हैं, connection आयात को का उपयोग postgres के बजाय आयात करने के लिए संशोधित करता है, लेकिन क्योंकि आप सजावटी के दायरे से बाहर आयात कर रहे हैं, यह सही का उपयोग नहीं कर रहा है। यदि आप इसे इतना पसंद किया डेकोरेटर स्वरुप में समारोह के अंदर डाल दिया तो क्या होगा ...

@pytest.mark.django_db 
def test_example(): 

    def function_to_run(): 
     from django.db import connection 
     cur_ = connection.cursor 
     logger.error(cur_.db.settings_dict) 

    p = multiprocessing.Process(target=function_to_run) 
    p.start() 

संपादित करें:

मैं तो मैं इस बिंदु पर अंधेरे में शूटिंग कर रहा हूँ pytest_django से परिचित नहीं हूँ, मैं कल्पना करें कि मार्कर फ़ंक्शन आपको कक्षा को सजाने की अनुमति देता है, इसलिए क्या आपने इस परीक्षण फ़ंक्शन और डीबी को एक टेस्टकेस क्लास में उपयोग करने वाले सभी परीक्षणों को डालने का प्रयास किया है? इस तरह:

from django.test import TestCase 

@pytest.mark.django_db 
class ThreadDBTests(TestCase): 

    # The function we want to share among tests 
    def function_to_run(): 
     from django.db import connection 
     cur_ = connection.cursor 
     logger.error(cur_.db.settings_dict) 

    # One of our tests taht needs the db 
    def test_example1(): 
     p = multiprocessing.Process(target=function_to_run) 
     p.start() 

    # Another test that needs the DB 
    def test_example2(): 
     p = multiprocessing.Process(target=function_to_run) 
     p.start() 
+0

धन्यवाद, ऊपर एक 'PicklingError: <0x0000000006901208 पर समारोह function_to_run> अचार नहीं कर सकता: यह के रूप में नहीं मिला है ...' देता है। इसके अलावा, मैं कई परीक्षणों के बीच थ्रेड फ़ंक्शन साझा करना चाहता हूं। मैंने pytest.mark.db के साथ थ्रेड फ़ंक्शन को सजाने की कोशिश की, हालांकि यह कुछ भी नहीं करेगा क्योंकि यह मल्टीप्रोसेसिंग मॉड्यूल के माध्यम से चलाया जाता है, न कि परीक्षण धावक। – mpaf

+0

ने मेरा उत्तर – ptr

+0

अपडेट किया है, मैंने इसे क्लास विधि बनाने का प्रयास किया है, लेकिन फिर भी डेटाबेस का उपयोग डिफ़ॉल्ट डेटाबेस है, परीक्षण डेटाबेस नहीं। मुझे लगता है कि समस्या यह है कि हम किसी भी django परीक्षण धावकों के माध्यम से बाल प्रक्रिया नहीं चला रहे हैं - जो मैं नहीं चाहता क्योंकि यह एक परीक्षण नहीं है (कोई पास/असफल नहीं है)। मैं उस बच्चे की प्रक्रिया की django सेटिंग्स को नियंत्रित करने में सक्षम होना चाहता हूं, लेकिन मैं सक्षम नहीं हूं। – mpaf

संबंधित मुद्दे