ইউনিট পরীক্ষার জন্য কোড পুনরাবৃত্তি করা ঠিক আছে কি?


11

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

এখানে একটি উদাহরণ:

    [TestMethod]
    public void MergeSortAssertArrayIsSorted()
    {
        int[] a = new int[1000];
        Random rand = new Random(DateTime.Now.Millisecond);
        for(int i = 0; i < a.Length; i++)
        {
            a[i] = rand.Next(Int16.MaxValue);
        }
        int[] b = new int[1000];
        a.CopyTo(b, 0);
        List<int> temp = b.ToList();
        temp.Sort();
        b = temp.ToArray();

        MergeSort merge = new MergeSort();
        merge.mergeSort(a, 0, a.Length - 1);
        CollectionAssert.AreEqual(a, b);
    }
    [TestMethod]
    public void InsertionSortAssertArrayIsSorted()
    {
        int[] a = new int[1000];
        Random rand = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < a.Length; i++)
        {
            a[i] = rand.Next(Int16.MaxValue);
        }
        int[] b = new int[1000];
        a.CopyTo(b, 0);
        List<int> temp = b.ToList();
        temp.Sort();
        b = temp.ToArray();

        InsertionSort merge = new InsertionSort();
        merge.insertionSort(a);
        CollectionAssert.AreEqual(a, b); 
    }

উত্তর:


21

টেস্ট কোডটি এখনও কোড এবং এটি বজায় রাখা দরকার।

যদি আপনাকে অনুলিপিযুক্ত যুক্তি পরিবর্তন করতে হয় তবে আপনার এটি অনুলিপি করা প্রতিটি জায়গাতেই সাধারণত এটি করা দরকার।

DRY এখনও প্রযোজ্য।

রিফ্যাক্টরিং পরীক্ষা করার জন্য আমার কি আর একটি পরীক্ষা লেখার দরকার নেই?

আপনি কি? এবং আপনি বর্তমানে যে পরীক্ষাগুলি সঠিকভাবে জানেন তা কীভাবে জানবেন?

আপনি পরীক্ষা চালিয়ে রিফ্যাক্টরিং পরীক্ষা করুন। তাদের সবার একই ফলাফল হওয়া উচিত।


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

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

2
আমি এর আগে কখনও ড্যাম্প শুনিনি, তবে আমি সেই বিবরণটি পছন্দ করি।
জোচিম সৌর

@ জার্গ ডব্লু মিটাগ: আপনি এখনও পরীক্ষার সাথে ডিআরআই এবং ডিএএমপি হতে পারেন। আমি সাধারণত পরীক্ষার বিভিন্ন সহায়তার পদ্ধতিতে পরীক্ষার বিভিন্ন অ্যারেঞ্জ-অ্যাক্ট-অ্যাসার্ট (বা GIVEN-WHEN-THEN) অংশগুলি রিফ্যাক্টর করি যদি আমি জানি যে পরীক্ষার কিছু অংশ পুনরাবৃত্তি করে। তাদের সাধারণত ডিএএমপি নাম থাকে, যেমন givenThereAreProductsSet(amount)এমনকি এমনকি সাধারণ actWith(param)। আমি givenThereAre(2).products()একবার সাবলীল এপি ওয়াইস (উদাহরণস্বরূপ ) দিয়ে এটি পরিচালনা করেছিলাম তবে আমি দ্রুত থামলাম কারণ এটি ওভারকিলের মতো অনুভূত হয়েছিল।
Spoike

11

ওডেড ইতিমধ্যে বলেছে, পরীক্ষার কোডটি এখনও বজায় রাখা দরকার। আমি পরীক্ষার কোডে সেই পুনরাবৃত্তি যুক্ত করবো রক্ষণাবেক্ষণকারীদের পরীক্ষার কাঠামো বুঝতে এবং নতুন পরীক্ষা যুক্ত করা আরও শক্ত করে তোলে।

আপনি পোস্ট দুটি ফাংশনে, forলুপের শুরুতে একটি স্পেস পার্থক্য বাদ দিয়ে নিম্নলিখিত লাইনগুলি একেবারে একরকম :

        int[] a = new int[1000];
        Random rand = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < a.Length; i++)
        {
            a[i] = rand.Next(Int16.MaxValue);
        }
        int[] b = new int[1000];
        a.CopyTo(b, 0);
        List<int> temp = b.ToList();
        temp.Sort();
        b = temp.ToArray();

এটি কোনও ধরণের সহায়ক ফাংশনে যাওয়ার জন্য নিখুঁত প্রার্থী হবে, যার নাম নির্দেশ করে যে এটি ডেটা শুরু করছে initial


4

না, ঠিক আছে না পরিবর্তে আপনার একটি টেস্টডেটাবিল্ডার ব্যবহার করা উচিত । আপনার পরীক্ষাগুলির পাঠযোগ্যতার বিষয়ে আপনারও যত্ন নেওয়া উচিত: ক? 1000? খ? আগামীকাল যদি আপনি যে পরীক্ষাগুলি পরীক্ষা করছেন তার বাস্তবায়নে কাজ করতে হয়, পরীক্ষাগুলি যুক্তিতে প্রবেশের দুর্দান্ত উপায়: আপনার পরীক্ষাগুলি লিখুন সহকারী প্রোগ্রামারদের জন্য, সংকলকের জন্য নয় :)

এখানে আপনার পরীক্ষাগুলি বাস্তবায়ন, "পুনর্নির্মাণ":

/**
* Data your tests will exercice on
*/
public class MyTestData(){
    final int [] values;
    public MyTestData(int sampleSize){
        values = new int[sampleSize];
        //Out of scope of your question : Random IS a depencency you should manage
        Random rand = new Random(DateTime.Now.Millisecond);
        for (int i = 0; i < a.Length; i++)
        {
            a[i] = rand.Next(Int16.MaxValue);
        }
    }
    public int [] values();
        return values;
    }

}

/**
* Data builder, with default value. 
*/
public class MyTestDataBuilder {
    //1000 is actually your sample size : emphasis on the variable name
    private int sampleSize = 1000; //default value of the sample zie
    public MyTestDataBuilder(){
        //nope
    }
    //this is method if you need to test with another sample size
    public MyTestDataBuilder withSampleSizeOf(int size){
        sampleSize=size;
    }

    //call to get an actual MyTestData instance
    public MyTestData build(){
        return new MyTestData(sampleSize);
    }
}

public class MergeSortTest { 

    /**
    * Helper method build your expected data
    */
    private int [] getExpectedData(int [] source){
        int[] expectedData =  Arrays.copyOf(source,source.length);
        Arrays.sort(expectedData);
        return expectedData;
    }
}

//revamped tests method Merge
    public void MergeSortAssertArrayIsSorted(){
        int [] actualData = new MyTestDataBuilder().build();
        int [] expected = getExpectedData(actualData);
        //Don't know what 0 is for. An option, that should have a explicit name for sure :)
        MergeSort merge = new MergeSort();
        merge.mergeSort(actualData,0,actualData.length-1); 
        CollectionAssert.AreEqual(actualData, expected);
    }

 //revamped tests method Insertion
 public void InsertionSortAssertArrayIsSorted()
    {
        int [] actualData = new MyTestDataBuilder().build();
        int [] expected = getExpectedData(actualData);
        InsertionSort merge = new InsertionSort();
        merge.insertionSort(actualData);
        CollectionAssert.AreEqual(actualData, expectedData); 
    }
//another Test, for which very small sample size matter
public void doNotCrashesWithEmptyArray()
    {
        int [] actualData = new MyTestDataBuilder().withSampleSizeOf(0).build();
        int [] expected = getExpectedData(actualData);
        //continue ...
    }
}

2

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


2

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

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

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

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