জাজানোতে বিভিন্ন সেটিংস সহ ইউনিট পরীক্ষা কীভাবে করবেন?


116

ইউনিট পরীক্ষার জন্য জ্যাঙ্গো সেটিংসকে ওভাররাইড করার জন্য কি কোনও সহজ পদ্ধতি আছে? আমার মডেলগুলির একটিতে আমার একজন পরিচালক রয়েছেন যা সর্বশেষতম অবজেক্টগুলির একটি নির্দিষ্ট সংখ্যক ফিরিয়ে দেয়। এটি প্রত্যাবর্তনকারী অবজেক্টের সংখ্যা একটি NUM_LATEST সেটিং দ্বারা সংজ্ঞায়িত করা হয়।

কেউ যদি সেটিংস পরিবর্তন করে থাকে তবে আমার পরীক্ষাগুলিকে ব্যর্থ করার সম্ভাবনা রয়েছে। আমি কীভাবে সেটিংসগুলিকে ওভাররাইড করতে পারি setUp()এবং পরে সেগুলি পুনরুদ্ধার করতে tearDown()পারি? যদি এটি সম্ভব না হয়, তবে আমি উপায়টি প্যাচ করতে বা সেটিংসকে উপহাস করার কোনও উপায় আছে কি?

সম্পাদনা: এখানে আমার পরিচালক কোড:

class LatestManager(models.Manager):
    """
    Returns a specific number of the most recent public Articles as defined by 
    the NEWS_LATEST_MAX setting.
    """
    def get_query_set(self):
        num_latest = getattr(settings, 'NEWS_NUM_LATEST', 10)
        return super(LatestManager, self).get_query_set().filter(is_public=True)[:num_latest]

ম্যানেজার settings.NEWS_LATEST_MAXক্যোরিসেটটি স্লাইস করতে ব্যবহার করে। getattr()কেবল একটি ডিফল্ট সেটিং অস্তিত্ব করা উচিত নয় প্রদান করতে ব্যবহৃত হয়।


@ এন্টো - আপনি ব্যাখ্যা করতে পারেন কেন বা আরও ভাল উত্তর সরবরাহ করতে পারেন?
ব্যবহারকারী

এরই মধ্যে এটি বদলে গেল; সাবেক গৃহীত অন্যতম এই এক );
Anto

উত্তর:


163

সম্পাদনা: আপনি যদি স্বল্প সংখ্যক নির্দিষ্ট পরীক্ষার জন্য সেটিংস পরিবর্তন করতে চান তবে এই উত্তরটি প্রযোজ্য ।

জ্যাঙ্গো ১.৪ থেকে যেহেতু পরীক্ষার সময় সেটিংসকে ওভাররাইড করার উপায় রয়েছে: https://docs.djangoproject.com/en/dev/topics/testing/tools/#overriding-settings

টেস্টকেসে একটি স্ব.সেটেটিং কনটেক্সট ম্যানেজার থাকবে এবং সেখানে একটি @ ওভারাইড_সেটিংস ডেকরেটরও থাকবে যা পরীক্ষার পদ্ধতি বা পুরো টেস্টকেস সাবক্লাসে প্রয়োগ করা যেতে পারে।

এই বৈশিষ্ট্যগুলি জ্যাঙ্গো ১.৩ এ এখনও বিদ্যমান ছিল না।

আপনি যদি আপনার সমস্ত পরীক্ষার জন্য সেটিংস পরিবর্তন করতে চান তবে আপনি পরীক্ষার জন্য একটি পৃথক সেটিংস ফাইল তৈরি করতে চাইবেন যা আপনার মূল সেটিংস ফাইল থেকে সেটিংস লোড এবং ওভাররাইড করতে পারে। অন্যান্য উত্তরে এটির জন্য বেশ কয়েকটি ভাল পন্থা রয়েছে; আমি এইচএসপেন্ডারের এবং উভয় ক্ষেত্রেই সফল পার্থক্য দেখেছি dmitrii এর ঘটায়।


4
আমি বলব এটি এখন সেরা কাজ এটি জ্যাঙ্গো ১.৪++
মাইকেল মায়ার

আপনি পরে কীভাবে পরীক্ষার মধ্যে থেকে সেটিংটি অ্যাক্সেস করবেন? আমি খুঁজে পেয়েছি সেরা এর মতো কিছু self.settings().wrapped.MEDIA_ROOT, তবে এটি বেশ ভয়ঙ্কর।
mlissner

2
জ্যাঙ্গোর নতুন সংস্করণগুলির জন্য এটির
এএন

আমার প্রিয়: @modify_settings(MIDDLEWARE_CLASSES=...(এই উত্তরের জন্য আপনাকে ধন্যবাদ)
guettli

44

আপনি UnitTestসাবক্লাসে পছন্দসই কিছু করতে পারেন , যেমন বৈশিষ্ট্যগুলি সেট করা এবং পড়া সহ:

from django.conf import settings

class MyTest(unittest.TestCase):
   def setUp(self):
       self.old_setting = settings.NUM_LATEST
       settings.NUM_LATEST = 5 # value tested against in the TestCase

   def tearDown(self):
       settings.NUM_LATEST = self.old_setting

যেহেতু জাঙ্গো পরীক্ষার কেসগুলি একক থ্রেডযুক্ত, তাই, আমি কী আগ্রহী যে আরও কী কী NUM_LATEST মানটি সংশোধন করতে পারে? যদি সেই "অন্য কিছু" আপনার পরীক্ষার রুটিন দ্বারা ট্রিগার হয়, তবে আমি নিশ্চিত নই যে কোনও পরিমাণ বানর প্যাচিং পরীক্ষাগুলির সত্যতা অবৈধ না করে পরীক্ষা সংরক্ষণ করবে।


আপনার উদাহরণ কাজ করে। ইউনিট পরীক্ষার সুযোগ এবং পরীক্ষাগুলি ফাইলের সেটিংস কল স্ট্যাকের মাধ্যমে কীভাবে প্রচার করে তা এই দৃষ্টিভঙ্গি হিসাবে বিবেচিত হয়েছে।
সোভিয়েট

এটি দিয়ে কাজ করে না settings.TEMPLATE_LOADERS... সুতরাং এটি কমপক্ষে সাধারণ উপায় নয়, সেটিংস বা জ্যাঙ্গো পুনরায় লোড করা হয়নি বা এই কৌশলটি দিয়ে কোনও কিছুই।
সায়েন্টিক

1
এটি 1.4 এর পরে পুরোনো সংস্করণ জাঙ্গোর জন্য ভাল উদাহরণ। জন্য> = 1.4 উত্তর stackoverflow.com/a/6415129/190127 আরো সঠিক
Oduvan

ব্যবহারের docs.djangoproject.com/en/dev/topics/testing/tools/... সেটআপ এবং টিয়ারডাউন ভালো সঙ্গে প্যাচিং সত্যিই ভঙ্গুর পরীক্ষার যে আরো বাগাড়ম্বরপূর্ণ চেয়ে তারা হতে হবে হয় করতে একটি দুর্দান্ত উপায়। আপনার যদি এমন কোনও প্যাচ দরকার হয় তবে ফ্লেক্সমকের মতো কিছু ব্যবহার করুন।
অস্পষ্ট-ওয়াফল 17

"যেহেতু জ্যাঙ্গো পরীক্ষার মামলাগুলি একক থ্রেডেড চালিত হয়": যা জাজানো ১.৯-এ আর হয় না।
ওয়াটওয়ার

22

যদিও রানটাইমগুলিতে ওভাররাইড সেটিংস কনফিগারেশনটি সহায়তা করতে পারে, আমার মতে আপনার পরীক্ষার জন্য একটি পৃথক ফাইল তৈরি করা উচিত। এটি পরীক্ষার জন্য প্রচুর কনফিগারেশন সাশ্রয় করে এবং এটি নিশ্চিত করে যে আপনি কখনও অপরিবর্তনীয় কিছু করতে পারবেন না (যেমন স্টেজিং ডেটাবেজ পরিষ্কার করা)।

আপনার পরীক্ষার ফাইলটি 'মাই_প্রজেক্ট / টেস্ট_সেটিংসপিপি' তে উপস্থিত রয়েছে বলে যোগ করুন

settings = 'my_project.test_settings' if 'test' in sys.argv else 'my_project.settings'

আপনার ম্যানেজ.পি। এটি নিশ্চিত করবে যে আপনি চালানোর সময় আপনি python manage.py testকেবল টেস্ট_সেটিংস ব্যবহার করেন। আপনি যদি পাইস্টেস্টের মতো আরও কিছু পরীক্ষার ক্লায়েন্ট ব্যবহার করেন তবে আপনি সহজেই এটি পাইটেক্সটিনইয়ে যুক্ত করতে পারেন


2
আমি মনে করি এটি আমার পক্ষে একটি ভাল সমাধান। আমার অনেকগুলি পরীক্ষা এবং কোড রয়েছে যা ক্যাশে ব্যবহার করছে। একের পর এক সেটিংস ওভাররাইড করা আমার পক্ষে কঠিন হবে। আমি দুটি কনফিগারেশন ফাইল তৈরি করব এবং কোনটি ব্যবহার করব তা নির্ধারণ করব। মাইক্রো পিরামিডের উত্তরটিও উপলভ্য, তবে আমি যদি সেটিংসের প্যারামিটারগুলি একবার যুক্ত করতে ভুলে যাই তবে এটি বিপজ্জনক হবে।
রামউইন

22

--settingsপরীক্ষা চালানোর সময় আপনি বিকল্পটি পাস করতে পারেন

python manage.py test --settings=mysite.settings_local

সেটিংসে অবস্থিত অ্যাপ্লিকেশনগুলি খুঁজে পাওয়া বন্ধ হয়ে গেছে
.দেব

4
আমি মনে করি যদি কেউ একবারে সেটিংসের প্যারামিটারগুলি যুক্ত করতে ভুলে যায় তবে তা বিপজ্জনক হবে।
রামউইন

20

আপডেট : নীচের সমাধানটি কেবল জাজানো 1.3.x এবং তার আগে এর উপর প্রয়োজন। 1.4 এর জন্য স্লিঙ্কপ এর উত্তর দেখুন

যদি আপনি আপনার পরীক্ষাগুলিতে ঘন ঘন সেটিংস পরিবর্তন করেন এবং পাইথন ≥2.5 ব্যবহার করেন তবে এটিও কার্যকর:

from contextlib import contextmanager

class SettingDoesNotExist:
    pass

@contextmanager
def patch_settings(**kwargs):
    from django.conf import settings
    old_settings = []
    for key, new_value in kwargs.items():
        old_value = getattr(settings, key, SettingDoesNotExist)
        old_settings.append((key, old_value))
        setattr(settings, key, new_value)
    yield
    for key, old_value in old_settings:
        if old_value is SettingDoesNotExist:
            delattr(settings, key)
        else:
            setattr(settings, key, old_value)

তারপরে আপনি এটি করতে পারেন:

with patch_settings(MY_SETTING='my value', OTHER_SETTING='other value'):
    do_my_tests()

এটি সত্যিই দুর্দান্ত সমাধান। কিছু কারণে আমার সেটিংস ইউনিট পরীক্ষায় সঠিকভাবে কাজ করছে না। খুব মার্জিত সমাধান, ভাগ করে নেওয়ার জন্য ধন্যবাদ।
টমাস

আমি এই কোডটি ব্যবহার করছি, তবে ক্যাসকেডিং পরীক্ষায় ব্যর্থতায় আমার সমস্যা হয়েছিল, কারণ প্রশ্নে পরীক্ষা ব্যর্থ হলে সেটিংসটি পুনরায় ফেরানো হবে না। এটির সমাধানের জন্য, আমি ব্লকটিতে yieldথাকা ফাংশনের চূড়ান্ত অংশটি সহ স্টেটমেন্টটির চারপাশে / চেষ্টা করার পরে শেষ করেছিলাম finallyযাতে সেটিংস সর্বদা ফিরে যায়।
ডাস্টিন রাসেনার

উত্তর উত্তর জন্য আমি সম্পাদনা করব। আমি আশা করি আমি এটি সঠিকভাবে করছি! :)
ডাস্টিন রাসেনার

11

@override_settings আপনার উত্পাদন এবং পরীক্ষার পরিবেশ কনফিগারেশনের মধ্যে আপনার অনেক পার্থক্য না থাকলে দুর্দান্ত।

অন্য ক্ষেত্রে আপনার আরও ভাল সেটিংস ফাইল থাকা উচিত। এক্ষেত্রে আপনার প্রকল্পটি এর মতো দেখাবে:

your_project
    your_app
        ...
    settings
        __init__.py
        base.py
        dev.py
        test.py
        production.py
    manage.py

সুতরাং আপনার নিজের সেটিংসের বেশিরভাগ অংশ থাকা দরকার base.pyএবং তারপরে অন্যান্য ফাইলগুলিতে আপনাকে সেখান থেকে সমস্ত কিছু আমদানি করতে হবে এবং কয়েকটি বিকল্পকে ওভাররাইড করতে হবে। আপনার test.pyফাইলটি কেমন দেখাচ্ছে তা এখানে :

from .base import *

DEBUG = False

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'app_db_test'
    }
}

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.MD5PasswordHasher',
)

LOGGING = {}

এবং তারপরে আপনাকে --settings@ মাইক্রো পিরামিড উত্তরের মতো বিকল্প নির্দিষ্ট করতে হবে , বা DJANGO_SETTINGS_MODULEপরিবেশের পরিবর্তনশীল নির্দিষ্ট করতে হবে এবং তারপরে আপনি আপনার পরীক্ষা চালাতে পারবেন:

export DJANGO_SETTINGS_MODULE=settings.test
python manage.py test 

হ্যালো . দিমিত্রি, আপনার উত্তরের জন্য ধন্যবাদ এই উত্তরটির সাথে একই ঘটনা ঘটছে তবে আমি কীভাবে অ্যাপটি জানতে পারি সে সম্পর্কে আরও দিকনির্দেশনা পেতে চাই, আমরা যে পরিবেশে আছি (পরীক্ষা বা উত্পাদন) , আমার শাখায় নজর রাখুন, পরীক্ষা করে দেখুন আমার রেপো github.com/andela/ah-backend-iroquois/tree/develop/authors , আমি কীভাবে সেই যুক্তিকে সামলাব ?
লুটোয়া হুযাইফাহ ইদ্রিস

যেহেতু আমি পরীক্ষা চালানোর জন্য নস্টিস্ট ব্যবহার করি , এখন এটি কীভাবে চালানো হবে ?, পরীক্ষার পরিবেশে উন্নয়নের পরিবেশে নয়
লুটোয়া হুজাইফাহ ইদ্রিস

3

কিছু দস্তাবেজ ঠিক করার চেষ্টা করার সময় এটি পাওয়া গেছে ... সম্পূর্ণতার জন্য আমি উল্লেখ করতে চাই যে ডকসেট ব্যবহার করার সময় আপনি যদি সেটিংসটি পরিবর্তন করতে চলেছেন তবে অন্য কিছু আমদানির আগে আপনার করা উচিত ...

>>> from django.conf import settings

>>> settings.SOME_SETTING = 20

>>> # Your other imports
>>> from django.core.paginator import Paginator
>>> # etc

3

জন্য pytest ব্যবহারকারীদের।

বৃহত্তম সমস্যাটি হ'ল:

  • override_settings পাইস্টের সাথে কাজ করে না
  • সাবক্লাসিং জ্যাঙ্গো এর TestCaseকাজ করবে কিন্তু তারপরে আপনি পাইস্টেস্ট ফিক্সচার ব্যবহার করতে পারবেন না।

সমাধানটি এখানেsettings ডকুমেন্টেড ফিক্সচার ব্যবহার করা

উদাহরণ

def test_with_specific_settings(settings):
    settings.DEBUG = False
    settings.MIDDLEWARE = []
    ..

এবং ক্ষেত্রে আপনার একাধিক ক্ষেত্র আপডেট করতে হবে

def override_settings(settings, kwargs):
    for k, v in kwargs.items():
        setattr(settings, k, v)


new_settings = dict(
    DEBUG=True,
    INSTALLED_APPS=[],
)


def test_with_specific_settings(settings):
    override_settings(settings, new_settings)

3

আপনি একক পরীক্ষার ফাংশনের জন্য এমনকি সেটিংসকে ওভাররাইড করতে পারেন।

from django.test import TestCase, override_settings

class SomeTestCase(TestCase):

    @override_settings(SOME_SETTING="some_value")
    def test_some_function():
        

অথবা আপনি ক্লাসে প্রতিটি ফাংশনের জন্য সেটিংটি ওভাররাইড করতে পারেন।

@override_settings(SOME_SETTING="some_value")
class SomeTestCase(TestCase):

    def test_some_function():
        

1

আমি পাইস্ট ব্যবহার করছি

আমি নিম্নলিখিত পদ্ধতিতে এটি সমাধান করতে পরিচালিত:

import django    
import app.setting
import modules.that.use.setting

# do some stuff with default setting
setting.VALUE = "some value"
django.setup()
import importlib
importlib.reload(app.settings)
importlib.reload(modules.that.use.setting)
# do some stuff with settings new value

1

আপনি পরীক্ষায় সেটিংসকে এইভাবে ওভাররাইড করতে পারেন:

from django.test import TestCase, override_settings

test_settings = override_settings(
    DEFAULT_FILE_STORAGE='django.core.files.storage.FileSystemStorage',
    PASSWORD_HASHERS=(
        'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher',
    )
)


@test_settings
class SomeTestCase(TestCase):
    """Your test cases in this class"""

এবং যদি অন্য কোনও ফাইলে আপনার এই একই সেটিংসের প্রয়োজন হয় তবে আপনি কেবল সরাসরি আমদানি করতে পারেন test_settings


0

আপনার যদি একটি উপ-ডিরেক্টরিতে (পাইথন প্যাকেজ) একাধিক পরীক্ষার ফাইল স্থাপন করা হয়, আপনি sys.argv এ 'টেস্ট' স্ট্রিংয়ের উপস্থিতির শর্তের ভিত্তিতে এই সমস্ত ফাইলের সেটিংসকে ওভাররাইড করতে পারেন

app
  tests
    __init__.py
    test_forms.py
    test_models.py

__init__.py:

import sys
from project import settings

if 'test' in sys.argv:
    NEW_SETTINGS = {
        'setting_name': value,
        'another_setting_name': another_value
    }
    settings.__dict__.update(NEW_SETTINGS)

সেরা পদ্ধতির না। এটি সেলারি ব্রোকারকে রেডিস থেকে মেমোরিতে পরিবর্তন করতে ব্যবহৃত হয়েছিল।


0

আমি একটি নতুন সেটিংস_টেষ্ট.পি ফাইল তৈরি করেছি যা সেটিংস.পি ফাইল থেকে সমস্ত কিছু আমদানি করে এবং পরীক্ষার উদ্দেশ্যে যা কিছু আলাদা তা পরিবর্তন করতে পারে। আমার ক্ষেত্রে আমি পরীক্ষা করার সময় একটি আলাদা ক্লাউড স্টোরেজ বালতিটি ব্যবহার করতে চেয়েছিলাম। এখানে চিত্র বর্ণনা লিখুন

settings_test.py:

from project1.settings import *
import os

CLOUD_STORAGE_BUCKET = 'bucket_name_for_testing'

manage.py:

def main():

    # use seperate settings.py for tests
    if 'test' in sys.argv:
        print('using settings_test.py')
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project1.settings_test')
    else:
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project1.settings')

    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.