CodeGym /جاوا بلاگ /Random-UR /JUnit کے ساتھ جاوا میں یونٹ ٹیسٹنگ
John Squirrels
سطح
San Francisco

JUnit کے ساتھ جاوا میں یونٹ ٹیسٹنگ

گروپ میں شائع ہوا۔

جاوا میں یونٹ ٹیسٹنگ کیا ہے؟

اس سے پہلے کہ ہم جاوا میں JUnit سیکھیں، آئیے مختصراً جائزہ لیتے ہیں کہ یونٹ ٹیسٹنگ کیا ہے اور یہ اتنا مقبول کیوں ہے (اگر آپ یہ چیزیں پہلے سے جانتے ہیں تو 'میں جاوا میں JUnit ٹیسٹ کیسے لکھوں؟' پر جائیں)۔ جاوا میں یونٹ ٹیسٹنگ بڑے پیمانے پر سافٹ ویئر کی ترقی کو بہت زیادہ موثر اور آسان بناتی ہے۔ یہ دونوں افراد کی مدد کر سکتا ہے، اور ٹیمیں ڈیبگنگ سے لاتعداد گھنٹے کاٹ دیتی ہیں اور تعاون کے عمل کو بے حد ہموار کرتی ہیں۔ JUnit - 1 کے ساتھ جاوا میں یونٹ ٹیسٹنگ

https://junit.org/junit4/

یونٹ ٹیسٹنگ کا لازمی خیال یہ ہے: انفرادی خصوصیات کے جوہری ٹیسٹ لکھیں (جسے یونٹ ٹیسٹ کہا جاتا ہے) اور جانچ کے بعد آہستہ آہستہ مزید خصوصیات شامل کریں اور اس بات کو یقینی بنائیں کہ پچھلے والے کام کریں۔ یہ ایک انتہائی سادہ لیکن طاقتور خیال ہے۔ ایک مثال کے طور پر کہ یہ عمل کیسا نظر آتا ہے، تصور کریں کہ آپ ایک ورچوئل سائنسی کیلکولیٹر بنا رہے ہیں۔ +ظاہری ریاضی کے آپریٹرز ( , -, x, ) کے سب سے اوپر %، اس کیلکولیٹر میں اعلی درجے کی خصوصیات ہوں گی جن کے اندر کام کرنے کے لیے دیگر ذیلی خصوصیات کی ضرورت ہوتی ہے۔ ایکسپوننٹ کا حساب لگانے کے لیے، آپ کے کیلکولیٹر کو درست طریقے سے ضرب لگانے کے قابل ہونا چاہیے۔ لہذا اس کیلکولیٹر کو بنانے اور جانچنے کے لیے یونٹ ٹیسٹنگ کا طریقہ یہ ہوگا:
  • ایک اضافی فنکشن لکھیں۔ اسے احتیاط سے آزمائیں، اسے تبدیل کریں، اس وقت تک دہرائیں جب تک یہ کام نہ کرے۔
  • گھٹاؤ، ضرب، تقسیم کے افعال کے لیے بھی ایسا ہی کریں۔
  • ان بیس آپریٹرز کو مزید جدید آپریٹر فنکشنز لکھنے کے لیے استعمال کریں جیسے exponents، پھر ان فنکشنز کو بھی جانچیں۔
یہ اس بات کو یقینی بناتا ہے کہ دیگر چھوٹی ذیلی خصوصیات کو بنانے والی خصوصیات نہ صرف اپنے طور پر صحیح طریقے سے کام کرتی ہیں بلکہ اس میں ناقص ذیلی خصوصیات بھی نہیں ہوتی ہیں۔ مثال کے طور پر، اگر میں ایکسپوننٹ فنکشن کی جانچ کر رہا ہوں اور کچھ غلط ہو رہا ہے، تو میں جانتا ہوں کہ یہ بگ غالباً ضرب کے ذیلی فیچر میں نہیں ہے، کیونکہ ضرب فنکشن پہلے ہی بڑے پیمانے پر جانچا جا چکا ہے۔ یہ کافی حد تک کوڈ کی کل مقدار کو ختم کرتا ہے جس کی مجھے بیک ٹریس کرنے اور بگ کو تلاش کرنے کے لیے معائنہ کرنے کی ضرورت ہے۔ امید ہے کہ، یہ معمولی مثال واضح کرتی ہے کہ یونٹ ٹیسٹنگ کے ارد گرد سوچ کا عمل کس طرح ترتیب دیا گیا ہے۔ لیکن یونٹ ٹیسٹنگ سافٹ ویئر کی ترقی کے باقی عمل کے ساتھ کیسے تعامل کرتی ہے؟ کیا ہوگا اگر آپ کے پاس اس سے بھی زیادہ پیچیدہ خصوصیات ہیں، جن کو ایک ساتھ کام کرنے اور بات چیت کرنے کے قابل ہونے کی ضرورت ہے؟ یونٹ ٹیسٹنگ اس بات کو یقینی بنانے کے لیے ناکافی ہے کہ اس طرح کی پیچیدہ خصوصیات ایک ساتھ ٹھیک طریقے سے کام کر سکتی ہیں۔ درحقیقت، یہ سافٹ ویئر ٹیسٹنگ کے چار درجوں کا صرف پہلا مرحلہ ہے (میں بڑے حروف کا استعمال کرتا ہوں کیونکہ میں صنعت کے معیار یا سافٹ ویئر کی جانچ کے لیے سب سے عام نقطہ نظر کا حوالہ دیتا ہوں)۔ آخری تین مراحل انٹیگریشن ٹیسٹنگ ، سسٹم ٹیسٹنگ ، اور ایکسیپٹنس ٹیسٹنگ ہیں ۔ ان سب کا شاید وہی مطلب ہے جو آپ کے خیال میں وہ کرتے ہیں، لیکن مجھے واضح کرنے دو: انٹیگریشن ٹیسٹنگ وہ ہے جو ہم ان لوگوں کو یقین دلانے کے لیے کریں گے جیسا کہ اوپر ذکر کیا گیا ہے، "پیچیدہ خصوصیات"، ایک دوسرے کے ساتھ مناسب طریقے سے تعامل کرتے ہیں۔ (مثال کے طور پر، اس بات کو یقینی بنانا کہ کیلکولیٹر "3 + 7 * 4 - 2" کو سنبھال سکتا ہے) سسٹم ٹیسٹنگ کسی خاص سسٹم کے مجموعی ڈیزائن کی جانچ کر رہا ہے۔ ایک پروڈکٹ میں اکثر پیچیدہ خصوصیات کے متعدد سسٹم مل کر کام کرتے ہیں، لہذا آپ ان کو سسٹمز میں گروپ کرتے ہیں اور انفرادی طور پر ان کی جانچ کرتے ہیں۔ (مثال کے طور پر اگر آپ گرافنگ کیلکولیٹر بنا رہے تھے، تو آپ سب سے پہلے نمبروں سے نمٹنے کے لیے ریاضی کا 'نظام' بنائیں گے، اس وقت تک ٹیسٹ کریں گے جب تک کہ یہ ارادہ کے مطابق کام نہ کرے، اور پھر آپ گرافنگ 'سسٹم' بنا کر جانچیں گے تاکہ واپسی سے نمٹنے کے لیے یہ ریاضی کے نظام کو ختم کرے گا)۔ قبولیت کی جانچ صارف کی سطح کی جانچ ہے۔ یہ دیکھ رہا ہے کہ آیا تمام سسٹمز مطابقت پذیری میں کام کر سکتے ہیں تاکہ ایک تیار شدہ پروڈکٹ تیار ہو جس کو صارفین قبول کر سکیں (مثال کے طور پر، صارفین کیلکولیٹر کی جانچ کر رہے ہیں)۔ سافٹ ویئر ڈویلپر بعض اوقات عمل کے اس آخری مرحلے کو نظر انداز کر سکتے ہیں، کیونکہ کمپنیاں اکثر دوسرے ملازمین کو صارف (بی ٹا) ٹیسٹ الگ سے تعینات کرتی ہیں۔

میں جاوا میں JUnit ٹیسٹ کیسے لکھ سکتا ہوں؟

اب جبکہ آپ کو یونٹ ٹیسٹنگ کے فوائد اور حدود کا واضح اندازہ ہے، آئیے کچھ کوڈ پر ایک نظر ڈالتے ہیں! ہم ایک مقبول جاوا ٹیسٹنگ فریم ورک استعمال کریں گے جسے JUnit کہا جاتا ہے (ایک اور مقبول ہے TestNG، جسے آپ چاہیں تو استعمال بھی کر سکتے ہیں۔ وہ بہت ملتے جلتے ہیں، نحوی طور پر؛ TestNG JUnit سے متاثر ہے)۔ آپ JUnit کو یہاں سے ڈاؤن لوڈ اور انسٹال کر سکتے ہیں ۔ اس مثال کے کوڈ کے لیے، ہم 'سائنٹیفک کیلکولیٹر' کی مثال کو جاری رکھیں گے جس کا میں پہلے ذکر کر رہا تھا۔ اپنے سر کو لپیٹنا بہت آسان ہے، اور ٹیسٹ کوڈ بہت آسان ہے۔ روایتی مشق یہ ہے کہ آپ اپنی ہر کلاس کے لیے الگ الگ ٹیسٹ کلاسز لکھیں، لہذا ہم یہی کریں گے۔ آئیے فرض کریں کہ اس وقت، ہمارے پاس ایک Math.javaفائل ہے جس میں ریاضی کے تمام افعال ہیں (بشمول Math.add)، اور ہم MathTests.javaاسی پیکج میں ایک فائل لکھ رہے ہیں۔ اب آئیے امپورٹ سٹیٹمنٹس اور کلاس باڈی ترتیب دیں: (ممکنہ JUnit انٹرویو سوال: آپ سے پوچھا جا سکتا ہے کہ اپنا JUnit ٹیسٹ کہاں رکھنا ہے اور کیا آپ کو اپنی سورس فائلیں درآمد کرنے کی ضرورت ہے یا نہیں۔ اگر آپ اپنی ٹیسٹ کلاسیں اسی پیکج میں لکھ رہے ہیں۔ آپ کی مین کلاسز، پھر آپ کو ٹیسٹ کلاس میں اپنی سورس فائلوں کے لیے درآمدی بیانات کی ضرورت نہیں ہے۔ بصورت دیگر، یقینی بنائیں کہ آپ اپنی سورس فائلیں درآمد کر رہے ہیں!)

import org.junit.jupiter.Test;    //gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; //less typing :) 

public class MathTests {
	//...
}
پہلا درآمدی بیان ہمیں @Testہیڈر دیتا ہے۔ ہم @Testہر ٹیسٹ فنکشن کی تعریف کے اوپر براہ راست ' ' لکھتے ہیں، تاکہ JUnit کو معلوم ہو کہ یہ ایک واحد یونٹ ٹیسٹ ہے جسے الگ سے چلایا جا سکتا ہے۔ بعد میں، میں آپ کو دکھاؤں گا کہ آپ اس ہیڈر کا استعمال کرتے ہوئے مخصوص یونٹ ٹیسٹ کیسے چلا سکتے ہیں۔ دوسرا درآمدی بیان ہمیں ٹائپنگ میں تھوڑا سا بچاتا ہے۔ بنیادی JUnit فنکشن جو ہم اپنے افعال کو جانچنے کے لیے استعمال کرتے ہیں وہ ہے Assert.assertEquals()، جو دو پیرامیٹرز (اصل قدر اور متوقع قدر) لیتا ہے اور یہ یقینی بناتا ہے کہ وہ برابر ہیں۔ اس دوسرے درآمدی بیان کے ہونے سے ہمیں assertEquals(...ہر بار یہ بتانے کی بجائے صرف ' ' ٹائپ کرنے کی اجازت ملتی ہے کہ یہ کس پیکج کا حصہ ہے۔ اب اس بات کی تصدیق کرنے کے لیے ایک بہت ہی آسان ٹیسٹ کیس لکھتے ہیں کہ 2 + 2 واقعی 4 ہے!

import org.junit.jupiter.Test; // gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; // less typing :) 


public class MathTests {
	@Test
	public void add_twoPlusTwo_returnsFour(){
	final int expected = 4;
	final int actual = Math.add(2, 2);
	assertEquals(2+2 is 4, actual, expected);
	}
}
آئیے ٹیسٹ فنکشن کی پانچ لائنوں میں سے ہر ایک کو دیکھتے ہیں اور وہ کیا کرتی ہیں: لائن 5: یہ @Testہیڈر بتاتا ہے کہ ذیل میں فنکشن کی تعریف add_twoPlusTwo_returnsFour()درحقیقت ایک ٹیسٹ فنکشن ہے جسے JUnit الگ سے چلا سکتا ہے۔ لائن 6: یہ ہمارے ٹیسٹ کیس کے لیے فنکشن کا دستخط ہے۔ ٹیسٹ کیسز ہمیشہ بہت ہی واحد ہوتے ہیں۔ وہ صرف ایک مخصوص مثال کی جانچ کرتے ہیں، جیسے 2+2=4۔ یہ کنونشن ہے کہ آپ اپنے ٹیسٹ کیسز کو " " فارم میں نام دیں [function]_[params]_returns[expected]()، جس [function]فنکشن کی آپ جانچ کر رہے ہیں اس کا نام کہاں ہے، [params]وہ مخصوص مثال کے پیرامیٹرز ہیں جن کی آپ جانچ کر رہے ہیں، اور [expected]فنکشن کی متوقع واپسی کی قیمت ہے۔ ٹیسٹ فنکشنز میں تقریباً ہمیشہ ہی '' کی واپسی کی قسم ہوتی ہے voidکیونکہ پورے فنکشن کا بنیادی نکتہ چلانا ہے assertEquals، جو کنسول کو آؤٹ پٹ کرے گا چاہے آپ کا ٹیسٹ پاس ہو یا نہ ہو۔ آپ کو کہیں بھی واپس کرنے کے لیے کسی دوسرے ڈیٹا کی ضرورت نہیں ہے۔ لائن 7: ہم finalواپسی کی قسم کے ایک ' ' متغیر کا اعلان کرتے ہیں Math.add (int)اور اسے کنونشن کے ذریعہ 'متوقع' کا نام دیتے ہیں۔ اس کی قیمت وہ جواب ہے جس کی ہم توقع کر رہے ہیں (4)۔ سطر 8: ہم finalواپسی کی قسم کے ایک ' ' متغیر کا اعلان کرتے ہیں Math.add (int)اور اسے کنونشن کے مطابق 'اصل' کا نام دیتے ہیں۔ اس کی قدر کا نتیجہ ہے Math.add(2, 2)۔ لائن 9: سنہری لکیر۔ یہ وہ لائن ہے جو اصل اور متوقع کا موازنہ کرتی ہے اور ہمیں بتاتی ہے کہ ہم نے ٹیسٹ صرف اس صورت میں پاس کیا جب وہ برابر ہوں۔ پاس کردہ پہلا پیرامیٹر "2+2 ہے 4" ٹیسٹ فنکشن کی تفصیل ہے۔

کیا ہوگا اگر میرا فنکشن مستثنیٰ ہو؟

@Testاگر آپ کی مخصوص جانچ کی مثال کو یہ دعوی کرنے کے بجائے ایک استثنا دینا چاہئے کہ ایک حقیقی اور متوقع قیمت برابر ہے، تو JUnit کے پاس ہیڈر میں اس کی وضاحت کرنے کا ایک طریقہ ہے۔ آئیے ذیل میں ایک مثال پر ایک نظر ڈالیں۔ Math.javaیہ فرض کرتے ہوئے کہ ہمارے پاس کالڈ میں ایک فنکشن ہے Math.divide، ہم اس بات کو یقینی بنانا چاہتے ہیں کہ ان پٹ کو 0 سے تقسیم نہیں کیا جاسکتا Math.divide(a, 0)ہے ArithmeticException.class۔ ہم ہیڈر میں اس طرح کی وضاحت کرتے ہیں:

import org.junit.jupiter.Test; // gives us the @Test header
import static org.junit.jupiter.api.Assertions.assertEquals; // less typing :) 


public class MathTests {
	@Test (expectedExceptions = ArithmeticException.class)
	public void divide_byZero_throwsException() throws ArithmeticException{
	Math.divide(1, 0);
	}
}
آپ کے لیے ایک سے زیادہ مستثنیات ہو سکتے ہیں expectedExceptions، بس اپنی استثنائی کلاسوں کی فہرست بنانے کے لیے بریکٹ اور کوما استعمال کرنا یقینی بنائیں، جیسا کہ:

expectedException = {FirstException.class, SecondException.class,}

میں جاوا میں اپنے JUnit ٹیسٹ کیسے چلا سکتا ہوں؟

JUnit کو IntelliJ میں کیسے شامل کیا جائے: https://stackoverflow.com/questions/19330832/setting-up-junit-with-intellij-idea آپ اپنا پروجیکٹ چلا سکتے ہیں جیسا کہ آپ عام طور پر ٹیسٹ چلاتے ہیں۔ ٹیسٹ کلاس میں تمام ٹیسٹ چلانے سے وہ حروف تہجی کی ترتیب میں چلیں گے۔ @OrderJUnit 5 میں، آپ ایک ٹیگ شامل کرکے ٹیسٹوں میں ترجیح دے سکتے ہیں ۔ ایک مثال:

@TestMethodOrder(OrderAnnotation.class)
public class Tests {@Test
@Order(2)
public void a_test() {}

@Test
@Order (1)
public void b_test() {}}
اگرچہ حروف تہجی سے a_test()پہلے b_test()اور کوڈ میں آتا ہے، یہاں سے b_test()پہلے چلے گا a_test()، کیونکہ 1 ترتیب میں 2 سے پہلے آتا ہے۔ تو یہ JUnit کی بنیادی باتوں کے بارے میں ہے۔ اب، آئیے JUnit کے انٹرویو کے چند عام سوالات سے نمٹتے ہیں، اور راستے میں JUnit کے بارے میں کچھ اور جانیں!

JUnit انٹرویو کے سوالات (اضافی معلومات)

یہاں میں نے JUnit انٹرویو کے سب سے مشہور سوالات جمع کیے ہیں۔ اگر آپ کے پاس شامل کرنے کے لئے کچھ ہے تو - نیچے دیئے گئے تبصروں میں بلا جھجھک ایسا کریں۔ س: خود بخود کسی ٹیسٹ میں ناکام ہونے کے لیے آپ اپنے ٹیسٹ کے طریقہ کار میں کس طریقہ کو کال کر سکتے ہیں؟ A: ناکام ("غلطی کی وضاحت یہاں!")؛ س: آپ ڈاگ کلاس کی جانچ کر رہے ہیں۔ ڈاگ آبجیکٹ کو جانچنے کے لیے، آپ کو اس پر ٹیسٹ چلانے سے پہلے اسے فوری بنانا ہوگا۔ لہذا آپ کتے کو تیز کرنے کے لئے ایک سیٹ اپ () فنکشن لکھتے ہیں۔ آپ تمام ٹیسٹنگ کے دوران اس فنکشن کو صرف ایک بار چلانا چاہتے ہیں۔ آپ کو سیٹ اپ () فنکشن دستخط کے اوپر براہ راست کیا رکھنا چاہئے تاکہ JUnit ٹیسٹ چلانے سے پہلے setUp() کو چلانا جانتا ہو؟ A: @BeforeClass (@BeforeAll JUnit 5 میں) سوال: اوپر بیان کردہ سیٹ اپ() فنکشن کا فنکشن دستخط کیا ہونا چاہیے؟ A: عوامی جامد باطل۔ @BeforeClass (@BeforeAll in JUnit 5) یا @AfterClass (@AfterAll JUnit 5 میں) کے ساتھ کوئی بھی فنکشن جامد ہونا ضروری ہے۔ س: آپ نے ڈاگ کلاس کی جانچ کر لی ہے۔ آپ void tearDown() فنکشن لکھتے ہیں جو ڈیٹا کو صاف کرتا ہے اور ہر ٹیسٹ کے بعد کنسول کے لیے معلومات پرنٹ کرتا ہے۔ آپ چاہتے ہیں کہ یہ فنکشن ہر ایک ٹیسٹ کے بعد چلے۔ آپ کو ٹیئر ڈاؤن() فنکشن دستخط کے اوپر براہ راست کیا رکھنا چاہیے تاکہ JUnit ہر ٹیسٹ چلانے کے بعد ٹیئر ڈاؤن() چلانا جانتا ہو؟ A: @After (@AfterEach JUnit 5 میں)
تبصرے
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION