পরীক্ষা করা শ্রেণীর খারাপ অভ্যাসের জন্য গুপ্তচরবৃত্তি করা কি?


14

আমি এমন একটি প্রকল্পে কাজ করছি যেখানে শ্রেণীর অভ্যন্তরীণ কলগুলি স্বাভাবিক তবে ফলাফলগুলি বহুগুণ সাধারণ মান। উদাহরণ ( বাস্তব কোড নয় ):

public boolean findError(Set<Thing1> set1, Set<Thing2> set2) {
  if (!checkFirstCondition(set1, set2)) {
    return false;
  }
  if (!checkSecondCondition(set1, set2)) {
    return false;
  }
  return true;
}

এই ধরণের কোডের জন্য ইউনিট পরীক্ষাগুলি লেখা সত্যিই শক্ত কারণ আমি কেবল কন্ডিশন সিস্টেমটি পরীক্ষা করতে চাই এবং প্রকৃত শর্তগুলির বাস্তবায়ন নয়। (আমি এটি পৃথক পরীক্ষায় করি)) আসলে আমি শর্তগুলি বাস্তবায়িত করে এমন ফাংশনগুলি পাস করি এবং পরীক্ষাগুলিগুলিতে আমি কেবল কিছু উপহাস সরবরাহ করি তবে ভাল হয়। এই পদ্ধতির সমস্যাটি হ'ল শোরগোল: আমরা জেনেরিকগুলি প্রচুর ব্যবহার করি

একটি কার্যনির্বাহী সমাধান; তবে, পরীক্ষিত বস্তুকে গুপ্তচর বানানো এবং অভ্যন্তরীণ ফাংশনগুলিতে কলগুলি উপহাস করা।

systemUnderTest = Mockito.spy(systemUnderTest);
doReturn(true).when(systemUnderTest).checkFirstCondition(....);

এখানে উদ্বেগটি হ'ল এসইউটির বাস্তবায়ন কার্যকরভাবে পরিবর্তিত হয়েছে এবং পরীক্ষাগুলি বাস্তবায়নের সাথে সুসংগত রাখতে সমস্যা হতে পারে। এটা কি সত্য? অভ্যন্তরীণ পদ্ধতির কলগুলির এই সর্বনাশ এড়াতে কি সর্বোত্তম অনুশীলন রয়েছে?

নোট করুন যে আমরা একটি অ্যালগরিদমের অংশগুলির বিষয়ে কথা বলছি, তাই এটি বেশ কয়েকটি শ্রেণিতে বিভক্ত করা পছন্দসই সিদ্ধান্ত নাও হতে পারে।

উত্তর:


15

ইউনিট পরীক্ষাগুলি তাদের যে ক্লাসগুলি পরীক্ষা করে তা কালো বক্স হিসাবে বিবেচনা করা উচিত একমাত্র বিষয় যা এর পাবলিক পদ্ধতিগুলি প্রত্যাশিতভাবে আচরণ করে। শ্রেণি অভ্যন্তরীণ রাষ্ট্র এবং ব্যক্তিগত পদ্ধতিগুলির মাধ্যমে কীভাবে এটি অর্জন করে তা বিবেচনা করে না।

আপনি যখন মনে করেন যে এইভাবে অর্থবহ পরীক্ষা করা অসম্ভব, তখন এটি আপনার লক্ষণীয় যে আপনার ক্লাসগুলি খুব শক্তিশালী এবং খুব বেশি করে too আপনার কিছু কার্যকারিতা আলাদা ক্লাসে স্থানান্তরিত করার কথা বিবেচনা করা উচিত যা পৃথকভাবে পরীক্ষা করা যেতে পারে।


1
আমি ইউনিট টেস্টিংয়ের ধারণাটি অনেক আগেই উপলব্ধি করেছি এবং এগুলির একটি গোছা সফলভাবে লিখেছি। এটি কেবল প্রতারণা করছে যে কোনও কিছু কাগজে সহজ দেখায়, কোডে এটি আরও খারাপ দেখায়, এবং অবশেষে আমার এমন একটি মুখোমুখি হয়েছি যার সত্যই একটি সহজ ইন্টারফেস রয়েছে তবে আমাকে ইনপুটগুলির আশেপাশের অর্ধেক বিশ্বের উপহাস করতে হবে।
allprog

@ allprog যখন আপনাকে প্রচুর পরিহাস করতে হবে তখন মনে হয় আপনার ক্লাসগুলির মধ্যে অনেক বেশি নির্ভরশীলতা রয়েছে। আপনি কি তাদের মধ্যে সংযোগ কমাতে চেষ্টা করেছেন?
ফিলিপ

@ এলপ্লাগ আপনি যদি এই পরিস্থিতিতে থাকেন তবে ক্লাস ডিজাইনের জন্য দোষ দেওয়া হবে।
itbruce

এটি ডেটা মডেল যা মাথা ব্যথার কারণ হয়ে দাঁড়ায়। এটি ORM নিয়ম এবং অন্যান্য অনেক প্রয়োজনীয়তা মেনে চলতে হয়। খাঁটি ব্যবসায়ের যুক্তি এবং স্টেটলেস কোড সহ ইউনিট পরীক্ষা করা সঠিকভাবে পাওয়া অনেক সহজ।
allprog

3
ইউনিট পরীক্ষাগুলি অগত্যা SUT কে ব্যাকবাক্স হিসাবে পরিচালনা করার প্রয়োজন হয় না। এ কারণেই তাদের ইউনিট পরীক্ষা বলা হয়। ঠাট্টা-নির্ভরতা নির্ভর করে আমি পরিবেশকে প্রভাবিত করতে পারি এবং আমার কী উপহাস করতে হবে তা জানতে, আমাকে অভ্যন্তরীণ কিছুগুলিও জানতে হবে। তবে অবশ্যই এর অর্থ এই নয় যে কোনওভাবেই এসইউটি পরিবর্তন করা উচিত। গুপ্তচরবৃত্তি, কিছু পরিবর্তন করতে পারবেন।
allprog

4

findError()এবং উভয়ই যদি checkFirstCondition()আপনার শ্রেণীর সর্বজনীন পদ্ধতি findError()হয় তবে কার্যকরভাবে একই কার্যকারিতাটির জন্য একটি মুখোমুখি যা ইতিমধ্যে একই এপিআই থেকে উপলব্ধ। এটির সাথে কোনও ভুল নেই, তবে এর অর্থ হ'ল এর জন্য আপনাকে পরীক্ষা লিখতে হবে যা ইতিমধ্যে বিদ্যমান পরীক্ষার সাথে খুব মিল। এই সদৃশটি আপনার জনসাধারণের ইন্টারফেসে অনুলিপিটি সহজেই প্রতিফলিত করে। অন্যদের থেকে এই পদ্ধতিটিকে আলাদাভাবে চিকিত্সা করার কোনও কারণ নেই।


অভ্যন্তরীণ পদ্ধতিগুলি কেবলমাত্র পরীক্ষার যোগ্য হওয়া দরকার বলে সর্বজনীন করা হয় এবং আমি এসইউটি সাবক্লাস করতে বা স্ট্যাটিক অভ্যন্তর শ্রেণির হিসাবে এসইউটি শ্রেণিতে ইউনিট পরীক্ষাগুলি অন্তর্ভুক্ত করতে চাই না। তবে আমি আপনার বক্তব্য পেতে। যাইহোক, এই ধরণের পরিস্থিতি এড়াতে আমি ভাল গাইড লাইন খুঁজে পাইনি। টিউটোরিয়ালগুলি সর্বদা বেসিক স্তরে আটকে থাকে যার বাস্তব সফ্টওয়্যারটির সাথে কোনও সম্পর্ক নেই। অন্যথায়, গুপ্তচরবৃত্তির কারণ হ'ল পরীক্ষার কোডের সদৃশতা এড়ানো এবং পরীক্ষার ইউনিটকে স্কোপড করা।
allprog

3
আমি একমত নই যে সঠিক ইউনিট পরীক্ষার জন্য সহায়তার পদ্ধতিগুলি সর্বজনীন হতে হবে। যদি কোনও পদ্ধতির চুক্তিতে বলা হয় যে এটি বিভিন্ন শর্ত পরীক্ষা করে, তবে একই পাবলিক পদ্ধতির বিরুদ্ধে কয়েকটি পরীক্ষা লেখার ক্ষেত্রে কোনও ভুল নেই, প্রতিটি "সাবকন্ট্র্যাক্ট" এর জন্য একটি। ইউনিট পরীক্ষার বিষয়টি হ'ল সমস্ত কোডের কভারেজ অর্জন করা, 1: 1 পদ্ধতি-পরীক্ষার চিঠিপত্রের মাধ্যমে জনসাধারণের পদ্ধতিগুলির একটি সূক্ষ্ম কভারেজ অর্জন করা নয়।
কিলিয়ান ফুট

একের পর এক অভ্যন্তরীণ টুকরো পরীক্ষা করার চেয়ে পরীক্ষার জন্য কেবল সর্বজনীন এপিআই ব্যবহার করা বহুগুণ বেশি জটিল is আমি তর্ক করি না, আমি পেয়েছি যে এই পদ্ধতির সেরা নয় এবং এটির আমার পশ্চাদমুখে রয়েছে যা আমার প্রশ্নটি দেখায়। বৃহত্তম সমস্যাটি হ'ল জাভাগুলিতে ফাংশনগুলি কম্পোজেবল হয় না এবং কাজের ক্ষেত্রগুলি অত্যন্ত নিবিষ্ট। তবে রিয়েল ইউনিট পরীক্ষার জন্য আর কোনও সমাধান নেই বলে মনে হয়।
allprog

4

ইউনিট পরীক্ষাগুলি চুক্তি পরীক্ষা করা উচিত; এটি তাদের জন্য একমাত্র গুরুত্বপূর্ণ জিনিস। চুক্তির অংশ নয় এমন কোনও কিছু পরীক্ষা করা কেবল সময়ের অপচয় নয়, এটি ত্রুটির সম্ভাব্য উত্স source যখনই আপনি কোনও বিকাশকারী যখন প্রয়োগের বিশদ পরিবর্তন করেন তখন পরীক্ষাগুলি পরিবর্তন করতে দেখেন, অ্যালার্ম বেল বাজে; যে বিকাশকারী তার ভুলগুলি লুকিয়ে রাখে (উদ্দেশ্যমূলক হোক বা নাও)। ইচ্ছাকৃতভাবে বাস্তবায়ন বিশদটি পরীক্ষা করে এই খারাপ অভ্যাসটি জোর করে, ত্রুটিগুলি মুখোশ হওয়ার সম্ভাবনা বেশি করে তোলে।

অভ্যন্তরীণ কলগুলি একটি বাস্তবায়নের বিশদ এবং কেবল পারফরম্যান্স পরিমাপে আগ্রহী হওয়া উচিত । যা সাধারণত ইউনিট পরীক্ষার কাজ নয়।


শুনে ভালো লাগছে. তবে বাস্তবে, "স্ট্রিং" আমাকে টাইপ করতে হবে এবং কোডটি কল করতে হবে এমন একটি ভাষায় যা ফাংশন সম্পর্কে খুব কমই জানে। তত্ত্বের মধ্যে আমি সহজেই কোনও সমস্যা বর্ণনা করতে পারি এবং এটি সহজ করার জন্য এখানে এবং সেখানে বিকল্পগুলি তৈরি করতে পারি। কোডে আমাকে এই নমনীয়তা অর্জন করতে অনেকগুলি সিনট্যাকটিক শব্দ করতে হবে যা এটি ব্যবহার থেকে আমাকে ফিরিয়ে দেয় down যদি পদ্ধতিটিতে একই ক্লাসে aএকটি কল টু মেথড থাকে b, তবে এর পরীক্ষাগুলিতে aঅবশ্যই এর পরীক্ষাগুলি অন্তর্ভুক্ত থাকে b। আর এটি পরিবর্তন করার কোনও উপায় নেই যতক্ষণ bনা aপ্যারামিটার হিসাবে পাস করা হয় তবে অন্য কোনও সমাধান নেই, আমি দেখছি।
allprog

1
যদি bসর্বজনীন ইন্টারফেসের একটি অংশ হয় তবে তা যাইহোক পরীক্ষা করা উচিত। যদি তা না হয় তবে এটি পরীক্ষা করার দরকার নেই। আপনি যদি এটি পরীক্ষা করতে চেয়েছিলেন কেবল তাই আপনি যদি এটি সর্বজনীন করেন তবে আপনি ভুল করেছেন।
itbruce

@ ফিলিপের উত্তরে আমার মন্তব্য দেখুন। আমি এখনও উল্লেখ করি নি তবে ডেটা মডেলটি হ'ল দুষ্টের উত্স। খাঁটি, স্টেটলেস কোড হ'ল একটি পিষ্টক।
allprog

2

প্রথমত, আমি ভাবছি যে আপনি লিখেছেন উদাহরণ ফাংশন সম্পর্কে পরীক্ষা করা কি কঠিন? আমি যতদূর দেখতে পাচ্ছি, আপনি সহজেই বিভিন্ন ইনপুটগুলিতে পাস করতে পারেন এবং সঠিক বুলিয়ান মানটি ফিরে এসেছে কিনা তা পরীক্ষা করতে পারেন। আমি কী মিস করছি?

গুপ্তচরদের হিসাবে, গুপ্তচর এবং উপহাস ব্যবহার করে এমন ধরণের তথাকথিত "হোয়াইট-বাক্স" পরীক্ষা করা আরও লেখার আরও বেশি কাজ করার আদেশ, কেবল লেখার জন্য আরও অনেক পরীক্ষামূলক কোড নেই, তবে যে কোনও সময় বাস্তবায়ন হয় পরিবর্তিত হয়েছে, আপনাকে অবশ্যই পরীক্ষাগুলি পরিবর্তন করতে হবে (এমনকি ইন্টারফেসটি একই থাকলেও)। ব্ল্যাক-বাক্স পরীক্ষার চেয়ে এই ধরণের পরীক্ষা-নিরীক্ষাও কম নির্ভরযোগ্য, কারণ আপনার অতিরিক্ত টেস্ট কোডটি সঠিক কিনা তা নিশ্চিত করা দরকার এবং আপনি বিশ্বাস করতে পারেন যে ব্ল্যাক-বাক্স ইউনিটের পরীক্ষাগুলি যদি ইন্টারফেসের সাথে মেলে না তবে ব্যর্থ হবে , আপনি কোডকে অত্যধিক উপকারের বিষয়ে বিশ্বাস করতে পারবেন না কারণ কখনও কখনও পরীক্ষা এমনকি অনেক বাস্তব কোডও পরীক্ষা করে না - কেবল বিদ্রূপ করে। উপহাসগুলি ভুল হলে, সম্ভাব্যতাটি হ'ল আপনার পরীক্ষাগুলি সফল হবে তবে আপনার কোডটি এখনও ভঙ্গ।

সাদা বাক্স পরীক্ষার সাথে যে কেউ অভিজ্ঞতা আছে সে আপনাকে বলতে পারে যে তারা লেখার এবং রক্ষণাবেক্ষণের জন্য পাছায় ব্যথা করছে। তারা কম নির্ভরযোগ্য এই সত্যটির সাথে মিলিত, বেশিরভাগ ক্ষেত্রেই সাদা-বাক্সের পরীক্ষাটি নিকৃষ্টতম।


নোটের জন্য ধন্যবাদ। উদাহরণ ফাংশন হ'ল একটি জটিল অ্যালগরিদমে আপনাকে যা লিখতে হবে তার চেয়ে বেশি মাত্রার অর্ডার। প্রকৃতপক্ষে, প্রশ্নটি আরও মতো হতে পারে: বেশ কয়েকটি অংশে গুপ্তচরদের সাথে অ্যালগরিদমগুলি পরীক্ষা করা কি সমস্যাযুক্ত? এটি রাষ্ট্রীয় কোড নয়, সমস্ত রাজ্যকে ইনপুট আর্গুমেন্টে আলাদা করা হয়। ইস্যুটি হ'ল সত্য যে আমি সাব ফাংশনগুলির জন্য বুদ্ধিমান পরামিতিগুলি সরবরাহ না করে উদাহরণে জটিল ফাংশনটি পরীক্ষা করতে চাই।
allprog

জাভা 8 এ ফাংশনাল প্রোগ্রামিংয়ের ভোর হওয়ার সাথে এটি কিছুটা মার্জিত হয়ে উঠেছে তবে এখনও একক শ্রেণিতে কার্যকারিতা রাখা আলাদাভাবে (একা কার্যকর নয়) অংশগুলি একবার "ব্যবহারের জন্য" বের করার চেয়ে অ্যালগরিদমের ক্ষেত্রে আরও ভাল পছন্দ হতে পারে Java ক্লাস শুধুমাত্র পরীক্ষার কারণে। এই সম্মানে গুপ্তচরবৃত্তি বিদ্রূপের মতোই করেন তবে সুসংগত কোডটি ভিজ্যুয়ালি উড়িয়ে দেওয়া ছাড়াই। প্রকৃতপক্ষে, একই সেটআপ কোডটি মোক হিসাবে ব্যবহৃত হয়। আমি চরম থেকে দূরে থাকতে চাই, প্রতিটি ধরণের পরীক্ষা নির্দিষ্ট জায়গায় উপযুক্ত হতে পারে। কোনওরকম পরীক্ষা নিরীক্ষার চেয়ে অনেক ভাল। :)
allprog

"আমি জটিল ক্রিয়াকলাপটি পরীক্ষা করতে চাই .. সাব ফাংশনগুলির জন্য বুদ্ধিমান পরামিতি সরবরাহ না করেই" - আপনি সেখানে কী বোঝাতে চেয়েছেন তা আমি পাই না। কোন সাব ফাংশন? আপনি কি 'জটিল ফাংশন' দ্বারা অভ্যন্তরীণ ফাংশনগুলি ব্যবহার করছেন সে সম্পর্কে কথা বলছেন?
বিটি

গুপ্তচরবৃত্তিটিই আমার ক্ষেত্রে এটি কার্যকর। অভ্যন্তরীণ ফাংশনগুলি নিয়ন্ত্রণ করতে বেশ জটিল। কোডের কারণে নয়, কারণ তারা যুক্তিযুক্ত জটিল কিছু বাস্তবায়িত করেছেন। বিভিন্ন শ্রেণিতে স্টাফ স্থানান্তর করা একটি প্রাকৃতিক বিকল্প তবে এই ফাংশনগুলি একাই কার্যকর হয় না। সুতরাং, ক্লাসকে একসাথে রাখা এবং গুপ্তচর কার্যকারিতা দ্বারা এটি নিয়ন্ত্রণ করা আরও ভাল বিকল্প হিসাবে প্রমাণিত হয়েছিল। প্রায় এক বছর ধরে নির্বিঘ্নে কাজ করেছে এবং সহজেই মডেল পরিবর্তনগুলি সহ্য করতে পারে। আমি তখন থেকে এই প্যাটার্নটি ব্যবহার করি নি, কেবল এটি উল্লেখ করা ভাল বলে মনে হয়েছিল যে এটি কিছু ক্ষেত্রে কার্যকর is
allprog

@ allprog "যৌক্তিকভাবে জটিল" - এটি জটিল হলে আপনার জটিল পরীক্ষার প্রয়োজন need এর আশেপাশে কোনও উপায় নেই। গুপ্তচরবৃত্তিগুলি আপনার জন্য এটি আরও শক্ত এবং আরও জটিল করে তুলছে। গুপ্তচরদের ব্যবহার করে অন্য ফাংশনের অভ্যন্তরে তাদের বিশেষ আচরণ পরীক্ষা করার পরিবর্তে আপনি বোধগম্য উপ-ফাংশন তৈরি করা উচিত যা আপনি নিজেরাই পরীক্ষা করতে পারেন।
বিটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.