خانه > Acceptance Testing, Agile, TDD, Unit Testing > تست نرم‌افزار در Agile Software Development

تست نرم‌افزار در Agile Software Development


همان‌طور که می‌دانید Unit Testing به معنای تست کردن قسمت کوچکی از برنامه است که ماجول یا یونیت برنامه نام دارد و می‌تواند در پیدا کردن اشکالات برنامه بسیار مؤثر واقع شود، اما در حقیقت نوشتن یک Unit Test بیشتر عملی است که در قسمت طراحی نرم‌افزار به کار می‌رود تا در قسمت Verification یا اشکال‌یابی، و می‌تواند نظرات کاربران را بگیرد.  به این معنا که وقتی کاربری در مورد سیستم نظر داد که مشکلی در Unit وجود دارد و آن مشکل در Unit Testing حل شد، در قسمت‌های بعدی نمی‌توان از او برای آن قسمت از برنامه نظرخواهی کرد. علاوه بر آن، عملکرد صحیح تمام Unit Testها نمی‌تواند بدین معنا باشد که همه سیستم خوب کار می‌کند؛ زیرا ممکن است در ارتباط اجزای سیستم مشکلی پیش آمده باشد.

https://i0.wp.com/leonmeijer.nl/images/leonmeijer_nl/WindowsLiveWriter/TestdrivendevelopmentUni.NETwhatsallthis_D86E/sw_testing.jpg

Test Driven Development

تصور کنید که تست‌های نرم‌افزار خود را قبل از نوشتن برنامه آماده کنید. این کاری است که ما درAgile  Development انجام می‌دهیم. در این روش تست‌ها خودشان به وجود میآیند و ما می‌توانیم بگوییم که رویه‌ای از سیستم را نمی‌نویسیم تا وقتی که تستی از برنامه موفق نباشد و نشان دهد که آن رویه لازم است.  بدین معنی که مثلاً اول یک قطعه کد برای افزودن دانشجویی جدید به فهرست دانشجویان می‌نویسیم، ولی چون در آن کد قطعه‌ای از کد کلاسی که insert را انجام می دهد وجود ندارد، برنامه اشکال می گیرد. حال کار گروه اکس‌پی این است که برنامه را طوری درست کنند که این تست پاس شود و به قدری روی برنامه کار ‌کنند تا برنامه دلخواه به دست آید.

با این کار فکر می‌کنید چه فایده‌ای نصیب ما خواهد شد؟ مهم‌ترین فایده این کار این خواهد بود که برای هر رویه یاFunction، یک تست داریم که عملکرد آن را تأیید می‌کند. تصور کنید که قرار است رویه و عملکرد جدیدی را در سیستم اعمال کنیم. اگر برای آن رویه تستی بنویسیم و آن تست را انجام دهیم،  مشاهده می‌کنیم که تأثیری روی کل برنامه  خواهد گذاشت یا خیر؟ و ترس ما را از اعمال تغییرات در سورس کد برنامه از بین می‌برد.
به علا‌وه، چنین کاری باعث خواهد شد برنامه‌ای را که می‌خواهیم بنویسیم، هم به اینترفیس آن اهمیت دهیم هم به عملکرد صحیح آن و رابطه رویه‌های آن با هم.

یکی از مهم‌ترین مزایای این روش این است که برنامه ما آزمون‌پذیر یا Testable است. از دیگر مزایای نوشتن تست قبل از نوشتن برنامه این است که می‌توانیم مستندات خود را از روی این تست‌ها داشته باشیم. مثلاً اگر می‌خواهید بدانید که یک Object چگونه فراخوانی می‌شود و چه پارامترهایی باید به آن فرستاد، کافی است به تست آن کلاس نگاهی بیندازیم. این مستندات همیشه بروزند و حتی قابل اجرا نیز هستند.

شکل 1 دیاگرام UML قسمتی از سیستم حقوق دستمزد را نشان می‌دهد. کلاس payroll از کلاسEmployeeDatabase برای گرفتن objectهای کارمندان یا Employee استفاده می‌کند. در حقیقت این کلاس از کلاسEmployee درخواست می‌کند که حقوق کارمند را حساب کند. سپس این حقوق را به شیء CheckWriter جهت چاپ چک کارمند ارسال می‌کند. در آخر نیز این پرداخت را به کلاس Employee جهت پست کردن چک ارسال می‌کند و object مربوطه را به  دیتابیس پاس می‌دهد.

شکل 1

تصور کنید که تا به حال هیچ کدی برای این سیستم ننوشته‌ایم و این دیاگرام تنها چیزی است که ما در جلسه اولیه شناخت سیستم داریم. اولین قدم برای ایجاد چنین سیستمی، نوشتن تست‌هایی است که عملکرد شیءpayroll را مشخص کند. ممکن است از خود سؤال کنید: ما که هنوز نمی‌دانیم از چه پایگاه اطلاعاتی استفاده می‌کنیم. آیا می‌خواهیم در سیستم خود از Sql Server استفاده کنیم یا از  اوراکل؟ شاید هم سؤال کنید که چگونه می‌توانیم بفهمیم که چک کارمندی واقعاً چاپ شده است یا خیر؟

شکل 2

چون اطلاعاتی که در دست داریم کم است، می‌توانیم از Mock Object یا شیء ظاهری استفاده کنیم. راه حل این است که از اینترفیس استفاده نماییم. برای این کار می‌توانیم همان‌طور که در شکل 2 مشاهده می‌کنید، اینترفیس‌هایی بین کلاس‌های مرتبط در سیستم payroll قرار دهیم و تست مربوط به این اینترفیس‌ها را بنویسیم. هم‌اکنون از اینترفیس‌های EmployeeDatabase و CheckWriter و Employee جهت برقراری ارتباط بین شیء‌ها استفاده می‌شود. اضافه بر این، سه Mock Object هم ایجاد شده است که با اینترفیس‌ها ارتباط برقرار می‌کند. اینMock Objectها توسط شیء payrollTest مورد جست‌وجو قرار می‌گیرند تا صحت کار شیء payroll را تضمین کنند.
تست زیر می‌تواند برای این کار مورد استفاده قرار گیرد:

Public void testPayRoll()
{
MockEmplyeeDatabase db=new MockEmplyeeDatabase();
MockCheckWriter w=new MockcheckWriter();
Payroll p=new Payroll(db,w);
p.payEmployees();
assert(W.checksWereWrittenCorrectly());
assert(db.paymentsWerePostedCorrectly());
}


همان‌طور که در این کدها مشاهده می‌کنید، شیء‌های Mock به وجود میآیند و آن‌ها را به شیء Payroll ارسال می‌کنیم و به شیء payroll می‌گوییم که پرداخت به تمام کارمندان را انجام دهد. بعد از آن از شیء Mock در مورد صحت عملیات انجام شده سؤال خواهد شد. کاری که این تست انجام می‌دهد، در حقیقت این است که چک کند که شیء payroll رویه‌های صحیح و با اطلاعات صحیح را فراخوانده است یا خیر. ولی این بررسی نمی‌تواند تست کند که آیا چک‌ها درست نوشته شده‌اند یا خیر. به ‌علا‌وه، نمی‌تواند بررسی کند که پایگاه اطلاعاتی بروزآوری شده است یا خیر؟  کاری که این تست انجام می‌دهد این است که کلاس ‌Payroll را به تنهایی چک کند.

Acceptance Test
Unitتست‌ها در حقیقت ابزاری ضروری برای تست کردن سیستم به شمار می‌روند، ولی کارایی خوبی ندارند؛ زیرا نمی‌توانند صحت کارایی کل سیستم را تضمین نمایند. Unit Testها در واقع تست‌های جعبه سفید (White box)  هستند که در آن تنها مکانیزمی خاص در سیستم چک می‌گردد. برای این‌که بتوانیم نیازهای کاربران سیستم خود را چک کنیم، به تست Black box یا Acceptance Test نیاز داریم. این تست‌ها نیازهای کاربران را در قسمت‌هایی از برنامه چک می‌کنند و ما را از این‌که نیاز کاربران از سیستم بر آورده شده است یا خیر، مطلع می‌کنند. این تست‌ها معمولاً توسط کسانی نوشته می‌شوند که هیچ اطلاعاتی از مکانیزم سیستم و اجزای داخلی آن ندارند و معمولاً توسط کاربران سیستم تهیه می‌شوند Acceptance Testها برنامه‌هایی هستند که حتی می‌توان آن‌ها را اجرا نمود و اغلب با استفاده از Scripting Languageها نوشته می‌شوند.

وقتی مشتری سیستم این تست‌ها را نوشت، برنامه نویسان می توانند برای این‌که از نیاز کاربران آگاه شوند، آن تست‌ها را بخوانند. برای مثال، سیستم حقوق و دستمزد را در نظر بگیرید. در مرحله اول ما باید بتوانیم کارمندی را به سیستم اضافه نماییم یا او را از دیتابیس حذف کنیم. به کدهای زیر که قسمتی از این تست هستند نگاه کنید:

‌در این تست ما کارمندی را با شماره 1256، نام Amin Safaei و حقوق دو میلیون در بانک اطلاعاتی وارد کرده‌ایم. سپس به سیستم می‌گوییم وقت پرداخت است و باید حقوق کارمند را پرداخت کنیم. سپس تست می‌کنیم که چک آن کارمند با مقداری که وارد کرده‌ایم، چاپ شده است.

Public void testPayRoll()
{
 MockEmplyeeDatabase db=new MockEmplyeeDatabase();
MockchekWriter w=new MockCheckWrit();
}


همان‌طور که مشاهده می‌کنید، نوشتن این تست برای کارفرمای سیستم کار آسانی است. اضافه کردن امکانات جدید به این قطعه کد نیز کار سختی به نظر نمی‌رسد.

هر تست در واقع به سیستم وارد می‌شود و نتیجه‌ای را در بر خواهد داشت. این تست‌ها در مقابل اطلاعات ورودی تست خواهند شد و نتیجه این تست‌ها با جوابی که از سیستم انتظار داریم مقایسه خواهند شد. اگر جواب به دست آمده با جوابی که انتظار داریم مساوی باشد، به اصطلاح تست پاس شده است. در غیر این صورت، اصلاحات مورد نظر تا به دست آمدن نتیجه مساوی، ادامه خواهد داشت.

منبع : مجله شبکه

یاشیاسیز

  1. هنوز دیدگاهی داده نشده است.
  1. No trackbacks yet.

پاسخی بگذارید

در پایین مشخصات خود را پر کنید یا برای ورود روی شمایل‌ها کلیک نمایید:

نشان‌وارهٔ وردپرس.کام

شما در حال بیان دیدگاه با حساب کاربری WordPress.com خود هستید. بیرون رفتن / تغییر دادن )

تصویر توییتر

شما در حال بیان دیدگاه با حساب کاربری Twitter خود هستید. بیرون رفتن / تغییر دادن )

عکس فیسبوک

شما در حال بیان دیدگاه با حساب کاربری Facebook خود هستید. بیرون رفتن / تغییر دادن )

عکس گوگل+

شما در حال بیان دیدگاه با حساب کاربری Google+ خود هستید. بیرون رفتن / تغییر دادن )

درحال اتصال به %s

%d وب‌نوشت‌نویس این را دوست دارند: