টেস্টিবিলিটির জন্য ডিজাইনের সময় স্থিতিশীল ইউটিলিটি ক্লাসগুলির সাথে কীভাবে ডিল করতে হয়


62

আমরা আমাদের সিস্টেমটি টেস্টযোগ্য এবং বেশিরভাগ অংশে টিডিডি ব্যবহার করে বিকশিত করার জন্য ডিজাইন করার চেষ্টা করছি। বর্তমানে আমরা নিম্নলিখিত সমস্যাটি সমাধান করার চেষ্টা করছি:

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

এই সমস্যাটি সমাধান করার জন্য আমার কাছে বেশ কয়েকটি ধারণা রয়েছে:

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

তবে আমি ভাবতে থাকি যে এটি টিডিডি করার সময় অনেক লোককেই सामना করতে হবে - সুতরাং ইতিমধ্যে এই সমস্যার সমাধান হতে হবে।

এই স্ট্যাটিক সহায়কদের পরীক্ষাযোগ্য করে এমন ক্লাসগুলি রাখার সর্বোত্তম কৌশল কী?


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

"বিশ্বাসযোগ্য এবং / অথবা অফিশিয়াল উত্স" কোনও প্রশ্নের জন্য একটি অনুগ্রহ শুরু করার সময় আপনি বেছে নিতে পারেন এমন একটি বিকল্প। আমি আসলে যা বোঝাতে চাইছি: টিডিডি বিশেষজ্ঞদের লেখা নিবন্ধগুলি থেকে অভিজ্ঞতা বা রেফারেন্স। বা একই সমস্যার মুখোমুখি হওয়া

উত্তর:


34

(এখানে কোনও "অফিসিয়াল" সূত্র নেই, আমি ভয় করি - কীভাবে ভালভাবে পরীক্ষা করা যায় তার নির্দিষ্টকরণের মতো নয় not আমার মতামত, যা আশাবাদী কার্যকর হবে))

এই স্থিতিশীল পদ্ধতিগুলি যখন আসল নির্ভরতা উপস্থাপন করে তখন মোড়ক তৈরি করুন। সুতরাং যেমন জিনিস জন্য:

  • ImageIO
  • এইচটিটিপি ক্লায়েন্ট (বা অন্য কোনও নেটওয়ার্ক-সম্পর্কিত)
  • ফাইল সিস্টেম
  • বর্তমান সময় পাওয়া (যেখানে নির্ভরতা ইনজেকশন সাহায্য করে সেখানে আমার প্রিয় উদাহরণ)

... এটি একটি ইন্টারফেস তৈরি করে তোলে।

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

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


20

এটি অবশ্যই একটি মতামতযুক্ত প্রশ্ন / উত্তর কিন্তু এটির জন্য আমি কীভাবে ভাবছিলাম যে আমি আমার দুটি সেন্ট নিক্ষেপ করব T টিডিডি শৈলী পদ্ধতি 2 এর নিরিখে অবশ্যই পত্রটি অনুসরণ করে এমন পন্থা is পদ্ধতি 2 এর পক্ষে যুক্তিটি হ'ল যদি আপনি কখনও সেই শ্রেণীর একটিটির বাস্তবায়নটি প্রতিস্থাপন করতে চেয়েছিলেন - একটি ImageIOসমমানের গ্রন্থাগার বলুন - তবে সেই কোডটি উত্সাহিত ক্লাসগুলির প্রতি আস্থা বজায় রেখে আপনি এটি করতে পারবেন।

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

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


1
একটি অতিরিক্ত সমস্যা যা সম্পর্কে আমি নির্ভর করে না: র‌্যাপারগুলি কার্যকর করার সময় আপনি কি আবৃত ক্লাসের সমস্ত পদ্ধতি বা বর্তমানে প্রয়োজনীয় যেগুলি প্রয়োজনীয়ভাবে প্রয়োগ করবেন?

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

@AssafStone একমত

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

আপনার ডিআই / আইওসি লাইব্রেরি গ্রহণের সাথে যদি আপনার পরীক্ষা / মাইগ্রেট করা দম্পতি হন তবে সত্যিই কি আপনাকে অনেক বেশি র‍্যাপার রাইটিং করতে হবে?

4

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

আমরা মূলত # 2 (স্ট্যাটিক ইউটিলিটিগুলির জন্য মোড়কের ক্লাস) হিসাবে বর্ণিত পথ অনুসরণ করছি। তবে আমরা কেবল তখনই তাদের ব্যবহার করি যখন কাঙ্ক্ষিত আউটপুট উত্পাদন করার জন্য প্রয়োজনীয় ডেটা সহ ইউটিলিটি সরবরাহ করা খুব জটিল হয় (যেমন যখন আমাদের একেবারে পদ্ধতিটি উপহাস করতে হয়)।

এর অর্থ আমাদের অ্যাপাচি কমন্সের মতো সাধারণ ইউটিলিটির জন্য একটি র‌্যাপার লিখতে হবে না StringEscapeUtils(কারণ তাদের প্রয়োজনীয় স্ট্রিংগুলি সহজেই সরবরাহ করা যেতে পারে) এবং আমরা স্থির পদ্ধতির জন্য উপহাসগুলি ব্যবহার করি না (যদি আমরা মনে করি যে এটি লেখার সময় প্রয়োজন তখন আমাদের প্রয়োজন হতে পারে) একটি মোড়কের ক্লাস এবং তারপরে মোড়কের উদাহরণটি উপহাস করুন)।


2

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


1

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

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

তবে এটি সত্যিই দ্রুত ছিল এবং এটি এখন পর্যন্ত বেশ ভালভাবে কাজ করছে। আমি এটি সুপারিশ করছি - http://www.easymock.org/


1

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

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


1

কখনও কখনও আমি বিকল্প 4 ব্যবহার করি

  1. কৌশল প্যাটার্ন ব্যবহার করুন। স্থিতিশীল পদ্ধতি সহ একটি ইউটিলিটি ক্লাস তৈরি করুন যা প্লাগেবল ইন্টারফেসের একটি উদাহরণে প্রয়োগের প্রতিনিধিত্ব করে। একটি স্ট্যাটিক ইনিশিয়ালাইজার কোড করুন যা কংক্রিট বাস্তবায়নে প্লাগ হয়। পরীক্ষার জন্য একটি মক বাস্তবায়ন প্লাগ ইন করুন।

এটার মতো কিছু.

public class DateUtil {
    public interface ITimestampGenerator {
        long getUtcNow();
    }

    class ConcreteTimestampGenerator implements ITimestampGenerator {
        public long getUtcNow() { return System.currentTimeMillis(); }
    }

    private static ITimestampGenerator timestampGenerator;

    static {
        timestampGenerator = new ConcreteTimeStampGenerator;
    }

    public static DateTime utcNow() {
        return new DateTime(timestampGenerator.getUtcNow(), DateTimeZone.UTC);
    }

    public static void setTimestampGenerator(ITimestampGenerator t) {...}

    // plus other util routines, which may or may not use the timestamp generator 
}

আমি এই পদ্ধতির সম্পর্কে যা পছন্দ করি তা হ'ল এটি ইউটিলিটি পদ্ধতিগুলিকে অচল করে রাখে, যখন আমি কোড জুড়ে ক্লাসটি ব্যবহার করার চেষ্টা করি তখন আমার কাছে ঠিক মনে হয়।

Math.sum(17, 29, 42);
// vs
new Math().sum(17, 29, 42);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.