۱۳۸۷/۱۰/۰۷

آشنايي با آزمايش واحد (unit testing) در دات نت، قسمت 1


آزمايش واحد چيست؟

آزمايش واحد (unit testing) هنر و تمرين بررسي صحت عملكرد قطعه‌اي از كد (كه در اينجا واحد ناميده شده است)، به وسيله كدهاي ديگري است كه توسط برنامه نويس نوشته خواهند شد. عموما اين آزمايش‌ها جهت بررسي يك متد تهيه مي‌شوند. در اين مرحله بايد درنظر داشت كه هدف، بررسي كارآيي نرم افزار نيست. هدف اين است كه بررسي كنيم آيا قطعه كد جديدي كه به برنامه اضافه شده است درست كار مي‌كند و آيا هدف اصلي از توسعه آن‌را برآورده مي‌سازد؟
براي مثال متدي را توسعه داده‌ايد كه آدرس يك دومين را از آدرس اينترنتي دريافت شده، جدا مي‌سازد. با استفاده از آزمايشات واحد متعدد مي‌توان از صحت عملكرد آن اطمينان حاصل كرد.


اهميت و مزاياي آزمايش واحد كدامند؟

  • كامپايل شدن كد به معناي صحت عملكرد آن نيست. حتما نياز به روش‌هايي براي آزمايش سيستم وجود دارد. صرفا به شما حقوق داده نمي‌شود كه كد بنويسيد. به شما حقوق داده مي‌شود كه كد قابل اجرايي را تهيه كنيد.
  • نوشتن آزمايش‌هاي واحد به توليد كدهايي با كيفيت بالا در دراز مدت منجر خواهد شد. براي نمونه فرض كنيد سيستمي را توسعه داده‌ايد. امروز كارفرما از شما خواسته است كه قابليت جديدي را به برنامه اضافه كنيد. براي اعمال اين تغييرات براي مثال نياز است تا قسمتي از كدهاي موجود تغيير كند، همچنين كلاس‌ها و متدهاي جديدي نيز به برنامه افزوده گردند. پس از انجام درخواست رسيده، چگونه مي‌توانيد اطمينان حاصل كنيد كه قسمت‌هاي پيشين سيستم كه تا همين چند لحظه پيش كار مي‌كردند، اكنون نيز همانند قبل كار مي‌كنند؟ حجم كدهاي نوشته شده بالا است. آزمايش دستي تك تك موارد شايد ديگر از لحاظ زماني مقدور نباشد. آزمايش واحد روشي است براي اطمينان حاصل كردن از اينكه هنگام تحويل كار به كارفرما مرتبا سرخ و سفيد نشويم! به اين صورت عمليات refactoring كدهاي موجود بدون ترس و لرز انجام خواهد شد، چون بلافاصله مي‌توانيم آزمايشات قبلي را اجرا كرده و از صحت عملكرد سيستم اطمينان حاصل نمائيم. بدون اينكه در زمان تحويل برنامه در هنگام بروز خطا بگوئيم : "اين غيرممكنه!"
  • روال‌هاي آزمايشات صورت گرفته در آينده تبديل به مرجع مهمي جهت درك چگونگي عملكرد قسمت‌هاي مختلف سيستم خواهند شد. چگونه فراخواني شده‌اند، چگونه بايد به آن‌ها مقداري را ارجاع داد و امثال آن.
  • با استفاده از آزمايش‌هاي واحد، بدترين حالات ممكن را قبل از وقوع مي‌توان در نظر گرفت و بررسي كرد.
  • نوشتن آزمايش‌هاي واحد در حين كار، برنامه نويس را وادار مي‌كند كه كار خود را به واحدهاي كوچكتري كه قابليت بررسي مستقلي دارند، بشكند. براي مثال فرض كنيد متدي را توسعه داده‌ايد كه پس از انجام سه عمليات مختلف بر روي يك رشته، خروجي خاصي را ارائه مي‌دهد. هنگام آزمايش اين متد چگونه مي‌توان اطمينان حاصل كرد كه كدام قسمت سبب شكست آزمايش شده است؟ به همين جهت برنامه نويس جهت ساده‌تر كردن آزمايشات، مجبور خواهد شد كه كد خود را به قسمت‌هاي مستقل كوچكتري تقسيم كند.
  • با توجه به امكان اجراي خودكار اين آزمايشات، به عنوان جزئي ايده‌آل از پروسه توليد نرم افزار محسوب مي‌شوند.


حد و مرز يك آزمايش واحد كجاست؟

آزمايش شما، آزمايش واحد ناميده نخواهد شد اگر:
  • با ديتابيس سر و كار داشته باشد.
  • با شبكه در ارتباط باشد.
  • با فايل‌ها كار كند.
  • نياز به تمهيدات ويژه‌اي براي اجراي آن وجود داشته باشد. مثلا وجود يك فايل config براي اجراي آن ضروري باشد.
  • همراه و همزمان با ساير كدهاي آزمايش‌هاي واحد شما قابل اجرا نباشد.
براي مثال اگر يكي از متدهاي شما بزرگترين عدد يك ليست را از ديتابيس دريافت مي‌كند، در متدي كه براي آزمايش واحد آن تهيه خواهيد كرد نبايد هيچگونه كدي جهت برقراري ارتباط با ديتابيس نوشته شود.
اين امر سبب سريع‌تر اجرا شدن آزمايشات واحد خواهند شد و در آينده شما را از انجام آن به‌دليل كند بودن روند انجام آزمايشات، منصرف نخواهد كرد. همچنين تغييرات انجام شده در لايه دسترسي به داده‌ها سبب غيرمعتبر شدن اين نوع آزمايشات نخواهند شد. به بيان ديگر وظيفه متد آزمايش واحد، اتصال به ديتابيس يا شبكه و يا خواندن اطلاعات از يك فايل نيست.

ادامه دارد...