এখানে আমার পদ্ধতির। সময়ের সাথে এটির ব্যয় হয়েছে কারণ এটি 4 টি পর্যায়ক্রমে রিফেক্টর-পরীক্ষা।
আমি যা প্রকাশ করতে যাচ্ছি তাতে প্রশ্নের জটিলতার চেয়ে আরও জটিলতার সাথে উপাদানগুলিতে আরও ভাল স্যুট হতে পারে।
যাইহোক কৌশলটি কোনও ইন্টারফেস (ডিএও, পরিষেবাদি, নিয়ন্ত্রণকারী, ...) দ্বারা সাধারণকরণের জন্য কোনও উপাদান প্রার্থীর পক্ষে বৈধ।
1. ইন্টারফেস
মাই ডকুমেন্টস সার্ভিস থেকে সমস্ত পাবলিক পদ্ধতি সংগ্রহ করতে দেয় এবং সেগুলি একসাথে একটি ইন্টারফেসে রাখি। এই ক্ষেত্রে. এটি ইতিমধ্যে বিদ্যমান থাকলে, কোনও নতুন সেট করার পরিবর্তে সেটি ব্যবহার করুন ।
public interface DocumentService {
List<Document> getAllDocuments();
//more methods here...
}
তারপরে আমরা মাইডোকামেন্টস সার্ভিসকে এই নতুন ইন্টারফেসটি প্রয়োগ করতে বাধ্য করি ।
এ পর্যন্ত সব ঠিকই. কোনও বড় পরিবর্তন আনা হয়নি, আমরা বর্তমান চুক্তিকে সম্মান জানাই এবং আচরণগুলি অচেনা থেকে যায়।
public class MyDocumentService implements DocumentService {
@Override
public List<Document> getAllDocuments(){
//legacy code here as it is.
// with no changes ...
}
}
2. উত্তরাধিকার কোড ইউনিট পরীক্ষা
এখানে আমাদের কঠোর পরিশ্রম আছে। একটি পরীক্ষা স্যুট সেট আপ করতে। আমাদের যতটা সম্ভব কেস সেট করা উচিত: সফল মামলা এবং ত্রুটির ক্ষেত্রেও। এগুলি সর্বশেষ ফলাফলের মানের জন্য রয়েছে।
এখন, মাইডোকামেন্টস সার্ভিস পরীক্ষা করার পরিবর্তে আমরা ইন্টারফেসটি চুক্তি হিসাবে পরীক্ষা করার জন্য ব্যবহার করতে যাচ্ছি।
আমি বিশদে যাচ্ছি না, তাই যদি আমার কোডটি খুব সাধারণ বা খুব অজ্ঞানময় মনে হয় তবে আমাকে ক্ষমা করুন
public class DocumentServiceTestSuite {
@Mock
MyDependencyA mockDepA;
@Mock
MyDependencyB mockDepB;
//... More mocks
DocumentService service;
@Before
public void initService(){
service = MyDocumentService(mockDepA, mockDepB);
//this is purposed way to inject
//dependencies. Replace it with one you like more.
}
@Test
public void getAllDocumentsOK(){
// here I mock depA and depB
// wanted behaivors...
List<Document> result = service.getAllDocuments();
Assert.assertX(result);
Assert.assertY(result);
//... As many you think appropiate
}
}
এই পর্যায়ে এই পদ্ধতির অন্য যে কোনও সময়ের চেয়ে বেশি সময় নেয়। এবং এটি সর্বাধিক গুরুত্বপূর্ণ কারণ এটি ভবিষ্যতের তুলনার জন্য বিন্দুটি সেট করবে।
দ্রষ্টব্য: কোনও বড় পরিবর্তন করার কারণে এবং আচরণটি অচেনা থেকে যায়। আমি এসসিএম-এ এখানে একটি ট্যাগ করার পরামর্শ দিই। ট্যাগ বা শাখা কোনও বিষয় নয়। শুধু একটি সংস্করণ না।
আমরা এটি রোলব্যাকস, সংস্করণগুলির তুলনাগুলির জন্য চাই এবং এটি পুরানো কোড এবং নতুনটির সমান্তরাল মৃত্যুদন্ডের জন্য হতে পারে।
৩. রিফ্যাক্টরিং
রিফ্যাক্টর একটি নতুন উপাদান হিসাবে বাস্তবায়ন হতে চলেছে। আমরা বিদ্যমান কোডটিতে কোনও পরিবর্তন করব না। যেমন কপি ও পেস্ট করতে প্রথম পদক্ষেপ হিসেবে সহজ MyDocumentService এবং তা নামান্তর CustomDocumentService (উদাহরণস্বরূপ)।
নতুন ক্লাস ডকুমেন্ট সার্ভিস বাস্তবায়ন করতে থাকে । তারপরে যান এবং সমস্ত ডকুমেন্টস () এ রিফ্যাক্টরিজ করুন । (এক সাথে শুরু করা যাক। পিন-রিফ্যাক্টর)
ডিএওর ইন্টারফেস / পদ্ধতিতে এটির জন্য কিছু পরিবর্তন প্রয়োজন হতে পারে। যদি তা হয় তবে বিদ্যমান কোডটি পরিবর্তন করবেন না। ডিএও ইন্টারফেসে আপনার নিজস্ব পদ্ধতি প্রয়োগ করুন। পুরনো কোড অ্যানোটেট্ অসমর্থিত এবং আপনি পরে কি সরিয়েছেন করা উচিত জানতে হবে।
বিদ্যমান বাস্তবায়ন ভঙ্গ / পরিবর্তন না করা গুরুত্বপূর্ণ। আমরা উভয় পরিষেবা সমান্তরালভাবে কার্যকর করতে এবং তারপরে ফলাফলগুলি তুলনা করতে চাই।
public class CustomDocumentService implements DocumentService {
@Override
public List<Document> getAllDocuments(){
//new code here ...
//due to im refactoring service
//I do the less changes possible on its dependencies (DAO).
//these changes will come later
//and they will have their own tests
}
}
4. ডকুমেন্টসোর্সেসটেষ্টসুট আপডেট করা
ঠিক আছে, এখন সহজ অংশ। নতুন উপাদানগুলির পরীক্ষা যুক্ত করতে add
public class DocumentServiceTestSuite {
@Mock
MyDependencyA mockDepA;
@Mock
MyDependencyB mockDepB;
DocumentService service;
DocumentService customService;
@Before
public void initService(){
service = MyDocumentService(mockDepA, mockDepB);
customService = CustomDocumentService(mockDepA, mockDepB);
// this is purposed way to inject
//dependencies. Replace it with the one you like more
}
@Test
public void getAllDocumentsOK(){
// here I mock depA and depB
// wanted behaivors...
List<Document> oldResult = service.getAllDocuments();
Assert.assertX(oldResult);
Assert.assertY(oldResult);
//... As many you think appropiate
List<Document> newResult = customService.getAllDocuments();
Assert.assertX(newResult);
Assert.assertY(newResult);
//... The very same made to oldResult
//this is optional
Assert.assertEquals(oldResult,newResult);
}
}
এখন আমাদের কাছে পুরানো রেজাল্ট এবং নতুন ফলাফল দুটিই স্বতন্ত্রভাবে বৈধ হয়েছে তবে আমরা একে অপরের সাথে তুলনাও করতে পারি। এই শেষ বৈধতা alচ্ছিক এবং এটি ফলাফলের উপর নির্ভরশীল। এটি তুলনাযোগ্য নাও হতে পারে।
এইভাবে দুটি সংগ্রহের তুলনা করার জন্য খুব বেশি সাডেস না তৈরি করতে পারে তবে অন্য যে কোনও ধরণের অবজেক্টের (পজোস, ডেটা মডেল সত্তা, ডিটিও, র্যাপার্স, নেটিভ টাইপস) এর জন্য এটি বৈধ হবে)
নোট
আমি ইউনিট টেস্টগুলি কীভাবে করব বা মক ল্যাবগুলি কীভাবে ব্যবহার করব তা বলার সাহস করব না। আপনার কীভাবে চুল্লিটি করতে হবে তা বলার মতো সাহসও আমি করি না। আমি যা করতে চেয়েছিলাম তা হ'ল একটি বৈশ্বিক কৌশল প্রস্তাব করা। কীভাবে এটি এগিয়ে নেওয়া যায় তা আপনার উপর নির্ভর করে। আপনি কোডটি ঠিক কীভাবে জানেন, এর জটিলতা এবং যদি এমন কৌশলটি চেষ্টা করার মতো হয়। সময় এবং সংস্থান সম্পর্কিত বিষয়গুলি এখানে গুরুত্বপূর্ণ। ভবিষ্যতে এই পরীক্ষাগুলি থেকে আপনি কী প্রত্যাশা করেন তাও গুরুত্বপূর্ণ।
আমি একটি উদাহরণ দিয়ে আমার উদাহরণগুলি শুরু করেছি এবং আমি ডিএও এবং এর সাথে অনুসরণ করব। নির্ভরতা স্তরের গভীরে চলে যাওয়া। কমবেশি এটি আপ-ডাউন কৌশল হিসাবে বর্ণনা করা যেতে পারে । তবে ছোটখাটো পরিবর্তন / পুনরুদ্ধারকারীদের ( ট্যুরের উদাহরণে যেমনটি উদ্ঘাটিত করা হয়েছে ) এর জন্য, নীচের অংশটি কাজটি আরও সহজ করে দেয়। কারণ পরিবর্তনের সুযোগ কম।
অবশেষে, অবহেলিত কোডটি সরিয়ে ফেলা এবং পুরানো নির্ভরতা নতুনকে পুনর্নির্দেশ করা আপনার পক্ষে।
অবচয় পরীক্ষাগুলিও সরান এবং কাজ শেষ হয়। আপনি যদি পুরানো সমাধানটিকে এর পরীক্ষাগুলির সাথে সংস্করণিত করেন তবে আপনি যে কোনও সময় একে অপরের সাথে চেক এবং তুলনা করতে পারেন।
এতগুলি কাজের ফলস্বরূপ, আপনার লিগ্যাসি কোড পরীক্ষা করা হয়েছে, যাচাইকৃত এবং সংস্করণ রয়েছে। এবং নতুন কোড, পরীক্ষিত, যাচাইকৃত এবং সংস্করণে প্রস্তুত।