इंजीनियरों के रूप में, हम ऐसी चीजें बनाना चाहते हैं जो काम करें , लेकिन हम जो भी नई सुविधा बनाते हैं, उसके साथ हम अनिवार्य रूप से अपने ऐप्स का आकार और जटिलता बढ़ाते हैं।
जैसे-जैसे उत्पाद बढ़ता है, आपके परिवर्तनों से प्रभावित प्रत्येक कार्यक्षमता का मैन्युअल रूप से (उदाहरण के लिए, अपने हाथों से) परीक्षण करना अधिक समय लेने वाला हो जाता है।
स्वचालित परीक्षणों की अनुपस्थिति के कारण हमें या तो बहुत अधिक समय खर्च करना पड़ता है और हमारी शिपिंग गति धीमी हो जाती है या वेग को बचाने के लिए बहुत कम खर्च करना पड़ता है, जिसके परिणामस्वरूप पेजरड्यूटी से देर रात की कॉल के साथ-साथ बैकलॉग में नई बगें पैदा होती हैं।
इसके विपरीत, कंप्यूटर को बार-बार एक ही कार्य करने के लिए प्रोग्राम किया जा सकता है । तो, आइए परीक्षण को कंप्यूटर पर सौंपें!
परीक्षण पिरामिड विचार तीन मुख्य प्रकार के परीक्षणों का सुझाव देता है: इकाई, एकीकरण और अंत-से-अंत। आइए प्रत्येक प्रकार की गहराई में उतरें और समझें कि हमें प्रत्येक की आवश्यकता क्यों है।
एक इकाई तर्क का एक छोटा टुकड़ा है जिसे आप अलग से परीक्षण करते हैं (अन्य घटकों पर भरोसा किए बिना)।
यूनिट परीक्षण तेज़ हैं. वे कुछ ही सेकंड में ख़त्म हो जाते हैं. अलगाव उन्हें किसी भी समय, स्थानीय स्तर पर और सीआई पर, आश्रित सेवाओं को स्पिन किए बिना/एपीआई और डेटाबेस कॉल किए बिना चलाने की अनुमति देता है।
इकाई परीक्षण उदाहरण: एक फ़ंक्शन जो दो संख्याओं को स्वीकार करता है और उनका एक साथ योग करता है। हम इसे अलग-अलग तर्कों के साथ कॉल करना चाहते हैं और दावा करना चाहते हैं कि लौटाया गया मान सही है।
// Function "sum" is the unit const sum = (x, y) => x + y test('sums numbers', () => { // Call the function, record the result const result = sum(1, 2); // Assert the result expect(result).toBe(3) }) test('sums numbers', () => { // Call the function, record the result const result = sum(5, 10); // Assert the result expect(result).toBe(15) })
एक अधिक दिलचस्प उदाहरण रिएक्ट घटक है जो एपीआई अनुरोध समाप्त होने के बाद कुछ पाठ प्रस्तुत करता है। हमें अपने परीक्षणों के लिए आवश्यक मान लौटाने, घटक प्रस्तुत करने और यह दावा करने के लिए एपीआई मॉड्यूल का अनुकरण करने की आवश्यकता है कि प्रस्तुत HTML में वह सामग्री है जिसकी हमें आवश्यकता है।
// "MyComponent" is the unit const MyComponent = () => { const { isLoading } = apiModule.useSomeApiCall(); return isLoading ? <div>Loading...</div> : <div>Hello world</div> } test('renders loading spinner when loading', () => { // Mocking the API module, so that it returns the value we need jest.mock(apiModule).mockReturnValue(() => ({ useSomeApiCall: jest.fn(() => ({ // Return "isLoading: false" for this test case isLoading: false })) })) // Execute the unit (render the component) const result = render(<MyComponent />) // Assert the result result.findByText('Loading...').toBeInTheDocument() }) test('renders text content when not loading', () => { // Mocking the API module jest.mock(apiModule).mockReturnValue(() => ({ useSomeApiCall: jest.fn(() => ({ // Return "isLoading: false" for this test case isLoading: false })) })) // Execute the unit (render the component) const result = render(<MyComponent />) // Assert the result result.findByText('Hello world').toBeInTheDocument() })
जब आपकी इकाई अन्य इकाइयों (निर्भरताओं) के साथ इंटरैक्ट करती है, तो हम इसे एक एकीकरण कहते हैं। ये परीक्षण यूनिट परीक्षणों की तुलना में धीमे हैं, लेकिन वे परीक्षण करते हैं कि आपके ऐप के हिस्से कैसे जुड़ते हैं।
एकीकरण परीक्षण उदाहरण: एक सेवा जो डेटाबेस में उपयोगकर्ता बनाती है। परीक्षण निष्पादित होने पर इसके लिए एक DB उदाहरण ( निर्भरता ) उपलब्ध होना आवश्यक है। हम परीक्षण करेंगे कि सेवा डीबी से उपयोगकर्ता बना और पुनर्प्राप्त कर सकती है।
import db from 'db' // We will be testing "createUser" and "getUser" const createUser = name => db.createUser(name) // creates a user const getUser = name => db.getUserOrNull(name) // retrieves a user or null test("creates and retrieves users", () => { // Try to get a user that doesn't exist, assert Null is returned const nonExistingUser = getUser("i don't exist") expect(nonExistingUser).toBe(null); // Create a user const userName = "test-user" createUser(userName); // Get the user that was just created, assert it's not Null const user = getUser(userName); expect(user).to.not.be(null) })
जब हम पूरी तरह से तैनात ऐप का परीक्षण करते हैं, तो यह एक एंड-टू-एंड परीक्षण होता है, जहां इसकी सभी निर्भरताएं उपलब्ध होती हैं। वे परीक्षण वास्तविक उपयोगकर्ता व्यवहार का सबसे अच्छा अनुकरण करते हैं और आपको अपने ऐप में सभी संभावित मुद्दों को पकड़ने की अनुमति देते हैं, लेकिन वे सबसे धीमे प्रकार के परीक्षण हैं।
जब भी आप एंड-टू-एंड परीक्षण चलाना चाहते हैं, तो आपको सभी बुनियादी ढांचे का प्रावधान करना होगा और सुनिश्चित करना होगा कि आपके वातावरण में तृतीय पक्ष प्रदाता उपलब्ध हैं।
आप उन्हें केवल अपने ऐप के मिशन-महत्वपूर्ण सुविधाओं के लिए रखना चाहते हैं।
आइए शुरू से अंत तक परीक्षण उदाहरण पर एक नज़र डालें: लॉगिन प्रवाह। हम ऐप पर जाना चाहते हैं, लॉगिन विवरण भरना चाहते हैं, सबमिट करना चाहते हैं और स्वागत संदेश देखना चाहते हैं।
test('user can log in', () => { // Visit the login page page.goto('https://example.com/login'); // Fill in the login form page.fill('#username', 'john'); page.fill('#password', 'some-password'); // Click the login button page.click('#login-button'); // Assert the welcome message is visible page.assertTextVisible('Welcome, John!') })
याद रखें कि एंड-टू-एंड परीक्षण एकीकरण की तुलना में धीमे होते हैं , और एकीकरण परीक्षण यूनिट परीक्षणों की तुलना में धीमे होते हैं ।
यदि आप जिस सुविधा पर काम कर रहे हैं वह मिशन-महत्वपूर्ण है, तो कम से कम एक एंड-टू-एंड परीक्षण लिखने पर विचार करें (जैसे कि प्रमाणीकरण प्रवाह विकसित करते समय लॉगिन कार्यक्षमता कैसे काम करती है इसकी जांच करना)।
मिशन-महत्वपूर्ण प्रवाह के अलावा, हम यथासंभव अधिक से अधिक एज मामलों और फीचर की विभिन्न स्थितियों का परीक्षण करना चाहते हैं। एकीकरण परीक्षण हमें यह परीक्षण करने की अनुमति देते हैं कि ऐप के हिस्से एक साथ कैसे काम करते हैं।
एंडपॉइंट और क्लाइंट घटकों के लिए एकीकरण परीक्षण करना एक अच्छा विचार है। समापन बिंदुओं को संचालन करना चाहिए, अपेक्षित परिणाम देना चाहिए, और कोई अप्रत्याशित त्रुटि नहीं देनी चाहिए।
क्लाइंट घटकों को सही सामग्री प्रदर्शित करनी चाहिए और उपयोगकर्ता के इंटरैक्शन पर उसी तरह प्रतिक्रिया देनी चाहिए जैसे आप उनसे प्रतिक्रिया की अपेक्षा करते हैं।
और अंततः, हमें यूनिट परीक्षण कब चुनना चाहिए? सभी छोटे फ़ंक्शन जिन्हें अलग से परीक्षण किया जा सकता है, जैसे sum
जो संख्याओं का योग करता है, Button
जो <button>
टैग प्रस्तुत करता है, यूनिट परीक्षणों के लिए महान उम्मीदवार हैं। यदि आप परीक्षण संचालित विकास दृष्टिकोण का पालन करते हैं तो इकाइयाँ उत्तम हैं।
कुछ परीक्षण लिखें! (लेकिन छोटी शुरुआत करें)
यह कैसे काम करता है यह समझने के लिए उपरोक्त चीजें एक बार करें। फिर, कुछ फीचर/बग कार्य के दौरान इसे दोबारा करें। फिर इसे अपने सहकर्मियों के साथ साझा करें ताकि आप सभी परीक्षण लिख सकें, समय बचा सकें और रात में बेहतर नींद ले सकें!