এম্বেড করা সি বিকাশকারীদের জন্য ভাল ইউনিট পরীক্ষার উদাহরণ [বন্ধ]


20

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

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

সুতরাং, প্রশ্নটিতে: দয়া করে কেউ লাইভ সেশনে ইউনিট টেস্টিং প্রদর্শনের জন্য যে ফাংশনগুলি ব্যবহার করতে পারেন তার কয়েকটি ভাল উদাহরণ উপস্থাপন করতে পারেন? আমার (পরিবর্তনের সাপেক্ষে) মতামতের একটি উত্তরের উত্তর সম্ভবত:

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

কোন চিন্তা?

যদিও এটি সম্ভবত প্রাসঙ্গিক নয়, গুগল টেস্ট ফ্রেমওয়ার্ক ব্যবহার করে পরীক্ষাগুলি নিজেরাই সম্ভবত সি ++ তে লেখা থাকবে: আমাদের সমস্ত শিরোনামের ইতিমধ্যে #ifdef __cplusplus extern "C" {তাদের চারপাশে মোড়ক রয়েছে; আমি এখন পর্যন্ত যে পরীক্ষাগুলি করেছি তার সাথে এটি ভাল কাজ করেছে।


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

উত্তর:


15

এখানে একটি সাধারণ ফাংশন যা লেন বাইটের মাধ্যমে একটি চেকসাম তৈরি করার কথা ।

int checksum(void *p, int len)
{
    int accum = 0;
    unsigned char* pp = (unsigned char*)p;
    int i;
    for (i = 0; i <= len; i++)
    {
        accum += *pp++;
    }
    return accum;
}

এটিতে একটি ফেন্সপোস্ট বাগ রয়েছে: বিবৃতিতে, পরীক্ষাটি হওয়া উচিত i < len

মজাটি হ'ল, আপনি যদি এটির মতো কোনও পাঠ্য স্ট্রিংয়ে এটি প্রয়োগ করেন ...

char *myString = "foo";
int testval = checksum(myString, strlen(myString));

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

এখানে একটি সাধারণ ইউনিট পরীক্ষা যা এই বাগটি পতাকাঙ্কিত করবে (বেশিরভাগ সময় ... :-)

void main()
{
    // Seed the random number generator
    srand(time(NULL));

    // Fill an array with junk bytes
    char buf[1024];
    int i;
    for (i = 0; i < 1024; i++)
    {
        buf[i] = (char)rand();
    }

    // Put the numbers 0-9 in the first ten bytes
    for (i = 0; i <= 9; i++)
    {
        buf[i] = i;
    }

    // Now, the unit test. The sum of 0 to 9 should
    // be 45. But if buf[10] isn't 0 - which it won't be,
    // 255/256 of the time - this will fail.
    int testval = checksum(buf, 10);
    if (testval == 45)
    {
        printf("Passed!\n");
    }
    else
    {
        printf("Failed! Expected 45, got %d\n", testval);
    }
}

খুব ভালো! এটি কেবলমাত্র এক ধরনের উত্তর যা আমি আশা করেছিলাম: আপনাকে ধন্যবাদ।
ডাঃআল

আপনি যখন বাফারটি তৈরি করেন যখন আপনি ইতিমধ্যে মেমরির এই খণ্ডে আবর্জনা ফেলেছেন, এলোমেলো সংখ্যার সাহায্যে এটি আরম্ভ করা কি সত্যই প্রয়োজন?
সাপ স্যান্ডার্স

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

ইউনিট পরীক্ষায় অ-বিবাদী আচরণের উপর নির্ভর করা একটি খারাপ ধারণা। একটি ঝাপটায় পরীক্ষা আপনাকে শীঘ্রই বা পরে মাথাব্যথা দেয় ...
সিগি

2

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

বাছাই করা এবং অনুসন্ধান করা তুলনার উপর নির্ভর করে যা ভুল হওয়া সহজ। এটি চারপাশে পয়েন্টারগুলি অদলবদল জড়িত যা যত্ন সহকারে করা উচিত। উভয়ই ত্রুটির ঝুঁকিতে পড়েছে, তাই নির্দ্বিধায় উদ্বিগ্ন :)

আরও কয়েকটি ধারণা:

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

আপনার কাছে এমন কোনও সাধারণ ত্রুটির জন্য কোনও নির্দিষ্ট পরামর্শ রয়েছে যা দেখায় যে পরীক্ষার ফলে কীভাবে জীবন আরও সহজ হয়?
ডাঃল

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