আমি বেশ কয়েকটি কারণে ব্যক্তিগত কার্যকারিতা পরীক্ষা করতে পছন্দ করি না। এগুলি নিম্নরূপ (টিএলডিআর লোকদের জন্য এটি প্রধান পয়েন্ট):
- সাধারণত যখন আপনি কোনও শ্রেণীর ব্যক্তিগত পদ্ধতি পরীক্ষা করার জন্য প্রলুব্ধ হন, তখন এটি একটি ডিজাইনের গন্ধ।
- আপনি পাবলিক ইন্টারফেসের মাধ্যমে এগুলি পরীক্ষা করতে পারেন (এটিই আপনি কীভাবে তাদের পরীক্ষা করতে চান, কারণ ক্লায়েন্ট এগুলি তাদের কল / ব্যবহার করবে)। আপনার ব্যক্তিগত পদ্ধতির জন্য সমস্ত উত্তীর্ণ পরীক্ষায় সবুজ আলো দেখে আপনি সুরক্ষার ভ্রান্ত ধারণা পেতে পারেন। আপনার জনসাধারণের ইন্টারফেসের মাধ্যমে আপনার ব্যক্তিগত ফাংশনে প্রান্তের মামলাগুলি পরীক্ষা করা আরও বেশি ভাল / নিরাপদ।
- আপনি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করে গুরুতর পরীক্ষার সদৃশ (যে পরীক্ষাগুলি দেখতে দেখতে দেখতে খুব অনুরূপ বলে মনে হচ্ছে) ঝুঁকিপূর্ণ। প্রয়োজনীয়তাগুলি পরিবর্তিত হওয়ার সাথে এর বড় ধরনের পরিণতি হয়, কারণ প্রয়োজনের চেয়ে আরও অনেকগুলি পরীক্ষাগুলি ভাঙবে। এটি আপনাকে এমন একটি অবস্থানেও রাখতে পারে যেখানে আপনার পরীক্ষার স্যুটের কারণে রিফ্যাক্টর পাওয়া শক্ত ... যা চূড়ান্ত বিড়ম্বনা, কারণ পরীক্ষার স্যুট আপনাকে নিরাপদে পুনরায় নকশাকরণ এবং রিফ্যাক্টর সাহায্য করতে পারে!
আমি এগুলির প্রত্যেককে একটি দৃ concrete় উদাহরণ দিয়ে ব্যাখ্যা করব। দেখা যাচ্ছে যে 2) এবং 3) কিছুটা জটিলভাবে সংযুক্ত রয়েছে, সুতরাং তাদের উদাহরণটি একই রকম, যদিও আমি আপনাকে ব্যক্তিগত পদ্ধতি পরীক্ষা না করানোর জন্য পৃথক কারণে আমি তাদের বিবেচনা করি।
এমন অনেক সময় আছে যেগুলি ব্যক্তিগত পদ্ধতিগুলির পরীক্ষা করা উপযুক্ত, উপরে তালিকাবদ্ধ ডাউনসাইড সম্পর্কে সচেতন হওয়া কেবল গুরুত্বপূর্ণ। আমি আরও বিশদ পরে এটি যেতে যাচ্ছি।
একেবারে প্রাইভেট পদ্ধতিগুলি পরীক্ষা করার জন্য টিডিডি কেন বৈধ অজুহাত নয় তাও আমি জানি।
খারাপ ডিজাইন থেকে বেরিয়ে আসার পথে আপনার প্রতিচ্ছবি
সবচেয়ে সাধারণ হল যে আমি দেখতে (বিরোধী) paterns কি মাইকেল পালক আহ্বান একটি "হিমশৈল" শ্রেণী (যদি আপনি যারা মাইকেল পালক জানি না, কিনতে যান / তার বই "উত্তরাধিকার কোড সঙ্গে কার্যকরভাবে কাজ করা" পড়ুন। তিনি হলেন আপনি একজন পেশাদার সফটওয়্যার ইঞ্জিনিয়ার / বিকাশকারী কিনা তা সম্পর্কে জানার যোগ্য কোনও ব্যক্তি। অন্যান্য (বিরোধী) নিদর্শন রয়েছে যা এই সমস্যাটি ক্রপ করার কারণ, তবে এটি এখন পর্যন্ত সবচেয়ে সাধারণ যা আমি পেরেছি। "আইসবার্গ" ক্লাসগুলির একটি পাবলিক পদ্ধতি রয়েছে এবং বাকীগুলি ব্যক্তিগত হয় (এ কারণেই এটি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করার জন্য লোভনীয়)। একে "আইসবার্গ" শ্রেণি বলা হয় কারণ সেখানে সাধারণত একাকী পাবলিক মেথড প্যাক আপ হয় তবে বাকী কার্যকারিতাটি ব্যক্তিগত পদ্ধতির আকারে পানির নীচে লুকিয়ে থাকে।
উদাহরণস্বরূপ, আপনি GetNextToken()
ধারাবাহিকভাবে একটি স্ট্রিং এ কল করে এবং এটি প্রত্যাশিত ফলাফলটি দেখায় তা পরীক্ষা করতে চাইতে পারেন । এর মতো একটি কার্য একটি পরীক্ষার নিশ্চয়তা দেয়: সেই আচরণটি তুচ্ছ নয়, বিশেষত যদি আপনার টোকেনাইজিং বিধিগুলি জটিল। আসুন ভান করুন যে এটি এতটা জটিল নয়, এবং আমরা কেবলমাত্র জায়গাগুলির দ্বারা সীমিত টোকেনগুলিতে দড়ি দিতে চাই। সুতরাং আপনি একটি পরীক্ষা লিখুন, সম্ভবত এটির মতো দেখতে কিছুটা লাগবে (কিছু ভাষা অজ্ঞেয়বাদী সিজেডো-কোড, আশা করি ধারণাটি পরিষ্কার হয়েছে):
TEST_THAT(RuleEvaluator, canParseSpaceDelimtedTokens)
{
input_string = "1 2 test bar"
re = RuleEvaluator(input_string);
ASSERT re.GetNextToken() IS "1";
ASSERT re.GetNextToken() IS "2";
ASSERT re.GetNextToken() IS "test";
ASSERT re.GetNextToken() IS "bar";
ASSERT re.HasMoreTokens() IS FALSE;
}
ঠিক আছে, এটি দেখতে বেশ সুন্দর দেখাচ্ছে। আমরা পরিবর্তন আনার সাথে সাথে আমরা এই আচরণটি বজায় রাখতে পারি তা নিশ্চিত করতে চাই। কিন্তু GetNextToken()
একটি ব্যক্তিগত ফাংশন! সুতরাং আমরা এটির মতো এটি পরীক্ষা করতে পারি না, কারণ এটি এমনকি সংকলনও করবে না (ধরে নেওয়া যাক আমরা পাইথনের মতো কিছু স্ক্রিপ্টিং ভাষার মত নয় এমন কিছু ভাষা ব্যবহার করি যা আসলে পাবলিক / প্রাইভেটকে প্রয়োগ করে)। তবে RuleEvaluator
একক দায়িত্বের নীতি (একক দায়িত্বের নীতি) অনুসরণ করতে শ্রেণি পরিবর্তন সম্পর্কে কী ? উদাহরণস্বরূপ, আমরা মনে করি পার্সার, টোকেনাইজার এবং মূল্যায়নকারীকে এক শ্রেণিতে জ্যাম দেওয়া হয়েছে। শুধু এই দায়িত্বগুলি আলাদা করা ভাল না? সর্বোপরি, আপনি যদি একটি Tokenizer
বর্গ তৈরি করেন , তবে এটি সর্বজনীন পদ্ধতিগুলি হবে HasMoreTokens()
এবং GetNextTokens()
। RuleEvaluator
বর্গ একটি হতে পারেTokenizer
সদস্য হিসাবে আপত্তি। Tokenizer
ক্লাসের পরিবর্তে ক্লাস পরীক্ষা না করে এখন আমরা উপরের মতো একই পরীক্ষা রাখতে পারি RuleEvaluator
।
এটি ইউএমএলে দেখতে কেমন লাগবে তা এখানে:
নোট করুন যে এই নতুন ডিজাইনটি মডুলারিটি বাড়িয়েছে, তাই আপনি আপনার সিস্টেমের অন্যান্য অংশগুলিতে এই ক্লাসগুলি পুনরায় ব্যবহার করতে পারবেন (আপনি না পারার আগে, সংজ্ঞা দ্বারা ব্যক্তিগত পদ্ধতিগুলি পুনরায় ব্যবহারযোগ্য নয়)। বর্ধিত বোধগম্যতা / স্থানীয়ত্বের পাশাপাশি নিয়ম মূল্যায়নকারীকে ভেঙে ফেলার এটি প্রধান সুবিধা।
পরীক্ষাটি চূড়ান্ত অনুরূপ দেখাবে, কেবলমাত্র এই সময়টি সংকলন করা ব্যতীত GetNextToken()
পদ্ধতিটি এখন Tokenizer
ক্লাসে প্রকাশ্য :
TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
input_string = "1 2 test bar"
tokenizer = Tokenizer(input_string);
ASSERT tokenizer.GetNextToken() IS "1";
ASSERT tokenizer.GetNextToken() IS "2";
ASSERT tokenizer.GetNextToken() IS "test";
ASSERT tokenizer.GetNextToken() IS "bar";
ASSERT tokenizer.HasMoreTokens() IS FALSE;
}
পাবলিক ইন্টারফেসের মাধ্যমে ব্যক্তিগত উপাদানগুলির পরীক্ষা করা এবং পরীক্ষার সদৃশ এড়ানো
এমনকি যদি আপনি ভাবেন না যে আপনি নিজের সমস্যাটিকে কম মডুলার উপাদানগুলিতে বিভক্ত করতে পারেন (যা আপনি যদি এটি করার চেষ্টা করেন তবে আপনি 95% সময় দিতে পারেন ), আপনি কেবলমাত্র একটি সরকারী ইন্টারফেসের মাধ্যমে ব্যক্তিগত ফাংশনগুলি পরীক্ষা করতে পারেন। অনেক সময় ব্যক্তিগত সদস্যরা পরীক্ষার উপযুক্ত না কারণ তাদের পাবলিক ইন্টারফেসের মাধ্যমে পরীক্ষা করা হবে। আমি যা যা দেখি তার অনেকগুলি পরীক্ষাগুলি দেখতে খুব মিল দেখা যায় তবে দুটি ভিন্ন ফাংশন / পদ্ধতি পরীক্ষা করে দেখি। যা ঘটতে চলেছে তা হ'ল যখন প্রয়োজনীয়তাগুলি পরিবর্তন হয় (এবং তারা সর্বদা এটি করে) তখন আপনার 1 টির পরিবর্তে এখন 2 টি ভাঙা পরীক্ষা রয়েছে And এবং যদি আপনি সত্যিই আপনার সমস্ত ব্যক্তিগত পদ্ধতি পরীক্ষা করেন তবে আপনার 1 টির পরিবর্তে 10 টির মতো ভাঙ্গা পরীক্ষা থাকতে পারে short , ব্যক্তিগত ফাংশন পরীক্ষা করে (ব্যবহার করে)FRIEND_TEST
বা তাদের সর্বজনীন করা বা প্রতিবিম্ব ব্যবহার করে) যা অন্যথায় পাবলিক ইন্টারফেসের মাধ্যমে পরীক্ষা করা যেতে পারে পরীক্ষার সদৃশ হতে পারে । আপনি সত্যিই এটি চান না, কারণ আপনার টেস্ট স্যুটটি আপনাকে ধীর করে দেওয়ার চেয়ে বেশি কিছু ব্যথা করে না। এটি বিকাশের সময় হ্রাস এবং রক্ষণাবেক্ষণ ব্যয় হ্রাস করার কথা! যদি আপনি কোনও ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করেন যা অন্যথায় পাবলিক ইন্টারফেসের মাধ্যমে পরীক্ষা করা হয়, টেস্ট স্যুটটি খুব ভাল বিপরীতভাবে করতে পারে এবং সক্রিয়ভাবে রক্ষণাবেক্ষণের ব্যয় বৃদ্ধি করতে এবং বিকাশের সময় বাড়িয়ে তুলতে পারে। আপনি যখন কোনও ব্যক্তিগত ফাংশন সর্বজনীন করেন, বা আপনি যেমন FRIEND_TEST
এবং / অথবা প্রতিবিম্বের মতো কিছু ব্যবহার করেন , আপনি সাধারণত দীর্ঘস্থায়ীভাবে অনুশোচনা করে শেষ করবেন।
Tokenizer
ক্লাসের নিম্নলিখিত সম্ভাব্য বাস্তবায়ন বিবেচনা করুন :
ধরা যাক যে SplitUpByDelimiter()
অ্যারে ফিরিয়ে দেওয়ার জন্য এটি দায়ী যে অ্যারের প্রতিটি উপাদানই একটি টোকেন। তদ্ব্যতীত, GetNextToken()
কেবল এটি বলা যাক যে কেবল এই ভেক্টরের উপরে একটি পুনরাবৃত্তকারী। সুতরাং আপনার সার্বজনীন পরীক্ষাটি এটিকে দেখতে পারে:
TEST_THAT(Tokenizer, canParseSpaceDelimtedTokens)
{
input_string = "1 2 test bar"
tokenizer = Tokenizer(input_string);
ASSERT tokenizer.GetNextToken() IS "1";
ASSERT tokenizer.GetNextToken() IS "2";
ASSERT tokenizer.GetNextToken() IS "test";
ASSERT tokenizer.GetNextToken() IS "bar";
ASSERT tokenizer.HasMoreTokens() IS false;
}
আসুন আমরা ভেবে দেখি যে মাইকেল ফেদারের একটি গ্রোপিং সরঞ্জামকে আমরা ডেকে আছি । এটি এমন একটি সরঞ্জাম যা আপনাকে অন্য ব্যক্তির ব্যক্তিগত অংশগুলি স্পর্শ করতে দেয়। FRIEND_TEST
গুগলতেস্টের একটি উদাহরণ , বা ভাষা যদি এটি সমর্থন করে তবে প্রতিবিম্ব।
TEST_THAT(TokenizerTest, canGenerateSpaceDelimtedTokens)
{
input_string = "1 2 test bar"
tokenizer = Tokenizer(input_string);
result_array = tokenizer.SplitUpByDelimiter(" ");
ASSERT result.size() IS 4;
ASSERT result[0] IS "1";
ASSERT result[1] IS "2";
ASSERT result[2] IS "test";
ASSERT result[3] IS "bar";
}
ঠিক আছে, এখন আসুন আমরা প্রয়োজনীয়তাগুলি পরিবর্তন করে বলি, এবং টোকেনাইজিং আরও জটিল হয়ে ওঠে। আপনি সিদ্ধান্ত নিয়েছেন যে একটি সরল স্ট্রিং ডিলিমিটার পর্যাপ্ত হবে না এবং Delimiter
কাজটি পরিচালনা করার জন্য আপনার ক্লাসের প্রয়োজন । স্বাভাবিকভাবেই, আপনি একটি পরীক্ষা ভাঙ্গার আশা করতে যাচ্ছেন, তবে আপনি যখন ব্যক্তিগত কাজগুলি পরীক্ষা করেন তখন সেই ব্যথা বাড়তে থাকে।
ব্যক্তিগত পদ্ধতি পরীক্ষা করা কখন উপযুক্ত হতে পারে?
সফ্টওয়্যারটিতে কোনও "এক আকারের ফিট করে না"। কখনও কখনও "নিয়মগুলি ভঙ্গ করা" ঠিক আছে (এবং প্রকৃত পক্ষে আদর্শ)। আপনি যখন পারেন তখন ব্যক্তিগত কার্যকারিতা পরীক্ষা না করার দৃ strongly়তার সাথে আমি সমর্থন করছি। দু'টি প্রধান পরিস্থিতি যখন আমি মনে করি এটি ঠিক আছে:
আমি লিগ্যাসি সিস্টেমগুলির সাথে ব্যাপকভাবে কাজ করেছি (যার কারণেই আমি এত বড় মাইকেল মাদার পাখার অনুরাগী), এবং আমি নিরাপদে বলতে পারি যে কখনও কখনও কেবল ব্যক্তিগত কার্যকারিতা পরীক্ষা করা কেবল নিরাপদ। এটি বেসলাইনে "চরিত্রায়ন পরীক্ষা" পাওয়ার জন্য বিশেষভাবে সহায়ক হতে পারে।
আপনি খুব তাড়াহুড়োয় রয়েছেন এবং এখানে এবং এখনকার পক্ষে দ্রুততম কাজটি করতে হবে। দীর্ঘ সময়, আপনি ব্যক্তিগত পদ্ধতি পরীক্ষা করতে চান না। তবে আমি বলব যে ডিজাইনের সমস্যাগুলি সমাধান করতে সাধারণত অ্যাক্টারে কিছু সময় লাগে। এবং কখনও কখনও আপনাকে এক সপ্তাহের মধ্যে জাহাজে দিতে হয়। এটি ঠিক আছে: দ্রুত এবং নোংরা কাজটি করুন এবং গ্রপিংয়ের সরঞ্জামটি ব্যবহার করে ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করুন যদি আপনি মনে করেন কাজটি সম্পাদন করার দ্রুততম এবং সবচেয়ে নির্ভরযোগ্য উপায়। তবে বুঝতে পারেন যে আপনি যা করেছেন তা দীর্ঘকালীন সময়ে সাবঅপটিমাল ছিল এবং দয়া করে এটির দিকে ফিরে আসার বিষয়টি বিবেচনা করুন (বা, যদি এটি ভুলে গিয়েছিল তবে আপনি এটি পরে দেখেন তবে ঠিক করুন)।
সম্ভবত অন্যান্য পরিস্থিতি রয়েছে যেখানে এটি ঠিক আছে। আপনি যদি মনে করেন এটি ঠিক আছে, এবং আপনার একটি ভাল ন্যায়সঙ্গততা রয়েছে, তবে এটি করুন। কোন এক আপনি বাঁধন। কেবল সম্ভাব্য ব্যয় সম্পর্কে সচেতন হন।
টিডিডি এক্সকিউজ
একদিকে যেমন, আমি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষার অজুহাত হিসাবে টিডিডি ব্যবহার করি তা আমি পছন্দ করি না। আমি টিডিডি অনুশীলন করি, এবং আমার মনে হয় না টিডিডি আপনাকে এটি করতে বাধ্য করে। আপনি প্রথমে আপনার পরীক্ষাটি (আপনার পাবলিক ইন্টারফেসের জন্য) লিখতে পারেন এবং তারপরে সেই ইন্টারফেসটি সন্তুষ্ট করার জন্য কোড লিখতে পারেন। কখনও কখনও আমি একটি পাবলিক ইন্টারফেসের জন্য একটি পরীক্ষা লিখি, এবং আমি পাশাপাশি দুটি বা দুটি ছোট ব্যক্তিগত পদ্ধতি লিখে এটি সন্তুষ্ট করব (তবে আমি সরাসরি ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করি না, তবে আমি জানি তারা কাজ করে বা আমার পাবলিক পরীক্ষা ব্যর্থ হবে) )। যদি আমাকে সেই ব্যক্তিগত পদ্ধতির প্রান্তের কেসগুলি পরীক্ষা করার দরকার হয়, তবে আমি সম্পূর্ণ গোটা পরীক্ষাগুলি লিখব যা সেগুলি আমার সার্বজনীন ইন্টারফেসের মাধ্যমে আঘাত করবে।আপনি যদি প্রান্তের কেসগুলি কীভাবে আঘাত করতে পারেন তা বুঝতে না পারলে, এটি একটি শক্তিশালী লক্ষণ যা আপনার নিজের পাবলিক পদ্ধতিতে প্রতিটি ছোট উপাদানগুলিতে রিফ্যাক্টর করতে হবে। এটি এমন একটি চিহ্ন যা আপনি ব্যক্তিগত ফাংশনগুলি খুব বেশি করছেন এবং শ্রেণির আওতার বাইরে ।
এছাড়াও, কখনও কখনও আমি দেখতে পাই যে এই মুহুর্তে চাবানোর মতো কামড়ের চেয়ে খুব বড় একটি পরীক্ষা লিখি এবং তাই আমি মনে করি "আহ আমি পরে এই পরীক্ষায় ফিরে আসব যখন আমার সাথে আরও কিছু এপিআই কাজ করবে" (I 'এটি মন্তব্য করব এবং এটি আমার মনের পিছনে রাখব)। এখানেই আমি প্রচুর ডেভস মিলিয়েছি এবং তাদের ব্যক্তিগত কার্যকারিতার জন্য টেডিটি লিখতে শুরু করব, টিডিডি কে বধ্যভূমি হিসাবে ব্যবহার করব। তারা বলে "ওহ, ভাল আমার আরও কিছু পরীক্ষা দরকার, তবে সেই পরীক্ষাটি লেখার জন্য আমার এই ব্যক্তিগত পদ্ধতিগুলির প্রয়োজন হবে Therefore সুতরাং, যেহেতু আমি পরীক্ষা না লিখে কোনও প্রোডাকশন কোড লিখতে পারি না, তাই আমাকে একটি পরীক্ষা লিখতে হবে একটি ব্যক্তিগত পদ্ধতির জন্য। " তবে তাদের সত্যিকারের যা করা দরকার তা হ'ল তাদের বর্তমান শ্রেণিতে প্রাইভেট পদ্ধতিগুলির গুচ্ছ যোগ / পরীক্ষার পরিবর্তে ছোট এবং পুনরায় ব্যবহারযোগ্য উপাদানগুলিতে রিফ্যাক্টর করা।
বিঃদ্রঃ:
আমি কিছুক্ষণ আগে গুগল টেস্ট ব্যবহার করে ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করার অনুরূপ প্রশ্নের উত্তর দিয়েছি । আমি বেশিরভাগ উত্তরটি এখানে আরও ভাষা অজ্ঞায়নের জন্য পরিবর্তন করেছি।
পিএস এখানে আইসবার্গ ক্লাস এবং মাইকেল পালক দ্বারা গ্রোপিং সরঞ্জাম সম্পর্কে প্রাসঙ্গিক বক্তৃতা: https://www.youtube.com/watch?v=4cVZvoFGJTU