ডিবি স্থাপন না করে জ্যাঙ্গো ইউনিটসেট লেখার কি সম্ভাবনা আছে? আমি এমন ব্যবসায়িক যুক্তি পরীক্ষা করতে চাই যার জন্য ডিবি সেট আপ করতে হবে না। এবং এটি যখন একটি ডিবি সেটআপ করা দ্রুত, তবে কিছু পরিস্থিতিতে আমার সত্যিই এটির দরকার নেই।
ডিবি স্থাপন না করে জ্যাঙ্গো ইউনিটসেট লেখার কি সম্ভাবনা আছে? আমি এমন ব্যবসায়িক যুক্তি পরীক্ষা করতে চাই যার জন্য ডিবি সেট আপ করতে হবে না। এবং এটি যখন একটি ডিবি সেটআপ করা দ্রুত, তবে কিছু পরিস্থিতিতে আমার সত্যিই এটির দরকার নেই।
উত্তর:
আপনি JangoTestSuiteRunner সাবক্লাস করতে পারেন এবং সেটআপ_ড্যাটাবেসগুলি এবং টিয়ারডাউন_ড্যাটাবেসগুলি পাস করার জন্য ওভাররাইড করতে পারেন।
একটি নতুন সেটিংস ফাইল তৈরি করুন এবং আপনার সদ্য নির্মিত নতুন শ্রেণিতে TEST_RUNNER সেট করুন। তারপরে আপনি যখন পরীক্ষাটি চালাচ্ছেন, - সেটিং ফ্ল্যাগ সহ আপনার নতুন সেটিংস ফাইলটি নির্দিষ্ট করুন।
আমি যা করেছি তা এখানে:
এটির মতো কাস্টম টেস্ট স্যুট রানার তৈরি করুন:
from django.test.simple import DjangoTestSuiteRunner
class NoDbTestRunner(DjangoTestSuiteRunner):
""" A test runner to test without database creation """
def setup_databases(self, **kwargs):
""" Override the database creation defined in parent class """
pass
def teardown_databases(self, old_config, **kwargs):
""" Override the database teardown defined in parent class """
pass
একটি কাস্টম সেটিংস তৈরি করুন:
from mysite.settings import *
# Test runner with no database creation
TEST_RUNNER = 'mysite.scripts.testrunner.NoDbTestRunner'
আপনি যখন পরীক্ষা চালাচ্ছেন, আপনার নতুন সেটিংস ফাইলে সেট করা - সেটিংস পতাকা সহ নিম্নলিখিতটির মতো এটি চালান:
python manage.py test myapp --settings='no_db_settings'
আপডেট: এপ্রিল / 2018
জ্যাঙ্গো ১.৮ থেকে, মডিউলটি সরানো হয়েছে ।django.test.simple.DjangoTestSuiteRunner
'django.test.runner.DiscoverRunner'
আরও তথ্যের জন্য কাস্টম পরীক্ষা দৌড়াবিদদের সম্পর্কে অফিসিয়াল ডক বিভাগটি পরীক্ষা করুন।
--testrunner
বিকল্পটি দিয়ে কমান্ড লাইনে নতুন টেস্টরুনার নির্দিষ্ট করতে পারবেন ।
সাধারণত একটি অ্যাপ্লিকেশন পরীক্ষার দুটি বিভাগে শ্রেণিবদ্ধ করা যেতে পারে
জ্যাঙ্গো উভয় ইউনিট এবং ইন্টিগ্রেশন টেস্ট সমর্থন করে।
ইউনিট পরীক্ষাগুলি, ডেটাবেস সেটআপ এবং ছিন্ন করতে হবে না এবং এগুলি সিম্পল টেস্টকেস থেকে উত্তরাধিকারী হওয়া উচিত ।
from django.test import SimpleTestCase
class ExampleUnitTest(SimpleTestCase):
def test_something_works(self):
self.assertTrue(True)
ইন্টিগ্রেশন পরীক্ষার ক্ষেত্রে টেস্ট কেস থেকে উত্তরাধিকার সূত্রে লেনদেন টেস্টক্যাস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় এবং এটি প্রতিটি পরীক্ষা চালানোর আগে ডাটাবেস সেটআপ করে এবং ছিন্ন করে।
from django.test import TestCase
class ExampleIntegrationTest(TestCase):
def test_something_works(self):
#do something with database
self.assertTrue(True)
এই কৌশলটি নিশ্চিত করবে যে কেবলমাত্র পরীক্ষার ক্ষেত্রে ডেটাবেস অ্যাক্সেস করেছে এবং তাই পরীক্ষাগুলি আরও দক্ষ হবে database
থেকে django.test.simple
warnings.warn(
"The django.test.simple module and DjangoTestSuiteRunner are deprecated; "
"use django.test.runner.DiscoverRunner instead.",
RemovedInDjango18Warning)
এর DiscoverRunner
পরিবর্তে ওভাররাইড করুন DjangoTestSuiteRunner
।
from django.test.runner import DiscoverRunner
class NoDbTestRunner(DiscoverRunner):
""" A test runner to test without database creation/deletion """
def setup_databases(self, **kwargs):
pass
def teardown_databases(self, old_config, **kwargs):
pass
এর মতো ব্যবহার করুন:
python manage.py test app --testrunner=app.filename.NoDbTestRunner
আমি উত্তরাধিকারী হয়ে পদ্ধতিতে django.test.runner.DiscoverRunner
কয়েকটি সংযোজন করেছি ofrun_tests
আমার প্রথম সংযোজনটি ডিবি স্থাপন করা প্রয়োজন কিনা তা পরীক্ষা করে এবং ডিবি প্রয়োজনীয় হলে স্বাভাবিক setup_databases
কার্যকারিতাটি লাথি মারতে দেয় । আমার দ্বিতীয় সংযোজনটি teardown_databases
যদি setup_databases
পদ্ধতিটি চালানোর অনুমতি দেয় তবে স্বাভাবিকটি চলতে দেয়।
আমার কোডটি ধরে নিয়েছে যে যে কোনও টেস্টকেস উত্তরাধিকার সূত্রে প্রাপ্ত django.test.TransactionTestCase
(এবং এইভাবে django.test.TestCase
) সেটআপ করার জন্য একটি ডেটাবেস প্রয়োজন। আমি এই ধারণাটি তৈরি করেছি কারণ জ্যাঙ্গো ডকস বলেছেন:
আপনার যদি আরও জটিল এবং হেভিওয়েট জ্যাঙ্গো-নির্দিষ্ট বৈশিষ্ট্যগুলির যেমন ... ওআরএম পরীক্ষা করা বা ব্যবহার করা দরকার ... তবে আপনার পরিবর্তে ট্রানজেকশন টেস্টকেস বা টেস্টকেস ব্যবহার করা উচিত।
https://docs.djangoproject.com/en/1.6/topics/testing/tools/#django.test.SimpleTestCase
from django.test import TransactionTestCase
from django.test.runner import DiscoverRunner
class MyDiscoverRunner(DiscoverRunner):
def run_tests(self, test_labels, extra_tests=None, **kwargs):
"""
Run the unit tests for all the test labels in the provided list.
Test labels should be dotted Python paths to test modules, test
classes, or test methods.
A list of 'extra' tests may also be provided; these tests
will be added to the test suite.
If any of the tests in the test suite inherit from
``django.test.TransactionTestCase``, databases will be setup.
Otherwise, databases will not be set up.
Returns the number of tests that failed.
"""
self.setup_test_environment()
suite = self.build_suite(test_labels, extra_tests)
# ----------------- First Addition --------------
need_databases = any(isinstance(test_case, TransactionTestCase)
for test_case in suite)
old_config = None
if need_databases:
# --------------- End First Addition ------------
old_config = self.setup_databases()
result = self.run_suite(suite)
# ----------------- Second Addition -------------
if need_databases:
# --------------- End Second Addition -----------
self.teardown_databases(old_config)
self.teardown_test_environment()
return self.suite_result(suite, result)
অবশেষে, আমি আমার প্রকল্পের সেটিংস.পি ফাইলটিতে নিম্নলিখিত লাইনটি যুক্ত করেছি।
TEST_RUNNER = 'mysite.scripts.settings.MyDiscoverRunner'
এখন, যখন কেবল নন-ডিবি-নির্ভরশীল পরীক্ষা চালানো হচ্ছে, আমার পরীক্ষার স্যুটটি দ্রুততার একটি ক্রম চালায়! :)
আপডেট হয়েছে: তৃতীয় পক্ষের সরঞ্জাম ব্যবহারের জন্য এই উত্তরটিও দেখুন pytest
।
@ সিজার ঠিক আছে। দুর্ঘটনাক্রমে চলার পরে ./manage.py test --settings=no_db_settings
, কোনও অ্যাপের নাম উল্লেখ না করে, আমার বিকাশের ডেটাবেসটি মুছে ফেলা হয়েছিল।
নিরাপদ উপায়ে, একই ব্যবহার করুন NoDbTestRunner
তবে নিম্নলিখিতগুলির সাথে একত্রে mysite/no_db_settings.py
:
from mysite.settings import *
# Test runner with no database creation
TEST_RUNNER = 'mysite.scripts.testrunner.NoDbTestRunner'
# Use an alternative database as a safeguard against accidents
DATABASES['default']['NAME'] = '_test_mysite_db'
আপনাকে _test_mysite_db
একটি বহিরাগত ডাটাবেস সরঞ্জাম ব্যবহার করে একটি ডেটাবেস তৈরি করতে হবে । এর সাথে সম্পর্কিত সারণী তৈরি করতে নিম্নলিখিত কমান্ডটি চালান:
./manage.py syncdb --settings=mysite.no_db_settings
আপনি যদি দক্ষিণ ব্যবহার করছেন তবে নীচের কমান্ডটিও চালান:
./manage.py migrate --settings=mysite.no_db_settings
ঠিক আছে!
আপনি এখন একক টেস্টগুলি স্বতঃস্ফূর্তভাবে দ্রুত (এবং নিরাপদ) চালাতে পারবেন:
./manage.py test myapp --settings=mysite.no_db_settings
NoDbTestRunner "নিরাপদ" করার জন্য আপনার সেটিংস পরিবর্তন করার বিকল্প হিসাবে, এখানে NoDbTestRunner এর একটি সংশোধিত সংস্করণ রয়েছে যা বর্তমান ডাটাবেস সংযোগটি বন্ধ করে দেয় এবং সেটিংস এবং সংযোগের বিষয়বস্তু থেকে সংযোগের তথ্য সরিয়ে দেয়। আমার জন্য কাজ করে, তার উপর নির্ভর করার আগে আপনার পরিবেশে এটি পরীক্ষা করুন :)
class NoDbTestRunner(DjangoTestSuiteRunner):
""" A test runner to test without database creation """
def __init__(self, *args, **kwargs):
# hide/disconnect databases to prevent tests that
# *do* require a database which accidentally get
# run from altering your data
from django.db import connections
from django.conf import settings
connections.databases = settings.DATABASES = {}
connections._connections['default'].close()
del connections._connections['default']
super(NoDbTestRunner,self).__init__(*args,**kwargs)
def setup_databases(self, **kwargs):
""" Override the database creation defined in parent class """
pass
def teardown_databases(self, old_config, **kwargs):
""" Override the database teardown defined in parent class """
pass
__getitem__
আর সমর্থন করে না। ব্যবহারের connections._connections.default
বস্তু অ্যাক্সেস করার জন্য।
আর একটি সমাধান হ'ল আপনার পরীক্ষার ক্লাসটি unittest.TestCase
জ্যাঙ্গোর কোনও পরীক্ষার ক্লাসের পরিবর্তে কেবল উত্তরাধিকার সূত্রে প্রাপ্ত । জ্যাঙ্গো ডক্স ( https://docs.djangoproject.com/en/2.0/topics/testing/overview/#writing-tests ) এ সম্পর্কে নিম্নলিখিত সতর্কতা ধারণ করে:
ইউনিটেষ্টেস্ট.টেষ্টকেস ব্যবহার করে প্রতিটি লেনদেনে প্রতিটি পরীক্ষা চালানো এবং ডাটাবেস ফ্লাশ করা ব্যয় এড়ানো হয়, তবে যদি আপনার পরীক্ষাগুলি ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করে তবে তাদের আচরণের পরীক্ষা-নিরীক্ষক তাদের কার্যকর করার আদেশের ভিত্তিতে পরিবর্তিত হতে পারে। এটি ইউনিট পরীক্ষাগুলি নিয়ে যেতে পারে যা বিচ্ছিন্নতার সাথে চালিত হওয়ার পরে পাস হয় তবে স্যুটটিতে চালিত হওয়ার পরে ব্যর্থ হয়।
তবে, যদি আপনার পরীক্ষাটি ডাটাবেস ব্যবহার না করে তবে এই সতর্কতাটি আপনাকে উদ্বেগের প্রয়োজন হবে না এবং প্রতিটি পরীক্ষার কেস কোনও লেনদেনে চালিত না করার সুবিধা আপনি কাটাতে পারেন।
উপরের সমাধানগুলিও ঠিক আছে। তবে মাইগ্রেশনের সংখ্যা বেশি হলে নিম্নলিখিত সমাধানটি ডিবি তৈরির সময়ও হ্রাস করবে। ইউনিট পরীক্ষার সময়, সমস্ত দক্ষিণ মাইগ্রেশন চালানোর পরিবর্তে সিঙ্কডিবি চালানো আরও দ্রুত হবে।
SOUTH_TESTS_MIGRATE = মিথ্যা # স্থানান্তর অক্ষম করতে এবং পরিবর্তে সিঙ্কডিবি ব্যবহার করুন
আমার ওয়েব হোস্ট কেবল তাদের ওয়েব জিইউআই থেকে ডেটাবেস তৈরি এবং ছাড়ার অনুমতি দেয়, তাই চালানোর চেষ্টা করার সময় আমি "পরীক্ষার ডাটাবেস তৈরি করার সময় ত্রুটি পেয়েছি: অনুমতি অস্বীকার করা" পেয়েছিলাম python manage.py test
।
আমি জ্যাঙ্গো-অ্যাডমিন.পি-তে -কিডিডিবি বিকল্পটি ব্যবহার করব বলে আশা করি তবে জ্যাঙ্গো ১.7 হিসাবে এটি আর সমর্থিত বলে মনে হয় না।
আমি যা করে শেষ করেছি তা হল ... / জ্যাঞ্জো / ডিবি / ব্যাকেন্ডস / ক্রিয়েশন.পি তে জ্যাঙ্গো কোডটি সংশোধন করা, বিশেষত _ ক্রিয়েট_টেষ্ট_ডিবি এবং _ডাস্ট্রয়_টেষ্ট_ডিবি ফাংশন।
জন্য _create_test_db
আমি মন্তব্য cursor.execute("CREATE DATABASE ...
লাইন এবং সঙ্গে এটি প্রতিস্থাপিত pass
তাইtry
ব্লক খালি হবে না।
যেহেতু _destroy_test_db
আমি কেবল মন্তব্য cursor.execute("DROP DATABASE
করেছি - আমার এটিকে কোনও কিছুর সাথে প্রতিস্থাপনের দরকার নেই কারণ ব্লকের মধ্যে ইতিমধ্যে অন্য কমান্ড ছিল (time.sleep(1)
)।
এর পরে আমার পরীক্ষাগুলি ভাল ছিল - যদিও আমি আমার নিয়মিত ডাটাবেসের একটি টেস্ট_ সংস্করণ আলাদাভাবে সেট আপ করেছি।
এটি অবশ্যই দুর্দান্ত সমাধান নয়, কারণ জ্যাঙ্গো আপগ্রেড করা থাকলে এটি ভেঙে যাবে তবে ভ্যাচুয়ালেনভ ব্যবহারের কারণে আমার কাছে জাঙ্গোর একটি স্থানীয় অনুলিপি ছিল তাই আমি / আমি যদি নতুন সংস্করণে আপগ্রেড করি তবে কমপক্ষে আমার নিয়ন্ত্রণ থাকে।
অন্য একটি সমাধান উল্লেখ করা হয়নি: এটি কার্যকর করা আমার পক্ষে সহজ ছিল কারণ আমার কাছে ইতিমধ্যে বেস.পি থেকে উত্তরাধিকারসূত্রে একাধিক সেটিংস ফাইল রয়েছে (স্থানীয় / মঞ্চায়ন / উত্পাদনের জন্য)। সুতরাং অন্যান্য ব্যক্তির মতো আমি DATABASES ['ডিফল্ট'] ওভাররাইট করতে পারি নি, যেমন DATABASES বেস.পি তে সেট করা নেই isn't
সিম্পলটেস্টকেস এখনও আমার পরীক্ষার ডাটাবেসে সংযোগ স্থাপন এবং মাইগ্রেশন চালানোর চেষ্টা করেছিল। যখন আমি কোনও কনফিগারেশন / সেটিংস / টেস্ট.পি ফাইল তৈরি করে যা কোনও কিছুতে ডেটাবাসকে সেট করে না, তখন আমার ইউনিট পরীক্ষাগুলি এটি ছাড়া চলে। এটি আমাকে এমন মডেলগুলি ব্যবহার করার অনুমতি দিয়েছে যাতে বিদেশী কী এবং অনন্য সীমাবদ্ধ ক্ষেত্র ছিল। (বিপরীত বিদেশী কী লুকোচুরির জন্য, যার জন্য ডিবি লুকআপ দরকার, ব্যর্থ হয়))
(জাজানো ২.০..6)
পিএস কোড স্নিপেটস
PROJECT_ROOT_DIR/config/settings/test.py:
from .base import *
#other test settings
#DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': 'PROJECT_ROOT_DIR/db.sqlite3',
# }
#}
cli, run from PROJECT_ROOT_DIR:
./manage.py test path.to.app.test --settings config.settings.test
path/to/app/test.py:
from django.test import SimpleTestCase
from .models import *
#^assume models.py imports User and defines Classified and UpgradePrice
class TestCaseWorkingTest(SimpleTestCase):
def test_case_working(self):
self.assertTrue(True)
def test_models_ok(self):
obj = UpgradePrice(title='test',price=1.00)
self.assertEqual(obj.title,'test')
def test_more_complex_model(self):
user = User(username='testuser',email='hi@hey.com')
self.assertEqual(user.username,'testuser')
def test_foreign_key(self):
user = User(username='testuser',email='hi@hey.com')
ad = Classified(user=user,headline='headline',body='body')
self.assertEqual(ad.user.username,'testuser')
#fails with error:
def test_reverse_foreign_key(self):
user = User(username='testuser',email='hi@hey.com')
ad = Classified(user=user,headline='headline',body='body')
print(user.classified_set.first())
self.assertTrue(True) #throws exception and never gets here
নাক পরীক্ষা চালক (জ্যাঙ্গো-নাক) ব্যবহার করার সময়, আপনি এরকম কিছু করতে পারেন:
my_project/lib/nodb_test_runner.py
:
from django_nose import NoseTestSuiteRunner
class NoDbTestRunner(NoseTestSuiteRunner):
"""
A test runner to test without database creation/deletion
Used for integration tests
"""
def setup_databases(self, **kwargs):
pass
def teardown_databases(self, old_config, **kwargs):
pass
আপনার মধ্যে settings.py
আপনি সেখানে পরীক্ষা রানার নির্দিষ্ট করতে পারেন, যেমন
TEST_RUNNER = 'lib.nodb_test_runner.NoDbTestRunner' . # Was 'django_nose.NoseTestSuiteRunner'
অথবা
আমি এটি কেবল নির্দিষ্ট পরীক্ষা চালানোর জন্য চেয়েছিলাম, তাই আমি এটির মতো চালিয়েছি:
python manage.py test integration_tests/integration_* --noinput --testrunner=lib.nodb_test_runner.NoDbTestRunner