परीक्षण व्यवस्थित करने के लिए PHPUnit सर्वोत्तम प्रथाओं




(2)

मैं मैन्युअल से लिंक करके और फिर मैंने जो देखा और उस क्षेत्र में सुना है, उसमें जाकर शुरू करूंगा।

Phpunit परीक्षण सूट व्यवस्थित करना

फ़ाइल सिस्टम में मॉड्यूल / टेस्ट फ़ोल्डर संगठन

मेरा अनुशंसित दृष्टिकोण फ़ाइल सिस्टम को एक एक्सएमएल कॉन्फ़िगरेशन के साथ जोड़ रहा है।

tests/
 \ unit/
 | - module1
 | - module2
 - integration/
 - functional/

एक phpunit.xml साथ एक सरल के साथ:

<testsuites>
  <testsuite name="My whole project">
    <directory>tests</directory>
  </testsuite>
</testsuites>

यदि आप चाहें तो परीक्षणों को विभाजित कर सकते हैं लेकिन यह प्रोजेक्ट पसंद करने के लिए एक प्रोजेक्ट है।

phpunit चलाना तब सभी परीक्षण निष्पादित करेगा और phpunit tests/unit/module1 चल रहा है phpunit tests/unit/module1 सभी परीक्षण चलाएगा।

"यूनिट" फ़ोल्डर का संगठन

यहां सबसे आम तरीका है अपने source/ निर्देशिका संरचना में अपने source/ निर्देशिका संरचना में दर्पण करना।

आपके पास प्रति टेस्ट क्लास प्रति उत्पादन क्लास है, इसलिए यह मेरी पुस्तक में एक अच्छा दृष्टिकोण है।

फाइल संगठन में

  • एक प्रति फ़ाइल एक वर्ग।

यदि आप एक फ़ाइल में एक से अधिक टेस्ट क्लास हैं तो यह किसी भी तरह से काम नहीं करेगा, इसलिए उस पतन से बचें।

  • परीक्षण नामस्थान नहीं है

यह सिर्फ परीक्षण को अधिक वर्बोज़ लिखता है क्योंकि आपको अतिरिक्त उपयोग कथन की आवश्यकता होती है, इसलिए मैं कहूंगा कि टेस्ट क्लास को उत्पादन वर्ग के समान नामस्थान में जाना चाहिए, लेकिन यह कुछ नहीं है PHPUnit आपको करने के लिए मजबूर करता है। मैंने अभी तक कोई कमी नहीं होने के साथ इसे आसान पाया है।

केवल कुछ परीक्षण निष्पादित करना

उदाहरण के लिए phpunit --filter Factory सभी phpunit --filter Factory निष्पादित करता है जबकि phpunit tests/unit/logger/ संबंधित लॉगिंग सब कुछ निष्पादित करता है।

आप अंक समूह, कहानियों या कुछ जैसे कुछ के लिए @group टैग का उपयोग कर सकते हैं लेकिन "मॉड्यूल" के लिए मैं फ़ोल्डर लेआउट का उपयोग करूंगा।

एकाधिक एक्सएमएल फाइलें

यदि आप चाहते हैं तो एकाधिक एक्सएमएल फाइलें बनाने के लिए यह उपयोगी हो सकता है:

  • कोड कवरेज के बिना एक
  • केवल यूनिट परीक्षणों के लिए (लेकिन कार्यात्मक या एकीकरण या लंबे समय तक चलने वाले परीक्षणों के लिए नहीं)
  • अन्य आम "फ़िल्टर" मामले
  • उदाहरण के लिए their phpunit.xmls लिए करता है

आपके परीक्षणों के लिए कोड कवरेज

चूंकि यह परीक्षण के साथ एक नई परियोजना शुरू करने से संबंधित है:

  • मेरा सुझाव है कि मेरे ब्लॉग में वर्णित @covers टैग का उपयोग @covers (केवल यूनिट परीक्षणों के लिए, हमेशा सभी गैर सार्वजनिक कार्यों को कवर करें, हमेशा कवर टैग का उपयोग करें।
  • अपने एकीकरण परीक्षण के लिए कवरेज उत्पन्न न करें। यह आपको सुरक्षा की झूठी भावना देता है।
  • अपने सभी उत्पादन कोड को शामिल करने के लिए हमेशा श्वेतसूची का उपयोग करें ताकि संख्याएं आपसे झूठ न बोलें!

अपने परीक्षणों को स्वत: लोड करना और बूटस्ट्रैप करना

आपको अपने परीक्षणों के लिए किसी भी प्रकार की ऑटो लोडिंग की आवश्यकता नहीं है। PHPUnit इसका ख्याल रखेगा।

अपने परीक्षण बूटस्ट्रैप को निर्दिष्ट करने के लिए <phpunit bootstrap="file"> विशेषता का प्रयोग करें। tests/bootstrap.php इसे रखने के लिए एक अच्छी जगह है। वहां आप अपने एप्लिकेशन ऑटोलोडर सेट कर सकते हैं और इसी तरह (या उस मामले के लिए अपने एप्लिकेशन बूटस्ट्रैप को कॉल करें)।

सारांश

  • बहुत अधिक सब कुछ के लिए एक्सएमएल विन्यास का प्रयोग करें
  • अलग इकाई और एकीकरण परीक्षण
  • आपके यूनिट परीक्षण फ़ोल्डरों को आपके अनुप्रयोग फ़ोल्डर संरचना को दर्पण करना चाहिए
  • केवल विशिष्ट परीक्षण निष्पादित करने के लिए phpunit --filter या phpunit tests/unit/module1
  • जाओ जाने से strict मोड का उपयोग करें और इसे कभी भी बंद न करें।

देखने के लिए नमूना परियोजनाओं

मैं वर्तमान में एक परियोजना के लिए phpunit परीक्षणों के साथ खरोंच से शुरू करने जा रहा हूँ। तो मैं कुछ परियोजनाओं (जैसे ज़ेंड) देख रहा था यह देखने के लिए कि वे चीजें कैसे कर रहे हैं और वे अपने परीक्षण कैसे व्यवस्थित कर रहे हैं।

ज्यादातर चीजें बहुत स्पष्ट हैं, केवल एक चीज है जिसमें मुझे कुछ समस्याएं हैं, परीक्षण सूट को व्यवस्थित तरीके से व्यवस्थित करना है। ज़ेंड में एक AllTests.php है जिसमें से अन्य परीक्षण सूट लोड करता है।
क्लास को देखकर यह एक सूट ऑब्जेक्ट बनाने के लिए PHPUnit_Framework_TestSuite का उपयोग कर रहा है और उसके बाद अन्य सूट जोड़ता है, लेकिन यदि मैं 3.4 के बाद PHPUnit संस्करणों में परीक्षण आयोजित करने के लिए PHPUnit दस्तावेज़ों में देखता हूं तो XML या FileHierarchy के लिए केवल एक विवरण है। परीक्षणों को व्यवस्थित करने के लिए कक्षाओं का उपयोग करने वाला एक हटा दिया गया था।
मुझे कुछ भी नहीं मिला है कि इस विधि को बहिष्कृत किया गया है और ज़ेंड जैसी परियोजनाएं अभी भी इसका उपयोग कर रही हैं।

लेकिन अगर इसे बहिष्कृत किया गया है, तो मैं एक्सएमएल कॉन्फ़िगरेशन के साथ उसी संरचना में परीक्षण कैसे व्यवस्थित कर पाऊंगा? सभी परीक्षणों को निष्पादित करना कोई समस्या नहीं है, लेकिन अगर मैं केवल कुछ परीक्षण निष्पादित करना चाहता हूं तो मैं परीक्षण (एक्सएमएल में) कैसे व्यवस्थित करूं। हो सकता है कि कई एक्सएमएल बनायें जहां मैं केवल कुछ परीक्षण / परीक्षण सूट चलाने के लिए निर्दिष्ट करता हूं?

तो अगर मैं केवल आवेदन के मॉड्यूल 1 और मॉड्यूल 2 का परीक्षण करना चाहता हूं, तो क्या मेरे पास प्रत्येक के लिए अतिरिक्त एक्सएमएल होगा और इसमें मॉड्यूल द्वारा उपयोग की जाने वाली कक्षाओं (मॉड्यूल द्वारा उपयोग की जाने वाली कक्षाओं) के लिए परीक्षण सूट को परिभाषित करना होगा। और यह भी कि सभी परीक्षणों के लिए एक परीक्षण सूट परिभाषित करता है?

या मॉड्यूल 1 या मॉड्यूल 2 के लिए चिह्नित करने के लिए विशिष्ट परीक्षणों पर @group एनोटेशन का उपयोग करना बेहतर होगा?

मुझे कुछ बेहतरीन प्रथाओं को इंगित करने के लिए अग्रिम धन्यवाद।


मूल निर्देशिका संरचना :

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

इसका एक बड़ा फायदा यह है कि इसका मतलब है कि अन्य कर्मचारी (आप नहीं क्योंकि आप कभी ऐसा नहीं करेंगे) परीक्षण कोड लिखने से बचने की संभावना कम होगी क्योंकि यह बहुत अधिक काम है। यहां तक ​​कि जब वे मौजूदा कक्षाओं में विधियों को जोड़ते हैं, तो वे मौजूदा टेस्ट कोड में परीक्षण जोड़ने की तरह महसूस नहीं करेंगे।

एक नुकसान यह है कि इसके उत्पादन के बिना आपके उत्पादन कोड को जारी करना मुश्किल हो जाता है। यद्यपि आप सख्त नामकरण सम्मेलनों का उपयोग करते हैं, फिर भी यह संभव हो सकता है। उदाहरण के लिए, मैं ClassName.php, ClassNameUnitTest.php, और ClassNameIntegrationTest.php का उपयोग कर रहा हूं। जब मैं सभी यूनिट परीक्षणों को चलाने के लिए चाहता हूं, तो एक सूट है जो UnitTest.php में समाप्त होने वाली फ़ाइलों को ढूंढता है। एकीकरण परीक्षण सूट इसी प्रकार काम करता है। अगर मैं चाहता था, तो परीक्षणों को उत्पादन में जारी होने से रोकने के लिए मैं एक समान तकनीक का उपयोग कर सकता हूं।

इस दृष्टिकोण का एक और नुकसान यह है कि जब आप केवल वास्तविक कोड की तलाश में हैं, परीक्षण कोड नहीं, तो दोनों के बीच अंतर करने के लिए थोड़ा और प्रयास किया जाता है।

प्रति वर्ग एक टेस्ट क्लास:

यह अधिकांश प्रोग्रामर के लिए प्रयोगात्मक से बहुत दूर है, लेकिन यह मेरे लिए है। मैं केवल एक टेस्ट क्लास प्रति कक्षा परीक्षण के साथ प्रयोग कर रहा हूं। अतीत में मेरे पास प्रत्येक वर्ग का परीक्षण करने के लिए एक संपूर्ण निर्देशिका थी और उसके बाद उस निर्देशिका के अंदर कई कक्षाएं थीं। प्रत्येक टेस्ट क्लास कक्षा को एक निश्चित तरीके से परीक्षण किया जाता है, और फिर अलग-अलग दावे के साथ प्रत्येक तरीके का एक समूह था। लेकिन फिर मैंने कुछ स्थितियों को ध्यान में रखना शुरू कर दिया, मैं इन वस्तुओं को अन्य परीक्षण कक्षाओं से प्राप्त अन्य स्थितियों के साथ सामान में सामान्य रूप से प्राप्त कर दूंगा। डुप्लिकेशंस को संभालने के लिए बहुत अधिक हो गया है, इसलिए मैंने इसे दूरस्थ करने के लिए abstractions बनाना शुरू कर दिया। परीक्षण कोड को समझना और बनाए रखना बहुत मुश्किल हो गया। मुझे यह एहसास हुआ, लेकिन मुझे एक विकल्प नहीं मिला जो मुझे समझ में आया। बस प्रति वर्ग एक टेस्ट क्लास लग रहा था जैसे यह एक टेस्ट क्लास के अंदर सभी टेस्ट कोड रखने के लिए जबरदस्त होने के बिना लगभग पर्याप्त परिस्थितियों का परीक्षण करने में सक्षम नहीं होगा। अब मेरे पास एक अलग परिप्रेक्ष्य है। यहां तक ​​कि अगर मैं सही था, तो यह अन्य प्रोग्रामर पर एक बड़ा धुंधला है, और खुद, परीक्षण लिखना और बनाए रखना चाहते हैं। अब मैं परीक्षण कर रहा हूं कि प्रति वर्ग एक टेस्ट क्लास का परीक्षण किया जा रहा है। यदि मैं उस टेस्ट क्लास में परीक्षण करने के लिए बहुत सी चीजों में भाग लेता हूं, तो मैं इसे एक संकेत के रूप में देखकर प्रयोग कर रहा हूं कि परीक्षण की जा रही कक्षा बहुत अधिक कर रही है, और इसे कई वर्गों में विभाजित किया जाना चाहिए। डुप्लिकेशंस को हटाने के लिए मैं जितना संभव हो सके सरल अबास्ट्रक्शंस से चिपकने की कोशिश कर रहा हूं जो सब कुछ एक पठनीय टेस्ट क्लास में मौजूद होने की अनुमति देता है।







phpunit