ایک حالیہ ڈیپلائمنٹ (deployment) نے تین مائیکرو سروسز (microservices) کو خراب کر دیا، باوجود اس کے کہ ہر یونٹ ٹیسٹ (unit test)، انٹیگریشن ٹیسٹ (integration test) اور مِک سرور (mock-server) چیک کامیاب رہا تھا۔ ٹیم نے اپنے API mocks کو contract testing سے بدل دیا۔ چھ ماہ میں contract کی تعداد تین سے بڑھ کر 47 ہو گئی اور ماہانہ انٹیگریشن فیل ہونے کی شرح دو واقعات سے کم ہو کر صفر ہو گئی۔
مِکس (mocks) آپ کی حفاظت کیوں نہیں کر سکتے
ایک مِک سرور صرف اس شکل کی نقل کرتا ہے جس کی صارف (consumer) توقع کرتا ہے؛ یہ کبھی یہ چیک نہیں کرتا کہ فراہم کنندہ (provider) واقعی وہی شکل فراہم کر رہا ہے یا نہیں۔ اگر کوئی فراہم کنندہ کسی فیلڈ کا نام تبدیل کر دے—مثلاً name سے display_name میں—تو مِک اب بھی پرانا پی لوڈ (payload) واپس کرے گا، صارف کے ٹیسٹ کامیاب (green) رہیں گے، اور لائیو سسٹم کریش ہو جائے گا۔ منگل کے دن دوپہر 2 بجے ہونے والا پروڈکشن فیلئیر بالکل ایسا ہی تھا: مِک نے اصل کنٹریکٹ کے بارے میں "جھوٹ" بولا تھا۔
کنٹریکٹ ٹیسٹنگ (Contract testing) خلا کو پُر کرتی ہے
کنٹریکٹ ٹیسٹنگ API کے دونوں اطراف کو کسی بھی کوڈ کے پروڈکشن میں جانے سے پہلے ایک مشترکہ تعریف پر اتفاق کرنے پر مجبور کرتی ہے۔ دو عام طریقے موجود ہیں:
- Consumer-driven contracts – صارف کی طرف سے چلنے والے کنٹریکٹس – صارف والی سروس توقعات لکھتی ہے؛ فراہم کرنے والی سروس ان کی تصدیق کرتی ہے۔ یہ ان اندرونی مائیکرو سروسز کے لیے بہترین کام کرتا ہے جو ایک ساتھ ترقی کرتی ہیں۔
- Provider-driven contracts – فراہم کنندہ کی طرف سے چلنے والے کنٹریکٹس – فراہم کنندہ ایک وضاحت (specification) شائع کرتا ہے؛ صارفین اپنے کوڈ کو اس کے مطابق چیک کرتے ہیں۔ یہ عوامی (public) APIs کے لیے عام طریقہ کار ہے۔
پہلا طریقہ عام طور پر مائیکرو سروس آرکیٹیکچر کے اندر ٹوٹے ہوئے انٹیگریشنز کو روکتا ہے۔
صارف کی طرف سے چلنے والا کنٹریکٹ (consumer-driven contract) کیسے کام کرتا ہے
- صارف ایک ایسا ٹیسٹ لکھتا ہے جو بالکل بیان کرتا ہے کہ اسے فراہم کنندہ سے کیا ضرورت ہے۔
- ٹیسٹ چلانے سے ایک pact file تیار ہوتی ہے – ایک JSON دستاویز جو ان توقعات کو ریکارڈ کرتی ہے۔
- فراہم کنندہ اپنے CI پائپ لائن میں pact file کے خلاف اپنی اصل سروس چلاتا ہے۔
- اگر فراہم کنندہ کوئی فیلڈ تبدیل کرتا ہے، تو تصدیق (verification) ناکام ہو جاتی ہے اور بلڈ (build) روک دیا جاتا ہے۔
چونکہ تصدیق اصل فراہم کنندہ کے کوڈ پر کی جاتی ہے، اس لیے کوئی بھی توڑنے والی تبدیلی (breaking change) ڈیپلائمنٹ کے بعد نہیں بلکہ شروع میں ہی پکڑی جاتی ہے۔
آپ کے ٹیسٹ پیرا مڈ (test pyramid) میں کنٹریکٹ ٹیسٹ کہاں ہونے چاہئیں
- Unit tests – تیز، الگ تھلگ لاجک (logic) کو ٹیسٹ کرتے ہیں۔
- Contract tests – درمیانی رفتار، اس بات کی تصدیق کرتے ہیں کہ API کے معاہدے برقرار ہیں۔
- End-to-end tests – سست، مکمل کاروباری بہاؤ (business flows) کا تجربہ کرتے ہیں۔
کنٹریکٹ ٹیسٹ کو یونٹ ٹیسٹ کے فوری فیڈ بیک اور اینڈ ٹو اینڈ سوٹس (end-to-end suites) کے وسیع کوریج کے درمیان ایک پل کے طور پر سمجھیں۔ ان انٹیگریشن پوائنٹس کو نشانہ بنائیں جو سب سے زیادہ ٹوٹتے ہیں اور دو یا تین اہم اینڈ پوائنٹس (endpoints) سے آغاز کریں۔
حقیقی دنیا میں اپنائے جانے کی کہانی
وہ ٹیم جس نے اس مضمون کی بنیاد رکھی، انہوں نے اپنے تین سب سے نازک کالز (calls) کو کور کرنے والے تین کنٹریکٹس سے آغاز کیا۔ چھ ماہ بعد ان کے پاس 47 کنٹریکٹس تھے جو بین السربیس (inter-service) ٹریفک کے زیادہ تر حصے کو کور کرتے تھے۔ اس دوران API ٹوٹنے کے واقعات ماہانہ دو سے کم ہو کر صفر ہو گئے۔
کب کنٹریکٹ ٹیسٹنگ فائدہ مند نہیں ہو سکتی
- آپ ایک اکیلے ڈویلپر ہیں جو تمام سروسز کو ایک ہی ریپوزٹری (repository) میں رکھتے ہیں۔
- API غیر معمولی طور پر مستحکم ہے اور برسوں سے تبدیل نہیں ہوئی ہے۔
- آپ ایک ایسا پروٹو ٹائپ (prototype) بنا رہے ہیں جسے جلد ہی ختم کر دیا جائے گا۔
ان حالات میں کنٹریکٹس کو برقرار رکھنے کا بوجھ (overhead) فائدے سے زیادہ ہو سکتا ہے۔
ممکنہ نقصانات اور ان میں کمی لانے کے طریقے
- کنٹریکٹس کو ان کوڈ کے ساتھ ورژن (version) کے مطابق رکھیں جن کی وہ وضاحت کرتے ہیں۔
- پرانے کنٹریکٹس سے بچنے کے لیے ہر CI رن میں تصدیق کو خودکار (automate) بنائیں۔
- اتفاقیہ خرابیوں کو پکڑنے کے لیے پل ریکویسٹ (pull requests) میں کنٹریکٹ کی تبدیلیوں کا جائزہ لیں۔
خلاصہ
اگر آپ اب بھی خود سے بنائے گئے مِکس (mocks) پر بھروسہ کر رہے ہیں تاکہ خود کو یقین دلا سکیں کہ آپ کی سروسز بات چیت کر سکتی ہیں، تو آپ ایک جھوٹے وعدے پر جوا لگا رہے ہیں۔ کنٹریکٹ ٹیسٹنگ اس جوئے کو ایک قابلِ تصدیق معاہدے میں بدل دیتی ہے، جو پروڈکشن تک پہنچنے سے پہلے ہی توڑنے والی تبدیلیوں کو پکڑ لیتی ہے اور جیسا کہ ٹیم کے اعداد و شمار ظاہر کرتے ہیں، یہ انٹیگریشن کی ناکامیوں کو مکمل طور پر ختم کر سکتی ہے۔
