آج آپ کو کوئی ایسی ایپلیکیشن نہیں ملے گی جو ٹیسٹوں کے ساتھ نہ لگائی گئی ہو، اس لیے یہ موضوع نئے ڈویلپرز کے لیے پہلے سے کہیں زیادہ متعلقہ ہو گا: آپ ٹیسٹ کے بغیر کامیاب نہیں ہو سکتے۔ آئیے اس بات پر غور کریں کہ اصولی طور پر کس قسم کی جانچ استعمال کی جاتی ہے، اور پھر ہم یونٹ ٹیسٹنگ کے بارے میں جاننے کے لیے ہر چیز کا تفصیل سے مطالعہ کریں گے۔ یونٹ ٹیسٹنگ کے بارے میں سب کچھ: تکنیک، تصورات، مشق - 1

جانچ کی اقسام

ٹیسٹ کیا ہے؟ ویکیپیڈیا کے مطابق: "سافٹ ویئر ٹیسٹنگ میں دلچسپی کی ایک یا زیادہ خصوصیات کا جائزہ لینے کے لیے سافٹ ویئر کے جزو یا سسٹم کے جزو کو انجام دینا شامل ہے۔" دوسرے لفظوں میں، یہ بعض حالات میں ہمارے نظام کی درستگی کی جانچ ہے۔ ٹھیک ہے، آئیے دیکھتے ہیں کہ عام طور پر جانچ کی کیا اقسام ہیں:
  • یونٹ ٹیسٹنگ - ٹیسٹ جن کا مقصد سسٹم کے ہر ماڈیول کو الگ سے چیک کرنا ہے۔ یہ ٹیسٹ سسٹم کے سب سے چھوٹے ایٹمی حصوں پر لاگو ہونے چاہئیں، جیسے کہ ماڈیولز۔
  • سسٹم ٹیسٹنگ - ایپلی کیشن کے کسی بڑے حصے یا مجموعی طور پر سسٹم کے آپریشن کو چیک کرنے کے لیے اعلیٰ سطح کی جانچ۔
  • ریگریشن ٹیسٹنگ - ٹیسٹنگ جس کا استعمال یہ جانچنے کے لیے کیا جاتا ہے کہ آیا نئی خصوصیات یا بگ فکسز ایپلی کیشن کی موجودہ فعالیت کو متاثر کرتے ہیں یا پرانے کیڑے متعارف کراتے ہیں۔
  • فنکشنل ٹیسٹنگ - یہ جانچنا کہ آیا ایپلیکیشن کا کوئی حصہ تصریحات، صارف کی کہانیوں وغیرہ میں بیان کردہ ضروریات کو پورا کرتا ہے۔

    فنکشنل ٹیسٹنگ کی اقسام:

    • وائٹ باکس ٹیسٹنگ - یہ جانچنا کہ آیا ایپلیکیشن کا کوئی حصہ سسٹم کے اندرونی نفاذ کو جانتے ہوئے ضروریات کو پورا کرتا ہے۔
    • بلیک باکس ٹیسٹنگ - جانچنا کہ آیا ایپلیکیشن کا کوئی حصہ سسٹم کے اندرونی نفاذ کو جانے بغیر ضروریات کو پورا کرتا ہے۔

  • کارکردگی کی جانچ - وہ ٹیسٹ جو اس بات کا تعین کرنے کے لیے لکھے جاتے ہیں کہ سسٹم یا سسٹم کا حصہ کسی خاص بوجھ کے تحت کس طرح کارکردگی کا مظاہرہ کرتا ہے۔
  • لوڈ ٹیسٹنگ — معیاری بوجھ کے تحت سسٹم کے استحکام کو جانچنے اور زیادہ سے زیادہ بوجھ تلاش کرنے کے لیے ڈیزائن کیے گئے ٹیسٹ جس پر ایپلیکیشن اب بھی صحیح طریقے سے کام کرتی ہے۔
  • تناؤ کی جانچ — غیر معیاری بوجھ کے تحت ایپلی کیشن کی کارکردگی کو جانچنے اور سسٹم کی ناکامی سے پہلے زیادہ سے زیادہ بوجھ کا تعین کرنے کے لیے ڈیزائن کی گئی جانچ۔
  • سیکیورٹی ٹیسٹنگ - سسٹم کی سیکیورٹی کو چیک کرنے کے لیے استعمال کیے جانے والے ٹیسٹ (ہیکرز، وائرس، خفیہ ڈیٹا تک غیر مجاز رسائی، اور دیگر خوشگوار حملوں سے)۔
  • لوکلائزیشن ٹیسٹنگ - ایپلیکیشن کے لوکلائزیشن کے ٹیسٹ۔
  • استعمال کی جانچ - جانچ کا مقصد استعمال کی اہلیت، قابل فہمی، کشش اور سیکھنے کی اہلیت کو جانچنا ہے۔
یہ سب اچھا لگتا ہے، لیکن عملی طور پر یہ کیسے کام کرتا ہے؟ سادہ! ہم مائیک کوہن کا ٹیسٹنگ اہرام استعمال کرتے ہیں: یونٹ ٹیسٹنگ کے بارے میں سب کچھ: تکنیک، تصورات، مشق - 2یہ اہرام کا ایک آسان ورژن ہے: اب اسے چھوٹے حصوں میں تقسیم کیا گیا ہے۔ لیکن آج ہم زیادہ نفیس نہیں ہوں گے۔ ہم سب سے آسان ورژن پر غور کریں گے۔
  1. یونٹ — اس حصے سے مراد یونٹ ٹیسٹ ہیں، جو ایپلی کیشن کی مختلف پرتوں میں لاگو ہوتے ہیں۔ وہ اطلاقی منطق کی سب سے چھوٹی تقسیم شدہ اکائی کی جانچ کرتے ہیں۔ مثال کے طور پر، کلاسز، لیکن اکثر طریقے۔ یہ ٹیسٹ عام طور پر زیادہ سے زیادہ کوشش کرتے ہیں کہ کسی بھی بیرونی منطق سے جانچ کی گئی چیز کو الگ تھلگ کیا جائے۔ یعنی یہ وہم پیدا کرنے کی کوشش کرتے ہیں کہ بقیہ ایپلی کیشن حسب توقع چل رہی ہے۔

    ان میں سے بہت سارے ٹیسٹ ہمیشہ ہونے چاہئیں (کسی بھی دوسری قسم سے زیادہ)، کیونکہ وہ چھوٹے ٹکڑوں کی جانچ کرتے ہیں اور بہت ہلکے ہوتے ہیں، بہت زیادہ وسائل استعمال نہیں کرتے (یعنی رام اور وقت)۔

  2. انٹیگریشن - یہ سیکشن انضمام کی جانچ سے مراد ہے۔ یہ جانچ سسٹم کے بڑے ٹکڑوں کو چیک کرتی ہے۔ یعنی، یہ یا تو منطق کے کئی ٹکڑوں (متعدد طریقے یا کلاسز) کو یکجا کرتا ہے، یا یہ کسی بیرونی جزو کے ساتھ تعامل کی درستگی کو چیک کرتا ہے۔ یہ ٹیسٹ عام طور پر یونٹ ٹیسٹ سے چھوٹے ہوتے ہیں کیونکہ یہ بھاری ہوتے ہیں۔

    انٹیگریشن ٹیسٹ کی ایک مثال ڈیٹا بیس سے منسلک ہونا اور اس کے ساتھ کام کرنے کے طریقوں کے آپریشن کی درستگی کی جانچ کرنا ہو سکتی ہے۔

  3. UI - اس حصے سے مراد ایسے ٹیسٹ ہیں جو یوزر انٹرفیس کے آپریشن کو چیک کرتے ہیں۔ وہ اطلاق کی تمام سطحوں پر منطق کو شامل کرتے ہیں، اسی لیے انہیں آخر سے آخر تک ٹیسٹ بھی کہا جاتا ہے۔ ایک اصول کے طور پر، ان میں سے بہت کم ہیں، کیونکہ وہ سب سے زیادہ بوجھل ہیں اور سب سے زیادہ ضروری (استعمال شدہ) راستوں کو چیک کرنا ضروری ہے۔

    اوپر کی تصویر میں، ہم دیکھتے ہیں کہ مثلث کے مختلف حصے سائز میں مختلف ہوتے ہیں: حقیقی کام میں مختلف قسم کے ٹیسٹوں کی تعداد میں تقریباً ایک ہی تناسب موجود ہے۔

    آج ہم سب سے زیادہ عام ٹیسٹوں، یونٹ ٹیسٹوں پر گہری نظر ڈالیں گے، کیونکہ جاوا کے تمام ڈیولپرز کو انہیں بنیادی سطح پر استعمال کرنے کے قابل ہونا چاہیے۔

یونٹ ٹیسٹنگ میں کلیدی تصورات

ٹیسٹ کوریج (کوڈ کوریج) اس بات کے اہم اقدامات میں سے ایک ہے کہ کسی درخواست کی جانچ کتنی اچھی طرح سے کی جاتی ہے۔ یہ اس کوڈ کا فیصد ہے جو ٹیسٹ (0-100%) کے ذریعے احاطہ کرتا ہے۔ عملی طور پر، بہت سے لوگ اس فیصد کو اپنے مقصد کے طور پر حاصل کر رہے ہیں۔ یہ وہ چیز ہے جس سے میں متفق نہیں ہوں، کیوں کہ اس کا مطلب ہے کہ جہاں ان کی ضرورت نہیں ہے وہاں ٹیسٹ لگائے جانے لگتے ہیں۔ مثال کے طور پر، فرض کریں کہ ہماری سروس میں بغیر کسی اضافی منطق کے معیاری CRUD (create/get/update/delete) آپریشنز ہیں۔ یہ طریقے خالصتاً بیچوان ہیں جو ریپوزٹری کے ساتھ کام کرنے والی پرت کو کام سونپتے ہیں۔ اس صورت حال میں، ہمارے پاس جانچنے کے لیے کچھ نہیں ہے، سوائے اس کے کہ آیا دیا گیا طریقہ DAO طریقہ کہتا ہے، لیکن یہ ایک مذاق ہے۔ اضافی ٹولز عام طور پر ٹیسٹ کوریج کا اندازہ لگانے کے لیے استعمال کیے جاتے ہیں: JaCoCo، Cobertura، Clover، Emma، وغیرہ۔ اس موضوع کے مزید تفصیلی مطالعہ کے لیے، یہاں چند متعلقہ مضامین ہیں: TDD کا مطلب ہے ٹیسٹ پر مبنی ترقی۔ اس نقطہ نظر میں، کچھ اور کرنے سے پہلے، آپ ایک ٹیسٹ لکھتے ہیں جو مخصوص کوڈ کو چیک کرے گا۔ یہ بلیک باکس ٹیسٹنگ نکلا: ہم جانتے ہیں کہ ان پٹ ہے اور ہم جانتے ہیں کہ آؤٹ پٹ کیا ہونا چاہیے۔ یہ کوڈ کی نقل سے بچنا ممکن بناتا ہے۔ ٹیسٹ سے چلنے والی ترقی آپ کی ایپلی کیشن میں ہر ایک فنکشنلٹی کے لیے ٹیسٹ ڈیزائن کرنے اور تیار کرنے کے ساتھ شروع ہوتی ہے۔ TDD نقطہ نظر میں، ہم سب سے پہلے ایک ٹیسٹ بناتے ہیں جو کوڈ کے رویے کی وضاحت اور جانچ کرتا ہے۔ TDD کا بنیادی مقصد آپ کے کوڈ کو زیادہ قابل فہم، آسان اور غلطی سے پاک بنانا ہے۔ یونٹ ٹیسٹنگ کے بارے میں سب کچھ: تکنیک، تصورات، مشق - 3نقطہ نظر مندرجہ ذیل پر مشتمل ہے:
  • ہم اپنا ٹیسٹ لکھتے ہیں۔
  • ہم ٹیسٹ چلاتے ہیں۔ حیرت انگیز طور پر، یہ ناکام ہوجاتا ہے، کیونکہ ہم نے ابھی تک مطلوبہ منطق کو نافذ نہیں کیا ہے۔
  • وہ کوڈ شامل کریں جو ٹیسٹ پاس کرنے کا سبب بنتا ہے (ہم دوبارہ ٹیسٹ چلاتے ہیں)۔
  • ہم کوڈ کو ری ایکٹر کرتے ہیں۔
TDD یونٹ ٹیسٹ پر مبنی ہے، کیونکہ یہ ٹیسٹ آٹومیشن اہرام میں سب سے چھوٹے بلڈنگ بلاکس ہیں۔ یونٹ ٹیسٹ کے ساتھ، ہم کسی بھی کلاس کی کاروباری منطق کو جانچ سکتے ہیں۔ بی ڈی ڈی کا مطلب ہے رویے سے چلنے والی ترقی۔ یہ نقطہ نظر TDD پر مبنی ہے۔ مزید خاص طور پر، یہ سادہ زبان کی مثالوں کا استعمال کرتا ہے جو ترقی میں شامل ہر فرد کے لیے نظام کے رویے کی وضاحت کرتی ہے۔ ہم اس اصطلاح میں غور نہیں کریں گے، کیونکہ یہ بنیادی طور پر ٹیسٹرز اور کاروباری تجزیہ کاروں کو متاثر کرتا ہے۔ ٹیسٹ کیس ایک ایسا منظر نامہ ہے جو ٹیسٹ کے تحت کوڈ کو چیک کرنے کے لیے درکار اقدامات، مخصوص شرائط اور پیرامیٹرز کو بیان کرتا ہے۔ ٹیسٹ فکسچر ایک کوڈ ہوتا ہے جو ٹیسٹ کے ماحول کو ترتیب دیتا ہے تاکہ ٹیسٹ کے تحت طریقہ کار کو کامیابی سے چلانے کے لیے ضروری حالت حاصل ہو۔ یہ اشیاء کا پہلے سے طے شدہ سیٹ ہے اور مخصوص حالات کے تحت ان کا برتاؤ۔

جانچ کے مراحل

ٹیسٹ تین مراحل پر مشتمل ہے:
  • ٹیسٹ ڈیٹا (فکسچر) کی وضاحت کریں۔
  • ٹیسٹ کے تحت کوڈ کی مشق کریں (ٹیسٹ شدہ طریقہ کو کال کریں)۔
  • نتائج کی تصدیق کریں اور متوقع نتائج کے ساتھ موازنہ کریں۔
یونٹ ٹیسٹنگ کے بارے میں سب کچھ: تکنیک، تصورات، مشق - 4ٹیسٹ ماڈیولریٹی کو یقینی بنانے کے لیے، آپ کو ایپلیکیشن کی دوسری تہوں سے الگ تھلگ کرنے کی ضرورت ہے۔ یہ stubs، mocks، اور جاسوسوں کا استعمال کرتے ہوئے کیا جا سکتا ہے. موکس ایسی چیزیں ہیں جنہیں اپنی مرضی کے مطابق بنایا جا سکتا ہے (مثال کے طور پر، ہر ٹیسٹ کے لیے تیار کردہ)۔ وہ ہمیں بتاتے ہیں کہ ہم میتھڈ کالز سے کیا توقع کرتے ہیں، یعنی متوقع جوابات۔ ہم فرضی اشیاء کا استعمال اس بات کی تصدیق کے لیے کرتے ہیں کہ ہمیں وہی ملتا ہے جس کی ہم توقع کرتے ہیں۔ سٹبس جانچ کے دوران کالوں کا سخت کوڈڈ جواب فراہم کرتے ہیں۔ وہ کال کے بارے میں معلومات بھی محفوظ کر سکتے ہیں (مثال کے طور پر، پیرامیٹرز یا کالز کی تعداد)۔ انہیں بعض اوقات جاسوس بھی کہا جاتا ہے۔ بعض اوقات لوگ سٹب اور مزاق کی اصطلاحات کو الجھاتے ہیں: فرق یہ ہے کہ سٹب کسی چیز کی جانچ نہیں کرتا ہے - یہ صرف ایک دی گئی حالت کی نقل کرتا ہے۔ ایک طنز ایک ایسی چیز ہے جس سے توقعات وابستہ ہوتی ہیں۔ مثال کے طور پر، یہ کہ ایک دیئے گئے طریقہ کو ایک مخصوص تعداد میں کہا جانا چاہیے۔ دوسرے لفظوں میں، آپ کا امتحان کبھی بھی سٹب کی وجہ سے نہیں ٹوٹے گا، لیکن یہ ایک مذاق کی وجہ سے ہو سکتا ہے۔

ٹیسٹ کے ماحول

تو، اب نقطہ پر. جاوا کے لیے کئی ٹیسٹ ماحول (فریم ورک) دستیاب ہیں۔ ان میں سب سے زیادہ مقبول JUnit اور TestNG ہیں۔ یہاں ہمارے جائزے کے لیے، ہم استعمال کرتے ہیں: یونٹ ٹیسٹنگ کے بارے میں سب کچھ: تکنیک، تصورات، مشق - 5JUnit ٹیسٹ کلاس میں ایک طریقہ ہے جو صرف جانچ کے لیے استعمال ہوتا ہے۔ کلاس کا نام عام طور پر وہی رکھا جاتا ہے جس کلاس کا یہ ٹیسٹ کرتا ہے، آخر میں "ٹیسٹ" کو جوڑا جاتا ہے۔ مثال کے طور پر، CarService -> CarServiceTest۔ ماون بلڈ سسٹم خود بخود ٹیسٹ کے دائرہ کار میں ایسی کلاسوں کو شامل کرتا ہے۔ درحقیقت اس کلاس کو ٹیسٹ کلاس کہا جاتا ہے۔ آئیے مختصراً بنیادی تشریحات کو دیکھتے ہیں:

  • @Test اشارہ کرتا ہے کہ طریقہ ایک ٹیسٹ ہے (بنیادی طور پر، اس تشریح کے ساتھ نشان زد کردہ طریقہ ایک یونٹ ٹیسٹ ہے)۔
  • @Before ایک طریقہ کی نشاندہی کرتا ہے جو ہر ٹیسٹ سے پہلے عمل میں لایا جائے گا۔ مثال کے طور پر، ٹیسٹ ڈیٹا کے ساتھ کلاس کو آباد کرنے کے لیے، ان پٹ ڈیٹا کو پڑھیں، وغیرہ۔
  • @After کا استعمال ایک طریقہ کو نشان زد کرنے کے لیے کیا جاتا ہے جسے ہر ٹیسٹ کے بعد بلایا جائے گا (مثال کے طور پر ڈیٹا کو صاف کرنے یا پہلے سے طے شدہ اقدار کو بحال کرنے کے لیے)۔
  • @BeforeClass کو ایک طریقہ کے اوپر رکھا گیا ہے، جو @Before کے مشابہ ہے۔ لیکن اس طرح کے طریقہ کو دی گئی کلاس کے تمام ٹیسٹوں سے پہلے صرف ایک بار کہا جاتا ہے اور اس لیے اسے جامد ہونا چاہیے۔ اس کا استعمال زیادہ وسائل سے متعلق کام کرنے کے لیے کیا جاتا ہے، جیسے کہ ٹیسٹ ڈیٹا بیس کو گھماؤ۔
  • @AfterClass @BeforeClass کے برعکس ہے: اسے دی گئی کلاس کے لیے ایک بار عمل میں لایا جاتا ہے، لیکن صرف تمام ٹیسٹوں کے بعد۔ یہ استعمال کیا جاتا ہے، مثال کے طور پر، مستقل وسائل کو صاف کرنے یا ڈیٹا بیس سے منقطع کرنے کے لیے۔
  • @Ignore اس بات کی نشاندہی کرتا ہے کہ ایک طریقہ غیر فعال ہے اور مجموعی ٹیسٹ رن کے دوران اسے نظر انداز کر دیا جائے گا۔ یہ مختلف حالات میں استعمال ہوتا ہے، مثال کے طور پر، اگر بنیادی طریقہ کو تبدیل کر دیا گیا ہے اور تبدیلیوں کو ایڈجسٹ کرنے کے لیے ٹیسٹ کو ابھی تک دوبارہ نہیں بنایا گیا ہے۔ ایسی صورتوں میں، تفصیل شامل کرنا بھی ضروری ہے، یعنی @Ignore("Some description")۔
  • @Test(expected = Exception.class) منفی ٹیسٹ کے لیے استعمال کیا جاتا ہے۔ یہ وہ ٹیسٹ ہیں جو اس بات کی تصدیق کرتے ہیں کہ غلطی کی صورت میں طریقہ کار کس طرح برتاؤ کرتا ہے، یعنی ٹیسٹ سے توقع ہوتی ہے کہ طریقہ کسی قسم کی رعایت کرے گا۔ اس طرح کے طریقہ کی نشاندہی @Test تشریح سے ہوتی ہے، لیکن اس بات کے اشارے کے ساتھ کہ کس غلطی کو پکڑنا ہے۔
  • @Test(ٹائم آؤٹ = 100) چیک کرتا ہے کہ طریقہ کار 100 ملی سیکنڈ سے زیادہ میں نہیں ہوتا ہے۔
  • @Mock ایک فیلڈ کے اوپر ایک فرضی آبجیکٹ تفویض کرنے کے لیے استعمال کیا جاتا ہے (یہ JUnit تشریح نہیں ہے، بلکہ اس کے بجائے Mockito سے آتا ہے)۔ ضرورت کے مطابق، ہم کسی مخصوص صورت حال کے لیے فرضی رویے کو براہ راست ٹیسٹ کے طریقہ کار میں سیٹ کرتے ہیں۔
  • @RunWith(MockitoJUnitRunner.class) کو کلاس کے اوپر رکھا گیا ہے۔ یہ تشریح JUnit کو کلاس میں ٹیسٹ لینے کے لیے کہتی ہے۔ مختلف رنرز ہیں، جن میں یہ شامل ہیں: MockitoJUnitRunner، JUnitPlatform، اور SpringRunner۔ JUnit 5 میں، @RunWith تشریح کو زیادہ طاقتور @ExtendWith تشریح سے بدل دیا گیا ہے۔
آئیے نتائج کا موازنہ کرنے کے لیے استعمال ہونے والے کچھ طریقوں پر ایک نظر ڈالیں:

  • assertEquals(Object expects, Object actuals) — چیک کرتا ہے کہ پاس شدہ اشیاء برابر ہیں یا نہیں۔
  • assertTrue(بولین فلیگ) - چیک کرتا ہے کہ آیا پاس کردہ قدر درست ہے۔
  • assertFalse(بولین فلیگ) - چیک کرتا ہے کہ آیا پاس کردہ قدر غلط ہے۔
  • assertNull(آبجیکٹ آبجیکٹ) - چیک کرتا ہے کہ آیا پاس شدہ آبجیکٹ کالعدم ہے۔
  • assertSame(Object firstObject، Object secondObject) - چیک کرتا ہے کہ آیا پاس شدہ اقدار ایک ہی چیز کا حوالہ دیتے ہیں۔
  • assertThat(T t، matcher میچر) - چیک کرتا ہے کہ آیا t میچر میں بیان کردہ شرط کو پورا کرتا ہے۔
AssertJ ایک مفید موازنہ کا طریقہ بھی فراہم کرتا ہے: assertThat(firstObject).isEqualTo(secondObject) ۔ یہاں میں نے بنیادی طریقوں کا ذکر کیا ہے - باقی مندرجہ بالا کی مختلف حالتیں ہیں۔

عملی طور پر جانچ

اب ایک مخصوص مثال میں مندرجہ بالا مواد کو دیکھتے ہیں۔ ہم سروس کے اپ ڈیٹ کے طریقے کی جانچ کریں گے۔ ہم ڈی اے او پرت پر غور نہیں کریں گے، کیونکہ ہم ڈیفالٹ استعمال کر رہے ہیں۔ آئیے ٹیسٹ کے لیے ایک اسٹارٹر شامل کریں:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
   <version>2.2.2.RELEASE</version>
   <scope>test</scope>
</dependency>
اور یہاں ہمارے پاس سروس کلاس ہے:

@Service
@RequiredArgsConstructor
public class RobotServiceImpl implements RobotService {
   private final RobotDAO robotDAO;

   @Override
   public Robot update(Long id, Robot robot) {
       Robot found = robotDAO.findById(id);
       return robotDAO.update(Robot.builder()
               .id(id)
               .name(robot.getName() != null ? robot.getName() : found.getName())
               .cpu(robot.getCpu() != null ? robot.getCpu() : found.getCpu())
               .producer(robot.getProducer() != null ? robot.getProducer() : found.getProducer())
               .build());
   }
}
لائن 8 - ڈیٹا بیس سے اپ ڈیٹ شدہ آبجیکٹ کو کھینچیں۔ لائنز 9-14 — بلڈر کے ذریعے ایک آبجیکٹ بنائیں۔ اگر آنے والی آبجیکٹ میں فیلڈ ہے تو اسے سیٹ کریں۔ اگر نہیں، تو ہم اسے چھوڑ دیں گے جو ڈیٹا بیس میں ہے۔ اب ہمارا امتحان دیکھیں:

@RunWith(MockitoJUnitRunner.class)
public class RobotServiceImplTest {
   @Mock
   private RobotDAO robotDAO;

   private RobotServiceImpl robotService;

   private static Robot testRobot;

   @BeforeClass
   public static void prepareTestData() {
       testRobot = Robot
               .builder()
               .id(123L)
               .name("testRobotMolly")
               .cpu("Intel Core i7-9700K")
               .producer("China")
               .build();
   }

   @Before
   public void init() {
       robotService = new RobotServiceImpl(robotDAO);
   }
لائن 1 - ہمارا رنر۔ لائن 4 — ہم ایک فرضی جگہ دے کر سروس کو DAO پرت سے الگ کر دیتے ہیں۔ لائن 11 — ہم کلاس کے لیے ایک ٹیسٹ ہستی (جسے ہم گنی پگ کے طور پر استعمال کریں گے) سیٹ کرتے ہیں۔ لائن 22 - ہم سروس آبجیکٹ سیٹ کرتے ہیں، جس کی ہم جانچ کریں گے۔

@Test
public void updateTest() {
   when(robotDAO.findById(any(Long.class))).thenReturn(testRobot);
   when(robotDAO.update(any(Robot.class))).then(returnsFirstArg());
   Robot robotForUpdate = Robot
           .builder()
           .name("Vally")
           .cpu("AMD Ryzen 7 2700X")
           .build();

   Robot resultRobot = robotService.update(123L, robotForUpdate);

   assertNotNull(resultRobot);
   assertSame(resultRobot.getId(),testRobot.getId());
   assertThat(resultRobot.getName()).isEqualTo(robotForUpdate.getName());
   assertTrue(resultRobot.getCpu().equals(robotForUpdate.getCpu()));
   assertEquals(resultRobot.getProducer(),testRobot.getProducer());
}
یہاں ہم دیکھتے ہیں کہ ٹیسٹ میں تین واضح تقسیم ہیں: لائنز 3-9 — مخصوص فکسچر۔ لائن 11 - ٹیسٹ کے تحت کوڈ پر عمل درآمد۔ لائنز 13-17 - نتائج کی جانچ کرنا۔ مزید تفصیل میں: لائنز 3-4 — DAO کے فرضی سلوک کو متعین کریں۔ لائن 5 - مثال قائم کریں کہ ہم اپنے معیار کے اوپر اپ ڈیٹ کریں گے۔ لائن 11 - طریقہ استعمال کریں اور نتیجے کی مثال لیں۔ لائن 13 - چیک کریں کہ یہ کالعدم نہیں ہے۔ لائن 14 - نتیجہ کی ID اور دیے گئے طریقہ کے دلائل کا موازنہ کریں۔ لائن 15 - چیک کریں کہ آیا نام کو اپ ڈیٹ کیا گیا تھا۔ لائن 16 - CPU نتیجہ دیکھیں۔ لائن 17 - ہم نے مثال میں اس فیلڈ کی وضاحت نہیں کی، لہذا یہ وہی رہنا چاہئے۔ ہم یہاں اس حالت کو چیک کرتے ہیں۔ آئیے اسے چلائیں: یونٹ ٹیسٹنگ کے بارے میں سب کچھ: تکنیک، تصورات، مشق - 6ٹیسٹ سبز ہے! ہم سکون کی سانس لے سکتے ہیں :) خلاصہ یہ کہ جانچ سے کوڈ کا معیار بہتر ہوتا ہے اور ترقی کے عمل کو مزید لچکدار اور قابل اعتماد بناتا ہے۔ تصور کریں کہ سینکڑوں کلاس فائلوں پر مشتمل سافٹ ویئر کو دوبارہ ڈیزائن کرنے میں کتنی محنت درکار ہے۔ جب ہمارے پاس ان تمام کلاسوں کے لیے یونٹ ٹیسٹ لکھے جاتے ہیں، تو ہم اعتماد کے ساتھ ری فیکٹر کر سکتے ہیں۔ اور سب سے اہم بات، یہ ترقی کے دوران آسانی سے کیڑے تلاش کرنے میں ہماری مدد کرتا ہے۔ لڑکوں اور لڑکیوں، آج میرے پاس بس اتنا ہی ہے۔ مجھے ایک پسند کریں، اور ایک تبصرہ چھوڑ دیں :)