ইউনিট টেস্টিং অ্যাপ্লিকেশন লজিক এবং অবিশ্বাস্য ভাষা গঠনগুলির মধ্যে রেখাটি কোথায়?


87

এর মতো একটি কার্যকারিতা বিবেচনা করুন:

function savePeople(dataStore, people) {
    people.forEach(person => dataStore.savePerson(person));
}

এটি এটির মতো ব্যবহৃত হতে পারে:

myDataStore = new Store('some connection string', 'password');
myPeople = ['Joe', 'Maggie', 'John'];
savePeople(myDataStore, myPeople);

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

করা উচিত savePeople()ইউনিট পরীক্ষা করা, বা এই ধরনের পরীক্ষার বিল্ট-ইন পরীক্ষা পরিমাণ হবে forEachভাষা গঠন করা?

আমরা অবশ্যই একটি বিদ্রূপের মধ্যে দিয়ে যেতে পারি dataStoreএবং dataStore.savePerson()প্রতিটি ব্যক্তির জন্য একবার ডেকে আনা দৃ .়তা দিতে পারি । আপনি অবশ্যই যুক্তি দিতে পারেন যে এই জাতীয় পরীক্ষা বাস্তবায়ন পরিবর্তনের বিরুদ্ধে সুরক্ষা প্রদান করে: উদাহরণস্বরূপ, যদি আমরা forEachএকটি traditional forতিহ্যগত লুপ, বা পুনরুক্তির কোনও অন্য পদ্ধতি প্রতিস্থাপনের সিদ্ধান্ত নিয়েছিলাম । সুতরাং পরীক্ষাটি সম্পূর্ণ তুচ্ছ নয়। এবং এখনও এটি অত্যন্ত ভয়ঙ্কর মনে হচ্ছে ...


আরও ফলদায়ক হতে পারে এমন আরও একটি উদাহরণ এখানে। এমন একটি ফাংশন বিবেচনা করুন যা অন্যান্য অবজেক্টস বা ফাংশনগুলির সমন্বয় ছাড়া কিছুই করে না। উদাহরণ স্বরূপ:

function bakeCookies(dough, pan, oven) {
    panWithRawCookies = pan.add(dough);
    oven.addPan(panWithRawCookies);
    oven.bakeCookies();
    oven.removePan();
}

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

অর্থবহ ব্ল্যাক বক্স উপায়ে ফাংশনটি পরীক্ষা করতে এই অক্ষমতা কি ফাংশনটির সাথেই কোনও ডিজাইনের ত্রুটি চিহ্নিত করে? যদি তা হয় তবে কীভাবে এটি উন্নত করা যায়?


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

যখন কোনও ব্যবহারকারী একটি নতুন অ্যাকাউন্ট তৈরি করে, তখন অনেকগুলি জিনিস হওয়া দরকার: 1) ডাটাবেজে নতুন ব্যবহারকারী রেকর্ড তৈরি করা দরকার 2) একটি স্বাগত ইমেল প্রেরণ করা প্রয়োজন 3) ব্যবহারকারীর আইপি ঠিকানা জালিয়াতির জন্য রেকর্ড করা দরকার উদ্দেশ্য।

সুতরাং আমরা একটি পদ্ধতি তৈরি করতে চাই যা সমস্ত "নতুন ব্যবহারকারী" পদক্ষেপের সাথে একত্রিত হয়:

function createNewUser(validatedUserData, emailService, dataStore) {
  userId = dataStore.insertUserRecord(validateduserData);
  emailService.sendWelcomeEmail(validatedUserData);
  dataStore.recordIpAddress(userId, validatedUserData.ip);
}

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

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


44
এটি চালানোর পরে। আপনার কি কুকি রয়েছে
ইওয়ান

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

11
দিনের শেষে, এখানে কাজের মূলনীতিটি হ'ল কোডটি কাজ করে তা নিশ্চিত করার জন্য আপনি পর্যাপ্ত পরীক্ষাগুলি লিখেন এবং কেউ যখন কিছু পরিবর্তন করে তখন এটি পর্যাপ্ত "কয়লা খনিতে ক্যানারি"। এটাই. কোনও magন্দ্রজালিক প্রবণতা, সূত্রমূলক ধারণা বা গোপনীয় বক্তব্য নেই, যার কারণে 85% থেকে 90% কোড কভারেজ (100% নয়) ব্যাপকভাবে দুর্দান্ত হিসাবে বিবেচিত হয়
রবার্ট হার্ভে

5
@ রবার্টহারভে দুর্ভাগ্যক্রমে সূত্রপূর্ণ প্ল্যাটিটিউডস এবং টিডিডি শব্দের কামড়, যদিও আপনাকে উত্সাহী চুক্তির উত্সাহ দেয়, বাস্তব-বিশ্ব সমস্যা সমাধানে সহায়তা করবেন না।
জোনা

4
চক্রবৃত্তীয় জটিলতা হ্রাসের ক্রমে ইউনিট পরীক্ষা। আমাকে বিশ্বাস করুন, আপনি এই
ফাংশনটিতে

উত্তর:


118

করা উচিত savePeople()ইউনিট পরীক্ষা করা? হ্যাঁ. আপনি পরীক্ষা করছেন না যে dataStore.savePersonকাজ করে, বা যে ডিবি সংযোগ কাজ করে, বা এমনকি এটিও কাজ foreachকরে। আপনি এটি পরীক্ষা করছেন যা savePeopleএটি তার চুক্তির মাধ্যমে প্রতিশ্রুতি পূর্ণ করে।

এই দৃশ্যের কল্পনা করুন: কেউ কোড বেসের একটি বড় রিফ্যাক্টর করেন এবং দুর্ঘটনাক্রমে forEachবাস্তবায়নের অংশটি সরিয়ে ফেলেন যাতে এটি সর্বদা প্রথম আইটেমটি কেবল সংরক্ষণ করে। আপনি একটি ইউনিট পরীক্ষা এটি ধরতে চান না?


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

64
"আপনি পরীক্ষা করছেন যে সেভপিয়োল তার চুক্তির মাধ্যমে প্রতিশ্রুতি পূর্ণ করেছে fulf" এই. এই এত।
লভিস

2
আপনার যদি "এন্ড টু এন্ড" সিস্টেম পরীক্ষা না করে থাকে যা এটি কভার করে।
আয়ান

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

4
@ ভিনসেন্টস্যাওয়ার্ড, তবে ইউনিট পরীক্ষার ব্যয় / সুবিধা হ্রাস পাবে যদি ঝুঁকিটি যদি আন্তর উপায়ে নিয়ন্ত্রণ করা হয়।
আয়ান

36

সাধারণত যখন মানুষ "পরীক্ষার পরে" বিকাশ করে তখন এই ধরণের প্রশ্ন আসে। টিডিডির দৃষ্টিকোণ থেকে এই সমস্যাটির দিকে যান, যেখানে প্রয়োগের আগে পরীক্ষাগুলি আসে এবং অনুশীলন হিসাবে নিজেকে আবার এই প্রশ্ন জিজ্ঞাসা করুন।

কমপক্ষে আমার টিডিডি-র প্রয়োগে, যা সাধারণত বাইরে-বাইরে থাকে, আমি প্রয়োগ করার savePeopleপরে কোনও ফাংশন বাস্তবায়ন করব না savePersonsavePeopleএবং savePersonফাংশন এক হিসাবে শুরু করবেন এবং একই ইউনিট পরীক্ষা থেকে পরীক্ষা চালিত হচ্ছে; উভয় মধ্যে বিচ্ছেদ কয়েক পরীক্ষার পরে উত্থাপিত হবে, রিফ্যাক্টরিং পদক্ষেপে। কাজের এই মোডটি এই প্রশ্নটিও উত্থাপন করবে যে ফাংশনটি কোথায় savePeopleহওয়া উচিত - এটি কোনও ফ্রি ফাংশন বা এর অংশ কিনা dataStore

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

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


4
মূলত ইন্টারফেসটি পরীক্ষা করুন, বাস্তবায়ন নয়।
স্নুপ

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

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

আপডেটের জন্য ধন্যবাদ. আপনি ঠিক কিভাবে পরীক্ষা করবেন savePeople? আমি ওপি বা অন্য কোনও উপায়ে শেষ অনুচ্ছেদে বর্ণনা করেছি?
জোনাহ

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

21

SavePeople () এর ইউনিট পরীক্ষা করা উচিত

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

function testSavePeople() {
    myDataStore = new Store('some connection string', 'password');
    myPeople = ['Joe', 'Maggie', 'John'];
    savePeople(myDataStore, myPeople);
    assert(myDataStore.containsPerson('Joe'));
    assert(myDataStore.containsPerson('Maggie'));
    assert(myDataStore.containsPerson('John'));
}

এই পরীক্ষাটি একাধিক জিনিস করে:

  • এটি ফাংশনের চুক্তি যাচাই করে savePeople()
  • এটি বাস্তবায়নের বিষয়ে চিন্তা করে না savePeople()
  • এটি উদাহরণ ব্যবহারের দলিল করে savePeople()

মনে রাখবেন যে আপনি এখনও স্টোরটিকে স্টক / স্টাব / নকল করতে পারেন। এই ক্ষেত্রে আমি সুস্পষ্ট ফাংশন কলগুলি পরীক্ষা করব না, তবে অপারেশনের ফলাফলের জন্য। এইভাবে আমার পরীক্ষা ভবিষ্যতের পরিবর্তনগুলি / পুনরুদ্ধারকারীদের জন্য প্রস্তুত।

উদাহরণস্বরূপ, আপনার ডেটা স্টোর বাস্তবায়ন saveBulkPerson()ভবিষ্যতে কোনও পদ্ধতি সরবরাহ করতে পারে - এখন savePeople()ব্যবহারের বাস্তবায়নের পরিবর্তনটি saveBulkPerson()ইউনিট পরীক্ষা যতক্ষণ saveBulkPerson()প্রত্যাশা অনুযায়ী কাজ করবে না ভাঙবে । এবং যদি saveBulkPerson()কোনওরকম প্রত্যাশার মতো কাজ না করে তবে আপনার ইউনিট পরীক্ষাটি এটি ধরবে।

বা এই জাতীয় পরীক্ষাগুলি প্রতিটি ভাষার নির্মাণের জন্য অন্তর্নির্মিত পরীক্ষার পরিমাণ হবে?

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

আপনার প্রশ্নের আপডেট সম্পর্কে:

রাষ্ট্র পরিবর্তনের পরীক্ষা! যেমন ময়দার কিছু ব্যবহার করা হবে। আপনার বাস্তবায়ন অনুসারে, জোর দিয়ে বলুন যে ব্যবহারের পরিমাণটি doughফিট করে panবা doughএটি ব্যবহৃত হয়েছে তা জোড় করে। দাবী করে যে, panফাংশন কল পর কুকিজ ধারণ করে। পূর্বের মতো ovenখালি / একই অবস্থায় রয়েছে তা জোর দিয়ে দিন।

অতিরিক্ত পরীক্ষার জন্য, প্রান্তের মামলাগুলি যাচাই করুন: ovenকল করার আগে যদি খালি না থাকে তবে কী ঘটবে ? পর্যাপ্ত পরিমাণ না থাকলে কী হয় dough? যদি panইতিমধ্যে পূর্ণ হয়?

ময়দা, প্যান এবং চুলা বস্তু থেকে এই পরীক্ষাগুলির জন্য প্রয়োজনীয় সমস্ত ডেটা আপনি সরিয়ে নিতে সক্ষম হবেন। ফাংশন কলগুলি ক্যাপচার করার দরকার নেই। ফাংশনটি এমন আচরণ করুন যেন এর বাস্তবায়ন আপনার কাছে পাওয়া না যায়!

আসলে, বেশিরভাগ টিডিডি ব্যবহারকারীরা ফাংশনটি লেখার আগে তাদের পরীক্ষাগুলি লেখেন যাতে তারা প্রকৃত বাস্তবায়নের উপর নির্ভর করে না dependent


আপনার সর্বশেষ সংযোজনের জন্য:

যখন কোনও ব্যবহারকারী একটি নতুন অ্যাকাউন্ট তৈরি করে, তখন অনেকগুলি জিনিস হওয়া দরকার: 1) ডাটাবেজে নতুন ব্যবহারকারী রেকর্ড তৈরি করা দরকার 2) একটি স্বাগত ইমেল প্রেরণ করা প্রয়োজন 3) ব্যবহারকারীর আইপি ঠিকানা জালিয়াতির জন্য রেকর্ড করা দরকার উদ্দেশ্য।

সুতরাং আমরা একটি পদ্ধতি তৈরি করতে চাই যা সমস্ত "নতুন ব্যবহারকারী" পদক্ষেপের সাথে একত্রিত হয়:

function createNewUser(validatedUserData, emailService, dataStore) {
    userId = dataStore.insertUserRecord(validateduserData);
    emailService.sendWelcomeEmail(validatedUserData);
    dataStore.recordIpAddress(userId, validatedUserData.ip);
}

এই আমি উপহাস করবে / শহরের উপর অসম্পূর্ণ নিবন্ধ / জাল মত একটি ফাংশন (যাই হোক না কেন আরো সাধারণ বলে মনে হয়) এর জন্য dataStoreএবং emailServiceপ্যারামিটার। এই ফাংশনটি নিজেই কোনও পরামিতিগুলিতে কোনও রাষ্ট্রীয় স্থানান্তর করে না, এটি তাদের কয়েকটি পদ্ধতির জন্য তাদেরকে অর্পণ করে। আমি যাচাই করতে চেষ্টা করব যে ফাংশনে কলটি 4 টি কাজ করেছে:

  • এটি ডেটা স্টোরটিতে একটি ব্যবহারকারীর প্রবেশ করিয়েছে
  • এটি একটি স্বাগত ইমেল প্রেরণ করেছে (বা কমপক্ষে সংশ্লিষ্ট পদ্ধতিটিকে বলা হয়)
  • এটি ব্যবহারকারীদের আইপি ডাটা স্টোরের মধ্যে রেকর্ড করে
  • এটি যে কোনও ব্যতিক্রম / ত্রুটির মুখোমুখি হয়েছিল (যদি থাকে)

প্রথম 3 টি চেক মক, স্টাব বা নকল dataStoreএবং emailService(পরীক্ষার সময় আপনি সত্যিই ইমেলগুলি প্রেরণ করতে চান না) দিয়ে করা যেতে পারে। যেহেতু আমাকে কয়েকটি মন্তব্যের জন্য এটি সন্ধান করতে হয়েছিল, এই পার্থক্যগুলি:

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

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

প্রত্যাশিত ব্যতিক্রম / ত্রুটিগুলি বৈধ পরীক্ষার কেস: আপনি নিশ্চিত করেন যে এই জাতীয় ঘটনা ঘটলে ফাংশনটি আপনার প্রত্যাশা মতো আচরণ করে। এটি যখন চান তখন সংশ্লিষ্ট মক / নকল / স্টাব বস্তুকে ফেলে দিয়ে অর্জন করা যায়।

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

কখনও কখনও এটি করতে হবে (যদিও আপনি ইন্টিগ্রেশন পরীক্ষায় বেশিরভাগ ক্ষেত্রে এটি যত্নশীল হন)। প্রায়শই, প্রত্যাশিত পার্শ্ব প্রতিক্রিয়া / রাষ্ট্র পরিবর্তনগুলি যাচাই করার অন্যান্য উপায় রয়েছে।

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

দুঃখের বিষয়, সেই ক্ষেত্রে ইউনিট পরীক্ষাটি তার কিছু বিশ্বাসযোগ্যতা হারিয়ে ফেলে: যেহেতু এটি পরিবর্তন করা হয়েছিল, পরিবর্তনটি আগের মতো আচরণ করার পরে এটি কার্যকারিতাটি নিশ্চিত করে না।

উদাহরণস্বরূপ, oven.preheat()আপনার কুকি বেকিং উদাহরণে কাউকে (অনুকূলকরণ!) একটি কল যুক্ত করার বিষয়টি বিবেচনা করুন :

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

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


1
সমস্যাটি হ'ল লেখার সাথে সাথে myDataStore.containsPerson('Joe')আপনি কার্যকরী পরীক্ষার ডাটাবেসের অস্তিত্ব ধরে নিচ্ছেন। একবার আপনি এটি করার পরে, আপনি একটি ইউনিট পরীক্ষা নয় একটি ইন্টিগ্রেশন পরীক্ষা লিখছেন।
জোনাহ

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

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

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

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

13

এই জাতীয় পরীক্ষার প্রাথমিক মান হ'ল এটি আপনার বাস্তবায়নকে পুনরুদ্ধারযোগ্য করে তোলে।

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

অন্যদিকে, আমরা অকালকালীনভাবে অপটিমাইজ করতে চাই না either আপনি যদি একসাথে কেবলমাত্র 1 - 3 জনকে সঞ্চয় করেন তবে একটি অনুকূলিত ব্যাচ লিখতে ওভারকিল হতে পারে।

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

এই আচরণের পরীক্ষার একক করার দ্বিতীয়টি হ'ল তার উদ্দেশ্য কী তা জন্য ডকুমেন্টেশন হিসাবে পরিবেশন করা। এই তুচ্ছ উদাহরণটি সুস্পষ্ট হতে পারে, তবে নীচের পরের বিষয়টি দেওয়া, এটি খুব গুরুত্বপূর্ণ হতে পারে।

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

আমি একটি চিন্তা যুক্ত করব যা আমি একটি টিডিডি প্রশিক্ষকের কাছ থেকে পেয়েছি। পদ্ধতিটি পরীক্ষা করবেন না। আচরণ পরীক্ষা করুন। অন্য কথায়, আপনি যে পরীক্ষা করে তা পরীক্ষা করেন না savePeople, আপনি পরীক্ষা করছেন যে একাধিক ব্যবহারকারীর একক কলে সংরক্ষণ করা যায়।

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


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

1
@ jpmc26 এমন একটি পরীক্ষার বিষয়ে যা পরীক্ষা করে যে লোকেরা রক্ষা পেয়েছিল ...?
ইমিগ্রিস

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

1
@ ইমিবিস আমি এটিকে একটি কার্যকর পরীক্ষা হিসাবে বিবেচনা করি না। জাল ডেটা স্টোর ব্যবহার করা আমাকে কোনও আত্মবিশ্বাস দেয় না এটি আসল জিনিসটির সাথে কাজ করবে। আসল জিনিসের মতো আমার জাল কাজগুলি কীভাবে জানব? আমি বরং কেবল একটি সংহত পরীক্ষার একটি স্যুট এটি কভার করতে দেব। (আমার সম্ভবত এখানে পরিষ্কার মন্তব্য করা উচিত যে আমি এখানে আমার প্রথম মন্তব্যে "যে কোনও ইউনিট পরীক্ষা" বলতে
চাইছিলাম

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

6

পরীক্ষা bakeCookies()করা উচিত ? হ্যাঁ.

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

আসলে তা না. ফাংশনটি কী করণীয় তা নিবিড়ভাবে দেখুন - এটি ovenঅবজেক্টটিকে একটি নির্দিষ্ট স্থিতিতে সেট করার কথা । কোডটির দিকে তাকালে এটি প্রদর্শিত হয় যে বস্তু panএবং doughবস্তুর রাজ্যগুলি আসলে খুব বেশি গুরুত্ব দেয় না। সুতরাং আপনার কোনও ovenঅবজেক্ট পাস করা উচিত (বা এটি উপহাস করুন) এবং ফাংশন কল শেষে এটি একটি নির্দিষ্ট অবস্থানে রয়েছে তা জোর করে।

অন্য কথায়, আপনার দাবি করা উচিত bakeCookies()যা কুকিগুলিকে বেকড করেছে

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

ইউনিট পরীক্ষা দুটি ফাংশন পরিবেশন করে:

  1. এটি পরীক্ষা করে যে সবকিছু কাজ করে। এটি সর্বনিম্ন কার্যকর ফাংশন ইউনিট পরীক্ষাগুলি পরিবেশন করে এবং মনে হয় প্রশ্নটি জিজ্ঞাসা করার সময় আপনি কেবল এই কার্যকারিতাটি বিবেচনা করবেন।

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

ফাংশনের ভিতরে কোডটি পরীক্ষা করবেন না। পরিবর্তে পরীক্ষা করুন যে ফাংশন এটি যা বলে তা যা করে। আপনি যখন ইউনিট পরীক্ষাগুলি এইভাবে দেখেন (টেস্টিং ফাংশনগুলি, কোড নয়) তখন আপনি বুঝতে পারবেন যে আপনি কখনই ভাষা গঠন বা প্রয়োগের যুক্তি পরীক্ষা করেন না। আপনি একটি এপিআই পরীক্ষা করছেন।


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

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

@ জেমস_পিক, ঠিক এবং হ্যাঁ, এটি আমি ব্যবহার করছি মক সংজ্ঞা। সুতরাং আপনার মন্তব্য দেওয়া, আপনি যেমন একটি ক্ষেত্রে কি করবেন? পরীক্ষা ছেড়ে দেবেন? ভঙ্গুর, বাস্তবায়ন-পুনরাবৃত্তি পরীক্ষা যাই হোক লিখুন? অন্যকিছু?
জোনাহ

@ জোনাঃ আমি সাধারণত ইন্টিগ্রেশন টেস্টের সাথে সেই উপাদানটি পরীক্ষা করে দেখব (সম্ভবত আধুনিক সরঞ্জামের গুণমানের কারণে সম্ভবত এটির উপরের দিকে চাপ দেওয়া কঠিন হয়ে পড়েছে বলে সতর্কতাটি পেয়েছি), বা একটি তৈরির সমস্যায় পড়ি আধা-বিশ্বাসযোগ্য জাল।
জেমস_পিক

3

সেভপিয়োপলগুলি () ইউনিট পরীক্ষা করা উচিত, না এই জাতীয় পরীক্ষাগুলি প্রতিটি ভাষা নির্মাণের জন্য অন্তর্নির্মিত পরীক্ষার পরিমাণ?

হ্যাঁ. কিন্তু আপনি পারে একটি উপায় যে শুধু কনস্ট্রাক্ট পুনঃপরীক্ষা করবে এটা করতে।

এখানে লক্ষ্য করার বিষয়টি হ'ল কোনও savePersonঅর্ধেক পথ ব্যর্থ হলে এই ফাংশনটি কীভাবে আচরণ করে? কীভাবে কাজ করার কথা?

এটি সূক্ষ্ম আচরণের ধরণের যা ফাংশনটি আপনাকে ইউনিট পরীক্ষার মাধ্যমে প্রয়োগ করা উচিত provides


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

@ জোনাঃ আপনি যদি নিজের ইউনিট পরীক্ষাটি কেবলমাত্র foreachনির্মাণের জন্য সীমাবদ্ধ রাখার জন্য জোর দিয়ে যাচ্ছেন , এবং এর বাইরে কোনও শর্ত, পার্শ্ব প্রতিক্রিয়া বা আচরণ নয় তবে আপনি ঠিক বলেছেন; নতুন ইউনিট পরীক্ষা আসলেই আকর্ষণীয় নয়।
রবার্ট হার্ভে

1
@ জোনাঃ - এটি কি পুনরাবৃত্তি করে যতটা সম্ভব সংরক্ষণ করা উচিত বা ত্রুটি বন্ধ করে দেওয়া উচিত? একক সংরক্ষণ এটি সিদ্ধান্ত নিতে পারে না , যেহেতু এটি কীভাবে এটি ব্যবহার হচ্ছে তা এটি জানেন না।
টেলাস্টিন

1
@ জোনাঃ সাইটে আপনাকে স্বাগতম। আমাদের Q & A- বিন্যাসের মূল উপাদান এক যে, আমরা এখানে সাহায্য করার জন্য নও আপনি । আপনার প্রশ্ন অবশ্যই আপনাকে সহায়তা করে তবে এটি সাইটটিতে আসা আরও অনেক লোককে তাদের প্রশ্নের উত্তর খুঁজতে সহায়তা করে। আপনার জিজ্ঞাসা প্রশ্নের উত্তর দিয়েছি। আপনি উত্তরটি পছন্দ না করলে বা গোলপোস্টগুলি স্থানান্তর করতে চান তবে এটি আমার দোষ নয়। এবং প্রকৃতপক্ষে, দেখে মনে হচ্ছে অন্যান্য উত্তরগুলি একই বুনিয়াদি কথা বলে, যদিও আরও স্পষ্টভাবে।
তেলস্তিন

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

3

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

একটি পরীক্ষা লেখা এত সহজ যে সত্যটি আপনার নকশাটি খারাপ নয়। আপনি কি এমন ডিজাইন পছন্দ করেন যা পরীক্ষা করা সহজ নয়?

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

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


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

1

সেভপিয়োপলগুলি () ইউনিট পরীক্ষা করা উচিত, না এই জাতীয় পরীক্ষাগুলি প্রতিটি ভাষা নির্মাণের জন্য অন্তর্নির্মিত পরীক্ষার পরিমাণ?

এটি ইতিমধ্যে @ ব্রায়ান ওকলি দ্বারা জবাব দেওয়া হয়েছে, তবে আমার কিছু অতিরিক্ত যুক্তি রয়েছে (আমার ধারণা):

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

দ্বিতীয়ত, আপনার পরীক্ষাটি ফাংশন পরিবর্তিত হলে আক্রমণকারীদের পরীক্ষা করার জন্য থাকবে । এখন এটি পরিবর্তিত হয় না এর অর্থ আপনার পরীক্ষা করা উচিত নয়।

তৃতীয়ত, টিডিডি পদ্ধতির (যা এটি আদেশ করে) এবং এর বাইরে উভয় ক্ষেত্রেই একটি তুচ্ছ পরীক্ষা প্রয়োগের মূল্য রয়েছে।

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


1

আমি মনে করি আপনার প্রশ্নটি এ পর্যন্ত ফুটে উঠেছে:

ইন্টিগ্রেশন টেস্ট না করে আমি কীভাবে শূন্য ফাংশনটি ইউনিট পরীক্ষা করব?

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

যদি ফাংশনটি কল করার পরে আমাদের প্যান.গটকুকিজকে কল করতে হয় তবে আমরা প্রশ্ন করতে পারি যদিও এটি 'সত্যই একটি ইন্টিগ্রেশন টেস্ট' বা 'তবে আমরা কেবল প্যান অবজেক্টটি পরীক্ষা করছি না?'

আমি মনে করি যে আপনি ঠাট্টা-বিদ্রূপযুক্ত সমস্ত কিছুর সাথে ইউনিট পরীক্ষা করা সঠিক এবং xy এবং z ফাংশন যাচাই করা অভাবের মান হিসাবে ডাকা হয় in

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

--- createNewUser উদাহরণের জন্য আপডেট করুন

  • ডাটাবেসে একটি নতুন ব্যবহারকারীর রেকর্ড তৈরি করা দরকার
  • একটি স্বাগত ইমেল প্রেরণ করা প্রয়োজন
  • জালিয়াতির উদ্দেশ্যে ব্যবহারকারীর আইপি ঠিকানা রেকর্ড করা দরকার।

ঠিক আছে তাই এবার ফাংশনের ফলাফল সহজেই ফিরে আসে না। আমরা পরামিতিগুলির স্থিতি পরিবর্তন করতে চাই।

এখানেই আমি কিছুটা বিতর্কিত হই। আমি রাষ্ট্রীয় পরামিতিগুলির জন্য কংক্রিট মক প্রয়োগগুলি তৈরি করি

দয়া করে প্রিয় পাঠকগণ, চেষ্টা করুন এবং আপনার ক্রোধ নিয়ন্ত্রণ করুন!

তাই ...

var validatedUserData = new UserData(); //we can use the real object for this
var emailService = new MockEmailService(); //a simple mock which saves sentEmails to a List<string>
var dataStore = new MockDataStore(); //a simple mock which saves ips to a List<string>

//run the test
target.createNewUser(validatedUserData, emailService, dataStore);

//check the results
Assert.AreEqual(1, emailService.EmailsSent.Count());
Assert.AreEqual(1, dataStore.IpsRecorded.Count());
Assert.AreEqual(1, dataStore.UsersSaved.Count());

এটি পরীক্ষার অধীনে পদ্ধতির বাস্তবায়ন বিবরণকে পছন্দসই আচরণ থেকে পৃথক করে। একটি বিকল্প বাস্তবায়ন:

function createNewUser(validatedUserData, emailService, dataStore) {
  userId = dataStore.bulkInsedrtUserRecords(new [] {validateduserData});
  emailService.addEmailToQueue(validatedUserData);
  emailService.ProcessQueue();
  dataStore.recordIpAddress(userId, validatedUserData.ip);
}

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


এটি কোনও সংহত পরীক্ষা নয় কেবল কারণ আপনি 2 টি কংক্রিট শ্রেণীর নাম উল্লেখ করেছেন ... ইন্টিগ্রেশন পরীক্ষাগুলি হ'ল ডিস্ক আইও, ডিবি, বাহ্যিক ওয়েব পরিষেবাদির মতো বাহ্যিক সিস্টেমের সাথে সংহতকরণের পরীক্ষা করা এবং প্যান.জেটকুকিজ () রয়েছে মেমরি, দ্রুত, আমাদের আগ্রহী জিনিসটির জন্য যাচাই করে নেয় I
সারা

3
অপেক্ষা করুন। সবার জন্য আমরা জানি প্যান.ব্যাটকুকিরা একটি কুককে একটি ইমেল প্রেরণ করে যখন তারা সুযোগ পেলে চুলা থেকে কুকিগুলি বের করে নিতে বলে
ইভান

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

2
এটি একটি অলৌকিক প্রশ্ন ছিল, কিন্তু: "ওভেন সরঞ্জামগুলি যে ইমেলগুলি প্রেরণ করেছিল সে সম্পর্কে কে কখনও শুনেছে?" venturebeat.com/2016/03/08/...
clacke

হাই ইয়ান, আমি মনে করি যে আমি সত্যিই যা জিজ্ঞাসা করছি তার উত্তরটি এতদূর নিকটে আসবে। আমার মনে bakeCookiesহয় বেকড কুকিজ ফিরিয়ে দেওয়ার বিষয়ে আপনার বক্তব্য স্পষ্ট , এবং এটি পোস্ট করার পরে আমার কিছুটা ভাবনা ছিল। সুতরাং আমি মনে করি এটি আবার কোনও দুর্দান্ত উদাহরণ নয়। আমি আরও একটি আপডেট যুক্ত করেছি যা আশাবাদী আমার প্রশ্নটি কী অনুপ্রেরণা দেয় তার আরও বাস্তব উদাহরণ প্রদান করে provides আমি আপনার ইনপুট প্রশংসা করি
জোনাহ

0

bakeCookiesআপনারও পরীক্ষা করা উচিত - bakeCookies(egg, pan, oven)ফলন কি / উচিত ? ভাজা ডিম নাকি ব্যতিক্রম? তাদের নিজেরাই, না উভয়ই আসল উপাদানগুলির বিষয়ে চিন্তা করবে panনা oven, যেহেতু তাদের কারওরই ধারণা করা হয় না, তবে bakeCookiesসাধারণত কুকিজ উত্পন্ন করা উচিত। আরো সাধারণভাবে এটা কিভাবে উপর নির্ভর করতে পারেন doughপ্রাপ্ত হয় এবং সেখানে কিনা হয় এটা নিছক হওয়ার কোনো সুযোগ eggবা যেমন waterপরিবর্তে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.