पाइटेस्ट में, हर किसी का पसंदीदा पायथन परीक्षण ढांचा, एक फिक्स्चर कोड का एक पुन: प्रयोज्य टुकड़ा है जो परीक्षण में प्रवेश करने से पहले कुछ व्यवस्थित करता है, और उसके समाप्त होने के बाद सफाई करता है। उदाहरण के लिए, एक अस्थायी फ़ाइल या फ़ोल्डर, सेटअप वातावरण, एक वेब सर्वर शुरू करना, आदि। इस पोस्ट में, हम देखेंगे कि कैसे एक पाइटेस्ट फिक्सचर बनाया जाए जो एक परीक्षण डेटाबेस बनाता है (खाली या ज्ञात स्थिति के साथ) जो प्राप्त होता है साफ़ किया गया, जिससे प्रत्येक परीक्षण को पूरी तरह से साफ़ डेटाबेस पर चलने की अनुमति मिली।
लक्ष्य
हम परीक्षण डेटाबेस को तैयार करने और साफ करने के लिए Psycopg 3 का उपयोग करके एक पाइटेस्ट फिक्स्चर बनाएंगे। क्योंकि एक खाली डेटाबेस परीक्षण के लिए शायद ही कभी सहायक होता है, हम इसे भरने के लिए वैकल्पिक रूप से योयो माइग्रेशन लागू करेंगे (लेखन के समय वेबसाइट बंद है, Archive.org स्नैपशॉट पर जाएं)।
तो, इस ब्लॉगपोस्ट में बनाए गए test_db नामक पाइटेस्ट फिक्स्चर की आवश्यकताएं हैं:
- परीक्षण डेटाबेस ड्रॉप करें यदि परीक्षण से पहले मौजूद है
- परीक्षण से पहले एक खाली डेटाबेस बनाएं
वैकल्पिक रूप से - परीक्षण से पहले माइग्रेशन लागू करें या एक परीक्षण डेटा बनाएं
- परीक्षण डेटाबेस से एक कनेक्शन प्रदान करेंपरीक्षण के लिए
- परीक्षण के बाद परीक्षण डेटाबेस को छोड़ें (विफलता की स्थिति में भी)
कोई भी परीक्षण विधि जो इसे परीक्षण विधि तर्क सूचीबद्ध करके अनुरोध करती है:
def test_create_admin_table(test_db):
...
def test_create_admin_table(test_db):
...
परीक्षण डीबी से जुड़ा एक नियमित Psycopg कनेक्शन उदाहरण प्राप्त होगा। सादे Psycopg सामान्य उपयोग के साथ परीक्षण वह सब कुछ कर सकता है जिसकी उसे आवश्यकता है, उदाहरण के लिए:
def test_create_admin_table(test_db):
# डेटाबेस संचालन करने के लिए एक कर्सर खोलें
cur = test_db.cursor()
# क्वेरी प्लेसहोल्डर्स को भरने के लिए डेटा पास करें और Psycopg को कार्य करने दें
# सही रूपांतरण (कोई SQL इंजेक्शन नहीं!)
cur.execute(
"परीक्षण (संख्या, डेटा) मान (%s, %s) में डालें",
(100, "abc'def"))
# डेटाबेस को क्वेरी करें और डेटा को पायथन ऑब्जेक्ट के रूप में प्राप्त करें।
cur.execute ("परीक्षण से चुनें *")
cur.fetchone()
# वापस आएगा (1, 100, "abc'def")
# आप किसी सूची को वापस करने के लिए `cur.fetchmany()`, `cur.fetchall()` का उपयोग कर सकते हैं
कई रिकॉर्ड्स का #, या यहां तक कि कर्सर पर पुनरावृत्त भी करें
वर्तमान में रिकॉर्ड के लिए:
प्रिंट(रिकॉर्ड)
def test_create_admin_table(test_db):
...
प्रेरणा एवं विकल्प
ऐसा लगता है कि कुछ पाइटेस्ट प्लगइन्स हैं जो डेटाबेस पर निर्भर परीक्षणों के लिए पोस्टग्रेएसक्यूएल फिक्स्चर का वादा करते हैं। वे आपके लिए अच्छा काम कर सकते हैं.
मैंने pytest-postgresql आज़माया है जो यही वादा करता है। मैंने अपना स्वयं का फिक्स्चर लिखने से पहले इसे आज़माया है लेकिन मैं इसे अपने लिए काम में लाने में सक्षम नहीं था। शायद इसलिए क्योंकि उनके दस्तावेज़ मेरे लिए बहुत भ्रमित करने वाले थे।
एक और, pytest-dbt-postgres, मैंने बिल्कुल भी कोशिश नहीं की है।
प्रोजेक्ट फ़ाइल लेआउट
क्लासिक पायथन प्रोजेक्ट में, स्रोत src/ में रहते हैं और परीक्षण test/ में रहते हैं:
├── स्रोत
│ └── तुवोक
│ ├── __init__.py
│ └── बिक्री
│ └── new_user.py
├── परीक्षण
│ ├── conftest.py
│ └── बिक्री
│ └── test_new_user.py
├── आवश्यकताओं.txt
└── yoyo.ini
def test_create_admin_table(test_db):
...
यदि आप फैंटेसी योयो जैसी माइग्रेशन लाइब्रेरी का उपयोग करते हैं, तो माइग्रेशन स्क्रिप्ट माइग्रेशन में होने की संभावना है/:
├── पलायन
├── 20240816_01_Yn3Ca-sales-user-user-add-last-run-table.py
├── ...
def test_create_admin_table(test_db):
...
विन्यास
हमारे परीक्षण डीबी फिक्सचर को बहुत कम कॉन्फ़िगरेशन की आवश्यकता होगी:
- कनेक्शन यूआरएल - (डेटाबेस के बिना)
- परीक्षण डेटाबेस नाम - प्रत्येक परीक्षण के लिए पुनः बनाया जाएगा
(वैकल्पिक रूप से) - माइग्रेशन फ़ोल्डर - प्रत्येक परीक्षण के लिए लागू करने के लिए माइग्रेशन स्क्रिप्ट
पाइटेस्ट के पास कई फाइलों में फिक्स्चर साझा करने के लिए एक प्राकृतिक स्थान conftest.py है। फिक्सचर कॉन्फ़िगरेशन भी वहां जाएगा:
# बिना डीबी नाम के!
TEST_DB_URL = "postgresql://localhost"
TEST_DB_NAME = "test_tuvok"
TEST_DB_MIGRATIONS_DIR = str(पथ(__file__, "../../migrations").resolve())
def test_create_admin_table(test_db):
...
आप इन मानों को पर्यावरण चर से या जो भी आपके मामले में उपयुक्त हो, सेट कर सकते हैं।
test_db फिक्स्चर बनाएं
PostgreSQL और Psycopg लाइब्रेरी के ज्ञान के साथ, conftest.py में फिक्सचर लिखें:
@pytest.fixture
डीईएफ़ test_db():
# ऑटोकमिट = सही है, कोई लेन-देन शुरू नहीं होगा क्योंकि डेटाबेस बनाएं/छोड़ें
# लेनदेन ब्लॉक में निष्पादित नहीं किया जा सकता।
psycopg.connect(TEST_DB_URL, autocommit=True) के साथ conn:
cur = conn.cursor()
# परीक्षण डीबी बनाएं, पहले छोड़ें
cur.execute(f'DROP डेटाबेस यदि "{TEST_DB_NAME}" (बल)' के साथ मौजूद है)
cur.execute(f'डेटाबेस बनाएं "{TEST_DB_NAME}"')
# अभी बनाए गए टेस्ट डीबी में (एक नया) कनेक्शन लौटाएं
# दुर्भाग्य से, आप मौजूदा Psycopg कनेक्शन के लिए डेटाबेस को सीधे नहीं बदल सकते। एक बार जब कोई कनेक्शन किसी विशिष्ट डेटाबेस से स्थापित हो जाता है, तो यह उस डेटाबेस से जुड़ जाता है।
psycopg.connect(TEST_DB_URL, dbname=TEST_DB_NAME) के साथ conn:
उपज कॉन
cur.execute(f'DROP डेटाबेस यदि "{TEST_DB_NAME}" (बल)' के साथ मौजूद है)
def test_create_admin_table(test_db):
...
माइग्रेशन फिक्सचर बनाएं
हमारे मामले में, हम
योयो माइग्रेशन का उपयोग करते हैं। योयो नामक एक अन्य फिक्स्चर के रूप में माइग्रेशन लागू करें लिखें:
@pytest.fixture
डिफ योयो():
# योयो `driver://user:pass@host:port/database_name?param=value` की अपेक्षा रखता है।
# पारित यूआरएल में हमें इसकी आवश्यकता है
यूआरएल = (
urlparse(TEST_DB_URL)
.
# 1) उपयोग करने के लिए ड्राइवर (स्कीमा भाग) को `postgresql psycopg` से बदलें
# psycopg 3 (2 नहीं जो `postgresql psycopg2` है)
_प्रतिस्थापन(योजना='पोस्टग्रेस्क्ल psycopg')
.
#2) डेटाबेस को टेस्ट डीबी में बदलें (जिसमें माइग्रेशन लागू होगा)
_प्रतिस्थापन(पथ=TEST_DB_NAME)
.geturl()
)
बैकएंड = get_backend(यूआरएल)
माइग्रेशन = read_migrations(TEST_DB_MIGRATIONS_DIR)
यदि लेन(माइग्रेशन) == 0:
वैल्यूएरर बढ़ाएं(f"'{TEST_DB_MIGRATIONS_DIR}'' में कोई योयो माइग्रेशन नहीं मिला")
बैकएंड.लॉक() के साथ:
बैकएंड.अप्लाई_माइग्रेशन(बैकएंड.टू_अप्लाई(माइग्रेशन))
def test_create_admin_table(test_db):
...
यदि आप
प्रत्येक परीक्षण डेटाबेस में माइग्रेशन लागू करना चाहते हैं, तो test_db फिक्स्चर के लिए योयो फिक्स्चर की आवश्यकता है:
@pytest.fixture
डीईएफ़ test_db(योयो):
...
def test_create_admin_table(test_db):
...
केवल कुछ परीक्षणों के लिए माइग्रेशन लागू करने के लिए, व्यक्तिगत रूप से योयो की आवश्यकता होती है:
def test_create_admin_table(test_db, yoyo):
...
def test_create_admin_table(test_db):
...
निष्कर्ष
अपने परीक्षणों को एक स्वच्छ डेटाबेस देने के लिए स्वयं का फिक्स्चर बनाना मेरे लिए एक पुरस्कृत अनुभव था, जिससे मुझे पाइटेस्ट और पोस्टग्रेज दोनों में गहराई से जाने का मौका मिला।
मुझे आशा है कि इस लेख ने आपको अपने डेटाबेस परीक्षण सूट में मदद की है। बेझिझक मुझे अपना प्रश्न टिप्पणियों में छोड़ें और कोडिंग का आनंद लें!