---
title: "`test::nginx` के परीक्षण विधियाँ: कॉन्फ़िगरेशन, अनुरोध भेजना, और प्रतिक्रियाओं को संभालना - API7.ai"
description: "यह लेख बताता है कि कैसे test::nginx का उपयोग करके एक test case में requests भेजें और responses को हैंडल करें।"
url: "https://api7.ai/hi/learning-center/openresty/all-inclusive-testing-methods-test-nginx"
---

# \`test::nginx\` के परीक्षण विधियाँ: कॉन्फ़िगरेशन, अनुरोध भेजना, और प्रतिक्रियाओं को संभालना

API7.ai

November 18, 2022

[OpenResty (NGINX + Lua)](https://api7.ai/learning-center/openresty)

पिछले लेख तक, हमने `test::nginx` का पहला झलक देख लिया है और सबसे सरल उदाहरण चला लिया है। हालांकि, एक वास्तविक ओपन-सोर्स प्रोजेक्ट में, `test::nginx` में लिखे गए टेस्ट केस सैंपल कोड की तुलना में कहीं अधिक जटिल और महारत हासिल करने में कठिन होते हैं। अन्यथा, इसे रोडब्लॉक नहीं कहा जाता।

इस लेख में, मैं आपको `test::nginx` में अक्सर उपयोग किए जाने वाले कमांड्स और टेस्ट विधियों के माध्यम से ले जाऊंगा, ताकि आप OpenResty प्रोजेक्ट में अधिकांश टेस्ट केस सेट को समझ सकें और अधिक वास्तविक टेस्ट केस लिखने की क्षमता प्राप्त कर सकें। भले ही आपने अभी तक OpenResty में कोड योगदान नहीं दिया हो, OpenResty के टेस्टिंग फ्रेमवर्क से परिचित होना आपके काम में टेस्ट केस डिजाइन और लिखने के लिए एक बड़ी प्रेरणा होगा।

`test::nginx` टेस्ट मूल रूप से प्रत्येक टेस्ट केस के कॉन्फ़िगरेशन के आधार पर `nginx.conf` जनरेट करता है और एक NGINX प्रक्रिया शुरू करता है। फिर, यह निर्दिष्ट अनुरोध बॉडी और हेडर्स के साथ एक क्लाइंट अनुरोध का अनुकरण करता है। इसके बाद, टेस्ट केस में Lua कोड अनुरोध को प्रोसेस करता है और एक प्रतिक्रिया बनाता है। इस समय, `test::nginx` प्रतिक्रिया बॉडी, प्रतिक्रिया हेडर्स, और त्रुटि लॉग जैसी महत्वपूर्ण जानकारी को पार्स करता है और उनकी तुलना टेस्ट कॉन्फ़िगरेशन से करता है। यदि कोई अंतर होता है, तो टेस्ट विफल हो जाता है और एक त्रुटि दिखाई देती है; अन्यथा, यह सफल होता है।

`test::nginx` बहुत सारे DSL (डोमेन-विशिष्ट भाषा) प्रिमिटिव प्रदान करता है। मैंने NGINX को कॉन्फ़िगर करने, अनुरोध भेजने, प्रतिक्रिया प्रोसेस करने, और लॉग की जांच करने के अनुसार एक सरल वर्गीकरण किया है। यह 20% कार्यक्षमता 80% एप्लिकेशन परिदृश्यों को कवर कर सकती है, इसलिए हमें इस पर मजबूत पकड़ बनानी चाहिए। अन्य अधिक उन्नत प्रिमिटिव और उपयोग के बारे में, हम अगले लेख में चर्चा करेंगे।

## NGINX कॉन्फ़िगरेशन

पहले NGINX कॉन्फ़िगरेशन को देखते हैं। `test::nginx` का "config" कीवर्ड वाला प्रिमिटिव NGINX कॉन्फ़िगरेशन से संबंधित है, जैसे `config`, `stream_config`, `http_config`, आदि।

इनके कार्य समान हैं: निर्दिष्ट NGINX कॉन्फ़िगरेशन को विभिन्न NGINX संदर्भों में डालना। ये कॉन्फ़िगरेशन या तो NGINX कमांड हो सकते हैं या `content_by_lua_block` में संलग्न Lua कोड।

यूनिट टेस्ट करते समय, `config` सबसे अधिक उपयोग किया जाने वाला प्रिमिटिव है जिसमें हम Lua लाइब्रेरीज़ लोड करते हैं और व्हाइट-बॉक्स टेस्टिंग के लिए फ़ंक्शन कॉल करते हैं। यहां एक टेस्ट कोड स्निपेट है, जो पूरी तरह से नहीं चल सकता है। यह एक वास्तविक ओपन-सोर्स प्रोजेक्ट से है, इसलिए यदि आप रुचि रखते हैं, तो आप पूर्ण टेस्ट देखने के लिए [लिंक](https://github.com/apache/apisix/blob/master/t/plugin/key-auth.t#L11) पर क्लिक कर सकते हैं, या आप इसे स्थानीय रूप से चलाने का प्रयास कर सकते हैं।

```
=== TEST 1: sanity
--- config
    location /t {
        content_by_lua_block {
            local plugin = require("apisix.plugins.key-auth")
            local ok, err = plugin.check_schema({key = 'test-key'})
            if not ok then
                ngx.say(err)
            end
            ngx.say("done")
        }
    }
```

इस टेस्ट केस का उद्देश्य `plugins.key-auth` कोड फ़ाइल में `check_schema` फ़ंक्शन की जांच करना है कि यह सही ढंग से काम करता है या नहीं। यह `location /t` में `content_by_lua_block` NGINX कमांड का उपयोग करता है ताकि टेस्ट किए जाने वाले मॉड्यूल को रिक्वायर किया जा सके और सीधे जांचे जाने वाले फ़ंक्शन को कॉल किया जा सके।

यह `test::nginx` में व्हाइट-बॉक्स टेस्टिंग का एक सामान्य तरीका है। हालांकि, यह कॉन्फ़िगरेशन अकेले टेस्ट को पूरा करने के लिए पर्याप्त नहीं है, इसलिए आगे बढ़ते हैं और देखते हैं कि क्लाइंट अनुरोध कैसे भेजा जाए।

## अनुरोध भेजना

क्लाइंट द्वारा अनुरोध भेजने का अनुकरण करने में काफी विवरण शामिल होते हैं, इसलिए सबसे सरल से शुरू करते हैं - एकल अनुरोध भेजना।

### `request`

उपरोक्त टेस्ट केस को जारी रखते हुए, यदि हम चाहते हैं कि यूनिट टेस्ट कोड चले, तो हमें कॉन्फ़िग में निर्दिष्ट `/t` पते पर एक HTTP अनुरोध शुरू करना होगा, जैसा कि निम्नलिखित टेस्ट कोड में दिखाया गया है:

```
--- request
GET /t
```

यह कोड अनुरोध प्रिमिटिव में `/t` पर एक `GET` अनुरोध भेजता है। यहां, हम एक्सेस के IP पते, डोमेन नाम, या पोर्ट को निर्दिष्ट नहीं करते हैं, न ही यह निर्दिष्ट करते हैं कि यह `HTTP 1.0` या `HTTP 1.1` है। ये सभी विवरण `test::nginx` द्वारा छिपाए जाते हैं, इसलिए हमें इनकी चिंता करने की आवश्यकता नहीं है। यह DSL का एक लाभ है - हमें केवल व्यावसायिक तर्क पर ध्यान केंद्रित करने की आवश्यकता है, सभी विवरणों से विचलित होने की नहीं।

इसके अलावा, यह आंशिक लचीलापन प्रदान करता है। उदाहरण के लिए, डिफ़ॉल्ट रूप से `HTTP 1.1` के लिए प्रोटोकॉल है, या यदि हम `HTTP 1.0` का परीक्षण करना चाहते हैं, तो हम अलग से निर्दिष्ट कर सकते हैं:

```
--- request
GET /t  HTTP/1.0
```

`GET` विधि के अलावा, `POST` विधि का भी समर्थन करने की आवश्यकता है। निम्नलिखित उदाहरण में, हम स्ट्रिंग `hello world` को निर्दिष्ट पते पर `POST` कर सकते हैं।

```
--- request
POST /t  
hello world
```

फिर से, `test::nginx` यहां आपके लिए अनुरोध बॉडी की लंबाई की गणना करता है, और `host` और `connection` अनुरोध हेडर्स को स्वचालित रूप से जोड़ता है ताकि यह सुनिश्चित हो सके कि यह एक सामान्य अनुरोध है।

बेशक, हम इसे और अधिक पठनीय बनाने के लिए टिप्पणियाँ जोड़ सकते हैं। `#` से शुरू होने वाली टिप्पणियाँ कोड टिप्पणियों के रूप में पहचानी जाएंगी।

```
--- request
# post request
POST /t  
hello world
```

अनुरोध एक अधिक जटिल और लचीली मोड का भी समर्थन करता है, जो `eval` को एक फ़िल्टर के रूप में उपयोग करता है ताकि Perl कोड को सीधे एम्बेड किया जा सके क्योंकि `test::nginx` Perl में लिखा गया है। यदि वर्तमान DSL भाषा आपकी आवश्यकताओं को पूरा नहीं करती है, तो `eval` Perl कोड को सीधे निष्पादित करने का "अंतिम हथियार" है।

`eval` के उपयोग के लिए, यहां कुछ सरल उदाहरण देखते हैं, और हम अगले लेख में अन्य अधिक जटिल उदाहरणों के साथ जारी रखेंगे।

```
--- request eval
"POST /t
hello\x00\x01\x02
world\x03\x04\xff"
```

पहले उदाहरण में, हम `eval` का उपयोग करके गैर-प्रिंटेबल वर्णों को निर्दिष्ट करते हैं, जो इसके उपयोगों में से एक है। डबल कोट्स के बीच की सामग्री को Perl स्ट्रिंग के रूप में माना जाएगा और फिर `request` को एक तर्क के रूप में पास किया जाएगा।

यहां एक और दिलचस्प उदाहरण है:

```
--- request eval
"POST /t\n" . "a" x 1024
```

हालांकि, इस उदाहरण को समझने के लिए, हमें Perl में स्ट्रिंग्स के बारे में कुछ जानना होगा, इसलिए मुझे यहां दो बिंदुओं का संक्षेप में उल्लेख करना होगा।

- Perl में, हम स्ट्रिंग संयोजन के लिए एक डॉट का उपयोग करते हैं। क्या यह `Lua` के दो डॉट्स से कुछ हद तक समान नहीं है?
- एक लोअरकेस `x` एक वर्ण को दोहराने की संख्या को दर्शाता है। उदाहरण के लिए, उपरोक्त `"a" x 1024` का अर्थ है कि वर्ण "a" को 1024 बार दोहराया जाएगा।

तो, दूसरे उदाहरण का अर्थ है कि `POST` विधि `/t` पते पर `1024` वर्ण `a` वाले अनुरोध को भेजता है।

### `pipelined_requests`

एकल अनुरोध भेजने का तरीका समझने के बाद, आइए देखें कि कैसे कई अनुरोध भेजे जाएं। `test::nginx` में, हम `pipelined_requests` प्रिमिटिव का उपयोग करके एक ही `keep-alive` कनेक्शन के भीतर कई अनुरोधों को क्रमिक रूप से भेज सकते हैं:

```
--- pipelined_requests eval
["GET /hello", "GET /world", "GET /foo", "GET /bar"]
```

उदाहरण के लिए, यह उदाहरण एक ही कनेक्शन में इन चार APIs को क्रमिक रूप से एक्सेस करेगा। इसके दो लाभ हैं:

- पहला यह है कि बहुत सारे दोहराव वाले टेस्ट कोड को समाप्त किया जा सकता है, और चार टेस्ट केस को एक में संपीड़ित किया जा सकता है।
- दूसरा और सबसे महत्वपूर्ण कारण यह है कि हम पाइपलाइन्ड अनुरोधों का उपयोग करके यह पता लगा सकते हैं कि क्या कोड लॉजिक कई एक्सेस के मामले में अपवाद होगा।

आप सोच रहे होंगे, मैं कई टेस्ट केस को क्रमिक रूप से लिखता हूं, तो कोड भी निष्पादन चरण में कई बार निष्पादित होगा। क्या यह उपरोक्त दूसरी समस्या को भी कवर नहीं करता है?

यह `test::nginx` के निष्पादन मोड पर निर्भर करता है, जो आपके विचार से अलग तरीके से काम करता है। प्रत्येक टेस्ट केस के बाद, `test::nginx` वर्तमान NGINX प्रक्रिया को बंद कर देता है, और मेमोरी में सभी डेटा गायब हो जाता है। अगले टेस्ट केस को चलाते समय, `nginx.conf` को फिर से जनरेट किया जाता है, और एक नया NGINX `Worker` शुरू किया जाता है। यह तंत्र सुनिश्चित करता है कि टेस्ट केस एक दूसरे को प्रभावित नहीं करते हैं।

इसलिए, जब हम कई अनुरोधों का परीक्षण करना चाहते हैं, तो हमें `pipelined_requests` प्रिमिटिव का उपयोग करने की आवश्यकता होती है। इसके आधार पर, हम रेट-लिमिटिंग, कंकरेंसी-लिमिटिंग, और कई अन्य परिदृश्यों का अनुकरण कर सकते हैं ताकि यह परीक्षण किया जा सके कि आपका सिस्टम अधिक वास्तविक और जटिल परिदृश्यों में सही ढंग से काम करता है। हम इसे अगले लेख के लिए भी छोड़ देंगे, क्योंकि इसमें कई कमांड्स और प्रिमिटिव्स शामिल होंगे।

### `repeat_each`

हमने अभी कई अनुरोधों का परीक्षण करने के मामले का उल्लेख किया है, तो एक ही टेस्ट को कई बार निष्पादित करने के लिए हमें क्या करना चाहिए?

इस समस्या के लिए, `test::nginx` एक वैश्विक सेटिंग प्रदान करता है: `repeat_each`, जो एक Perl फ़ंक्शन है जो डिफ़ॉल्ट रूप से `repeat_each(1)` होता है, जो इंगित करता है कि टेस्ट केस केवल एक बार चलेगा। इसलिए पिछले टेस्ट केस में, हम इसे अलग से सेट करने की परेशानी नहीं उठाते हैं।

स्वाभाविक रूप से, हम इसे `run_test()` फ़ंक्शन से पहले सेट कर सकते हैं, उदाहरण के लिए, तर्क को `2` में बदलकर।

```
repeat_each(2);
run_tests();
```

फिर, प्रत्येक टेस्ट केस दो बार चलेगा, और इसी तरह।

### `more_headers`

अनुरोध बॉडी के बारे में बात करने के बाद, आइए अनुरोध हेडर्स को देखें। जैसा कि हमने ऊपर उल्लेख किया है, `test::nginx` डिफ़ॉल्ट रूप से `host` और `connection` हेडर्स के साथ अनुरोध भेजता है। अन्य अनुरोध हेडर्स के बारे में क्या?

`more_headers` विशेष रूप से इसके लिए बनाया गया है।

```
--- more_headers
X-Foo: blah
```

हम इसका उपयोग विभिन्न कस्टम हेडर्स सेट करने के लिए कर सकते हैं। यदि हम एक से अधिक हेडर सेट करना चाहते हैं, तो एक से अधिक लाइन सेट करें:

```
--- more_headers
X-Foo: 3
User-Agent: openresty
```

## प्रतिक्रिया प्रोसेस करना

अनुरोध भेजने के बाद, `test::nginx` का सबसे महत्वपूर्ण हिस्सा प्रतिक्रिया को प्रोसेस करना है, जहां हम यह निर्धारित करेंगे कि प्रतिक्रिया अपेक्षाओं को पूरा करती है या नहीं। यहां हम इसे चार भागों में विभाजित करते हैं और उनका परिचय देते हैं: प्रतिक्रिया बॉडी, प्रतिक्रिया हेडर, प्रतिक्रिया स्थिति कोड, और लॉग।

### `response_body`

अनुरोध प्रिमिटिव का प्रतिरूप `response_body` है, और निम्नलिखित उनके दो कॉन्फ़िगरेशन के उपयोग का एक उदाहरण है:

```
=== TEST 1: sanity
--- config
    location /t {
        content_by_lua_block {
            ngx.say("hello")
        }
    }
--- request
GET /t
--- response_body
hello
```

यह टेस्ट केस पास होगा यदि प्रतिक्रिया बॉडी `hello` है, और अन्य मामलों में त्रुटि रिपोर्ट करेगा। लेकिन हम एक लंबी वापसी बॉडी के लिए कैसे परीक्षण करें? चिंता न करें, `test::nginx` ने पहले ही आपके लिए इसका ध्यान रखा है। यह नियमित अभिव्यक्ति के साथ प्रतिक्रिया बॉडी का पता लगाने का समर्थन करता है, जैसे निम्नलिखित:

```
--- response_body_like
^he\w+$
```

यह आपको प्रतिक्रिया बॉडी के साथ बहुत लचीला बनाता है। इसके अलावा, `test::nginx` `unlike` ऑपरेशन का भी समर्थन करता है:

```
--- response_body_unlike
^he\w+$
```

इस बिंदु पर, यदि प्रतिक्रिया बॉडी `hello` है, तो टेस्ट पास नहीं होगा।

इसी तरह, एकल अनुरोध का पता लगाने को समझने के बाद, आइए कई अनुरोधों का पता लगाने को देखें। यहां `pipelined_requests` के साथ इसका उपयोग करने का एक उदाहरण है:

```
--- pipelined_requests eval
["GET /hello", "GET /world", "GET /foo", "GET /bar"]
--- response_body eval
["hello", "world", "oo", "bar"]
```

बेशक, यहां ध्यान देने योग्य महत्वपूर्ण बात यह है कि जितने अनुरोध आप भेजते हैं, उतने ही प्रतिक्रियाओं की आवश्यकता होती है।

### `response_headers`

दूसरा, प्रतिक्रिया हेडर के बारे में बात करते हैं। प्रतिक्रिया हेडर अनुरोध हेडर के समान है जहां प्रत्येक लाइन एक हेडर की कुंजी और मान से मेल खाती है।

```
--- response_headers
X-RateLimit-Limit: 2
X-RateLimit-Remaining: 1
```

प्रतिक्रिया बॉडी के पता लगाने की तरह, प्रतिक्रिया हेडर भी नियमित अभिव्यक्ति और `unlike` ऑपरेशन का समर्थन करते हैं, जैसे `response_headers_like`, `raw_response_headers_like`, और `raw_response_headers_unlike`।

### `error_code`

तीसरा प्रतिक्रिया कोड है। प्रतिक्रिया कोड का पता लगाना सीधे तुलना का समर्थन करता है और `like` ऑपरेशन का भी समर्थन करता है, जैसे निम्नलिखित दो उदाहरण:

```
--- error_code: 302
```

```
--- error_code_like: ^(?:500)?$
```

कई अनुरोधों के मामले में, `error_code` को कई बार जांचने की आवश्यकता होती है:

```
--- pipelined_requests eval
["GET /hello", "GET /hello", "GET /hello", "GET /hello"]
--- error_code eval
[200, 200, 503, 503]
```

### `error_log`

अंतिम टेस्ट आइटम त्रुटि लॉग है। अधिकांश टेस्ट केस में, कोई त्रुटि लॉग उत्पन्न नहीं होता है। हम `no_error_log` का उपयोग करके पता लगा सकते हैं:

```
--- no_error_log
[error]
```

उपरोक्त उदाहरण में, यदि NGINX `error.log` में स्ट्रिंग `[error]` दिखाई देती है, तो टेस्ट विफल हो जाएगा। यह एक बहुत ही सामान्य सुविधा है, और यह अनुशंसा की जाती है कि आप अपने सभी सामान्य टेस्ट में त्रुटि लॉग का पता लगाने को जोड़ें।

```
--- error_log
hello world
```

उपरोक्त कॉन्फ़िगरेशन `error.log` में `hello world` की उपस्थिति का पता लगा रहा है। बेशक, आप Perl कोड में एम्बेडेड `eval` का उपयोग करके नियमित अभिव्यक्ति का पता लगाने को लागू कर सकते हैं, जैसे निम्नलिखित:

```
--- error_log eval
qr/\[notice\] .*?  \d+ hello world/
```

## सारांश

आज, हम `test::nginx` में अनुरोध भेजने और प्रतिक्रिया का परीक्षण करने का तरीका सीख रहे हैं, जिसमें अनुरोध बॉडी, हेडर, प्रतिक्रिया स्थिति कोड, और त्रुटि लॉग शामिल हैं। हम इन प्रिमिटिव्स के संयोजन के साथ टेस्ट केस का एक पूरा सेट लागू कर सकते हैं।

अंत में, यहां एक सोचने वाला प्रश्न है: `test::nginx`, एक अमूर्त DSL के क्या फायदे और नुकसान हैं? मुझे टिप्पणियाँ छोड़ने और मेरे साथ चर्चा करने के लिए स्वतंत्र महसूस करें, और आप इस लेख को साझा करके एक साथ संवाद और सोचने के लिए भी आमंत्रित हैं।

Share article link

Share

Related Posts

[![OpenResty FAQ | टेस्टिंग के लिए नेटवर्क संरचना, SSL-संबंधित सुविधाएँ, DSL, \`ab\` टूल](https://static.api7.ai/2022/12/02/63896c177fde1.png)](https://api7.ai/learning-center/openresty/faq-3)

## [OpenResty FAQ | टेस्टिंग के लिए नेटवर्क संरचना, SSL-संबंधित सुविधाएँ, DSL, \`ab\` टूल](https://api7.ai/learning-center/openresty/faq-3)

[![\`test::nginx\` का कम ज्ञात उपयोग](https://static.api7.ai/2022/11/25/63802a7fb4697.png)](https://api7.ai/learning-center/openresty/little-known-usage-of-test-nginx)

## [\`test::nginx\` का कम ज्ञात उपयोग](https://api7.ai/learning-center/openresty/little-known-usage-of-test-nginx)

Table of Contents

- [NGINX कॉन्फ़िगरेशन](#nginx-%E0%A4%95%E0%A5%89%E0%A4%A8%E0%A5%8D%E0%A4%AB%E0%A4%BC%E0%A4%BF%E0%A4%97%E0%A4%B0%E0%A5%87%E0%A4%B6%E0%A4%A8)

- [अनुरोध भेजना](#%E0%A4%85%E0%A4%A8%E0%A5%81%E0%A4%B0%E0%A5%8B%E0%A4%A7-%E0%A4%AD%E0%A5%87%E0%A4%9C%E0%A4%A8%E0%A4%BE)

  - [`request`](#request)
  - [`pipelined_requests`](#pipelined_requests)
  - [`repeat_each`](#repeat_each)
  - [`more_headers`](#more_headers)

- [प्रतिक्रिया प्रोसेस करना](#%E0%A4%AA%E0%A5%8D%E0%A4%B0%E0%A4%A4%E0%A4%BF%E0%A4%95%E0%A5%8D%E0%A4%B0%E0%A4%BF%E0%A4%AF%E0%A4%BE-%E0%A4%AA%E0%A5%8D%E0%A4%B0%E0%A5%8B%E0%A4%B8%E0%A5%87%E0%A4%B8-%E0%A4%95%E0%A4%B0%E0%A4%A8%E0%A4%BE)

  - [`response_body`](#response_body)
  - [`response_headers`](#response_headers)
  - [`error_code`](#error_code)
  - [`error_log`](#error_log)

- [सारांश](#%E0%A4%B8%E0%A4%BE%E0%A4%B0%E0%A4%BE%E0%A4%82%E0%A4%B6)
