কীভাবে কেবল স্মৃতিতে জাঙ্গোর পরীক্ষার ডাটাবেস চালানো যায়?


125

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

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

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

উত্তর:


164

আপনি যখন পরীক্ষা চালাবেন তখন আপনি যদি ডেটাবেস ইঞ্জিনটিকে স্ক্লাইট 3 এ সেট করেন, জাজানো একটি মেমরির ডাটাবেস ব্যবহার করবে

আমি settings.pyআমার পরীক্ষাগুলি চালানোর সময় ইঞ্জিনটিকে স্ক্লাইটে সেট করতে আমার মতো কোড ব্যবহার করছি :

if 'test' in sys.argv:
    DATABASE_ENGINE = 'sqlite3'

বা জ্যাঙ্গো ১.২ এ:

if 'test' in sys.argv:
    DATABASES['default'] = {'ENGINE': 'sqlite3'}

এবং অবশেষে জ্যাঙ্গোতে 1.3 এবং 1.4 এ:

if 'test' in sys.argv:
    DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}

(ব্যাকএন্ডে পুরো পথটি জ্যাঙ্গো ১.৩ এর সাথে কঠোরভাবে প্রয়োজনীয় নয়, তবে সেটিংসটিকে সামঞ্জস্যপূর্ণ করে তোলে))

আপনি যদি দক্ষিণ মাইগ্রেশনে সমস্যা বোধ করেন তবে আপনি নিম্নলিখিত লাইনটি যুক্ত করতে পারেন:

    SOUTH_TESTS_MIGRATE = False

9
হ্যাঁ অবশ্যই. আমার উত্তরটি দেওয়া উচিত ছিল! SOUTH_TESTS_MIGRATE = এর সাথে একত্রিত করুন: মিথ্যা এবং আপনার পরীক্ষাগুলি অনেক দ্রুত হওয়া উচিত।
এটিয়েন

7
এই হল সন্ত্রস্ত। নতুন জাঙ্গো সেটআপগুলিতে এই লাইনটি ব্যবহার করুন: 'ENGINE': 'sqlite3' যদি sys.argv এ 'পরীক্ষা' করা হয় 'django.db.backends.mysql',
mjallday

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

3
আমি -১ থেকে +1 বিপরীত: আমি এখন এটি দেখতে পাচ্ছি, দ্রুত রান করার জন্য স্ক্লাইট ব্যবহার করা এবং চূড়ান্ত দৈনিক পরীক্ষার জন্য মাইএসকিউএল-এ স্যুইচ করা অনেক দ্রুত। (দ্রষ্টব্য যে ভোটদান আনলক করতে আমাকে একটি ছদ্মবেশী সম্পাদনা করতে হয়েছিল)
টমাসজ জিয়েলসিস্কি

12
এর সাথে সতর্কতা "test" in sys.argv; আপনি এটি না চান যখন এটি ট্রিগার করতে পারে, যেমন manage.py collectstatic -i testsys.argv[1] == "test"একটি আরও সুনির্দিষ্ট শর্ত যা সেই সমস্যাটি হওয়া উচিত নয়।
কেটর্ন

83

আমি সাধারণত পরীক্ষার জন্য পৃথক সেটিংস ফাইল তৈরি করি এবং এটি পরীক্ষার কমান্ডে যেমন ব্যবহার করি

python manage.py test --settings=mysite.test_settings myapp

এর দুটি সুবিধা রয়েছে:

  1. আপনাকে testsys.argv- তে কোনও যাদু শব্দের জন্য বা পরীক্ষা test_settings.pyকরতে হবে না , এটি সহজভাবে হতে পারে

    from settings import *
    
    # make tests faster
    SOUTH_TESTS_MIGRATE = False
    DATABASES['default'] = {'ENGINE': 'django.db.backends.sqlite3'}

    বা আপনি নিজের প্রয়োজনের জন্য এটি আরও সামঞ্জস্য করতে পারেন, পরিষ্কারভাবে টেস্ট সেটিংসকে উত্পাদন সেটিংস থেকে আলাদা করে।

  2. আরেকটি সুবিধা হ'ল আপনি সূক্ষ্ম বাগগুলি এড়িয়ে স্ক্যালাইট 3 এর পরিবর্তে উত্পাদন ডেটাবেস ইঞ্জিন দিয়ে পরীক্ষা চালাতে পারেন, তাই ব্যবহারের বিকাশ করার সময়

    python manage.py test --settings=mysite.test_settings myapp

    এবং কমিট করার আগে একবার কোড চালান

    python manage.py test myapp

    সমস্ত পরীক্ষা সত্যিই উত্তীর্ণ হয় তা নিশ্চিত হতে।


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

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

চমৎকার উত্তর. আমি আশ্চর্য হই যে কভারেজের মাধ্যমে পরীক্ষা চলাকালীন সেটিংস ফাইল কীভাবে নির্দিষ্ট করা যায়।
ওয়াটওয়ার

এটি একটি ভাল পদ্ধতির, তবে DRY নয়। জাজানো ইতিমধ্যে জানে যে আপনি পরীক্ষা চালাচ্ছেন। আপনি যদি এই জ্ঞানটি কোনওভাবে 'হুক' করতে পারতেন তবে আপনি সেট হয়ে যাবেন। দুর্ভাগ্যক্রমে, আমি বিশ্বাস করি যে ম্যানেজমেন্ট কমান্ড প্রসারিত করা প্রয়োজন। এই জেনেরিকটি কাঠামোর মূল অংশে তৈরি করা সম্ভবত বোধগম্য হবে, উদাহরণস্বরূপ, যখনই ম্যানেজ.পাই ডাকা হয় তখনকার কমান্ডটিতে একটি MANAGEMENT_COMMAND সেট করা থাকে, বা সেই প্রভাবতে কিছু থাকে।
ডিলানইং

2
@ ডায়ালান ইয়ং আপনি টেস্ট_সেটেজে প্রধান সেটিংস অন্তর্ভুক্ত করে এবং পরীক্ষার জন্য যা চান কেবল সেগুলি ওভাররাইড করে এটি শুষ্ক করে তুলতে পারেন।
অনুরাগ ইউনিয়াল

22

মাইএসকিউএল "মেমোরি" নামক একটি স্টোরেজ ইঞ্জিন সমর্থন করে, যা আপনি আপনার ডাটাবেস কনফিগারেশনে কনফিগার করতে পারেন ( settings.pyযেমন):

    'USER': 'root',                      # Not used with sqlite3.
    'PASSWORD': '',                  # Not used with sqlite3.
    'OPTIONS': {
        "init_command": "SET storage_engine=MEMORY",
    }

মনে রাখবেন যে মেমোরি স্টোরেজ ইঞ্জিন ব্লব / পাঠ্য কলামগুলিকে সমর্থন করে না, তাই আপনি যদি এটি ব্যবহার করেন তবে এটি আপনার django.db.models.TextFieldপক্ষে কাজ করবে না।


5
ব্লব / পাঠ্য কলামগুলির সমর্থনের অভাব উল্লেখ করার জন্য +1 এটি লেনদেন সমর্থন করে বলে মনে হয় না ( dev.mysql.com/doc/refman/5.6/en/memory-stores-engine.html )।
টুকু মুস্তোনেন

আপনি যদি সত্যিই ইন-মেমরি টেস্টগুলি চান, আপনি সম্ভবত স্ক্লাইট দিয়ে যাওয়াই ভাল যা অন্তত লেনদেনকে সমর্থন করে।
পরমাণু 77

15

আমি আপনার মূল প্রশ্নের উত্তর দিতে পারি না, তবে জিনিসগুলি গতি বাড়ানোর জন্য আপনি কয়েকটি জিনিস করতে পারেন।

প্রথমত, নিশ্চিত হয়ে নিন যে আপনার মাইএসকিউএল ডাটাবেসটি ইনোডিবি ব্যবহারের জন্য সেট আপ হয়েছে। তারপরে এটি প্রতিটি পরীক্ষার আগে ডিবির স্থিতি রোলব্যাক করার জন্য লেনদেনগুলি ব্যবহার করতে পারে, যা আমার অভিজ্ঞতায় একটি প্রচুর গতি বাড়িয়ে তুলেছে। আপনি আপনার সেটিংসে একটি ডাটাবেস সূচনা কমান্ডটি পাস করতে পারেন pypy (জাজানো ১.২ সিনট্যাক্স):

DATABASES = {
    'default': {
            'ENGINE':'django.db.backends.mysql',
            'HOST':'localhost',
            'NAME':'mydb',
            'USER':'whoever',
            'PASSWORD':'whatever',
            'OPTIONS':{"init_command": "SET storage_engine=INNODB" } 
        }
    }

দ্বিতীয়ত, আপনাকে প্রতিবার দক্ষিণ মাইগ্রেশন চালানোর দরকার নেই। SOUTH_TESTS_MIGRATE = Falseআপনার সেটিংসে সেট করুন.পি এবং ডেটাবেস প্লেইন সিঙ্কডিবি দিয়ে তৈরি করা হবে যা সমস্ত historicতিহাসিক স্থানান্তরের মধ্য দিয়ে চলার চেয়ে অনেক দ্রুত হবে।


দুর্দান্ত টিপ! এটি আমার পরীক্ষাগুলি থেকে কমিয়ে 369 tests in 498.704sদিয়েছে 369 tests in 41.334s । এটি 10 ​​গুণ বেশি দ্রুত!
গবি পুরকারু

জ্যাঙ্গো 1.7+ এ মাইগ্রেশনের জন্য সেটিংস.পাইয়ের সমতুল্য সুইচ আছে কি?
এডওয়ার্ড নেওয়েল

পুনঃটুইট তবে আপনি --keepডাটাবেসটি অবিরাম রাখতে ব্যবহার করতে পারেন এবং প্রতি পরীক্ষার জন্য আপনার মাইগ্রেশনের পুরো সেটটি পুনরায় প্রয়োগ করার দরকার নেই। নতুন স্থানান্তর এখনও চলবে। যদি আপনি ঘন ঘন শাখাগুলির মধ্যে স্যুইচ করে থাকেন তবে এটি কোনও বেমানান অবস্থায় যেতে পারে যদিও (পরীক্ষার ডাটাবেসে ডেটাবেস পরিবর্তন করে আপনি চালনা করার আগে আপনি নতুন স্থানান্তর ফিরিয়ে নিতে পারেন migrateতবে এটি কিছুটা ব্যথা হবে)।
ডিলানইং

10

আপনি ডাবল টুইট করতে পারেন:

  • লেনদেনের সারণীগুলি ব্যবহার করুন: প্রতিটি টেস্টকেসের পরে ডাটাবেস রোলব্যাক ব্যবহার করে প্রাথমিক ফিক্সারগুলির স্থিতি সেট করা হবে।
  • আপনার ডাটাবেস ডেটা র‌্যামডিস্কে রাখুন: ডাটাবেস তৈরির বিষয়ে আপনি যতটা লাভ অর্জন করবেন এবং পরীক্ষা চালানোও তত দ্রুত হবে।

আমি উভয় কৌশল ব্যবহার করছি এবং আমি বেশ খুশি।

উবুন্টুতে এটি কীভাবে মাইএসকিউএল-এর জন্য সেট আপ করবেন:

$ sudo service mysql stop
$ sudo cp -pRL /var/lib/mysql /dev/shm/mysql

$ vim /etc/mysql/my.cnf
# datadir = /dev/shm/mysql
$ sudo service mysql start

সাবধান, এটি কেবল পরীক্ষার জন্য, পুনরায় বুট করার পরে আপনার ডাটাবেসটি স্মৃতি থেকে হারিয়ে যায়!


ধন্যবাদ! আমার জন্য কাজ কর. আমি স্ক্লাইট ব্যবহার করতে পারি না, কারণ আমি মাইএসকিএল (পূর্ণ-পাঠ্য সূচী) এর সাথে সম্পর্কিত বৈশিষ্ট্যগুলি ব্যবহার করছি। উবুন্টু ব্যবহারকারীদের জন্য, আপনাকে / অ্যাপ্লিকেশন কনফিগারেশনটি সম্পাদনা করতে হবে / মাইএসকিএলডি / dev / shm / mysql অ্যাক্সেসের অনুমতি দিতে
ইভান ভাইরাবায়ান

ইভান এবং পাত্রের মাথা আপ করার জন্য চিয়ার্স। এখন জন্য AppArmor মাইএসকিউএল প্রোফাইল অক্ষম, কিন্তু প্রাসঙ্গিক স্থানীয় প্রফাইল কাস্টমাইজ করার জন্য একটি গাইড পাওয়া যায়নি: blogs.oracle.com/jsmyth/entry/apparmor_and_mysql
trojjer

হুম। আমি স্থানীয় প্রোফাইলটিকে / dev / shm / mysql পাথ এবং এর বিষয়বস্তুগুলিতে অ্যাক্সেস দেওয়ার জন্য কাস্টমাইজ করার চেষ্টা করেছি, তবে পরিষেবাটি কেবল 'অভিযোগ' মোডে (এএ-অভিযোগ কমান্ড) চালু হতে পারে এবং কারও জন্য 'প্রয়োগ' নয় কারণ ... অন্য ফোরামের জন্য একটি প্রশ্ন! আমি বুঝতে পারি না যে এটি যখন কাজ করে তখন কোনও 'অভিযোগ' কীভাবে হয় না, বোঝা যায় যে
মাইএসকিএলডি

4

আরেকটি পদ্ধতির: মাইএসকিউএল-র একটি অন্য উদাহরণ রয়েছে যা কোনও টেম্পফেসে চলছে যা একটি র‌্যাম ডিস্ক ব্যবহার করে। এই ব্লগ পোস্টে নির্দেশনা: জ্যাঙ্গোতে পরীক্ষার জন্য মাইএসকিউএল গতি বাড়িয়ে দেওয়া

সুবিধাদি:

  • আপনার প্রোডাকশন সার্ভারটি ঠিক একই ডাটাবেস ব্যবহার করে
  • আপনার ডিফল্ট মাইএসকিএল কনফিগারেশন পরিবর্তন করার দরকার নেই

2

অনুরাগের উত্তরের প্রসারকে প্রসারিত করে একই টেস্ট_সেটিংগুলি তৈরি করে এবং ব্যবস্থাপনাটি অনুসরণ করার জন্য নিম্নলিখিতগুলি যুক্ত করে প্রক্রিয়াটি সহজ করেছি

if len(sys.argv) > 1 and sys.argv[1] == "test":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.test_settings")
else:
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

সিস্টেমগুলি ইতিমধ্যে আমদানি করা হয়েছে এবং ম্যানেজ.পি কেবল কমান্ড লাইনের মাধ্যমেই ব্যবহৃত হয়, তাই সেটিংসকে বিশৃঙ্খলাবদ্ধ করার দরকার নেই বলে পরিষ্কার মনে হচ্ছে


2
এর সাথে সতর্কতা "test" in sys.argv; আপনি এটি না চান যখন এটি ট্রিগার করতে পারে, যেমন manage.py collectstatic -i testsys.argv[1] == "test"একটি আরও সুনির্দিষ্ট শর্ত যা সেই সমস্যাটি হওয়া উচিত নয়।
কেটর্ন

2
এই ভাবে যখন চলমান এটা ব্যতিক্রম উত্পন্ন @keturn ./manage.pyআর্গুমেন্ট ছাড়া (যেমন যা প্ল্যাগইন একই হিসাবে পাওয়া যায়, দেখতে --help)
অ্যান্টনি Hatchkins

1
@ অ্যান্টনি হ্যাচকিন্স এটি সমাধানের জন্য তুচ্ছ:len(sys.argv) > 1 and sys.argv[1] == "test"
ডিলান ইউং

1
@ ডায়ালান ইয়ং হ্যাঁ, আমি ঠিক এটাই চাইছিলাম আলভিনকে তার সমাধানে যুক্ত করা কিন্তু তিনি এর উন্নতিতে বিশেষ আগ্রহী নন। যাইহোক এটি লিট সমাধানের চেয়ে দ্রুত হ্যাকের মতো দেখাচ্ছে।
অ্যান্টনি হ্যাচকিন্স

1
এই জবাবটি কিছুক্ষণের মধ্যে দেখেনি, আমি @ ডিলানইংয়ের উন্নতির প্রতিফলিত করার জন্য স্নিপেট আপডেট করেছি
অ্যালভিন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.