بایگانی

Posts Tagged ‘Testing’

آیا Agile نیازی به Technical Excellence دارد؟

اوت 24, 2010 4 دیدگاه

Technical Excellence یکی از مبحث های Agile می باشد که یا مورد محبت زیاد و یا کم مهری بیش از اندازه  قرار می گیرد .  البته این مسئله صرفا برای ایران نیست و تیم های تازه کار Agile با این مشکل مواجه می شوند.  در آیه شماره 9 اصول توسعه چابک آمده است :

https://sirasad.files.wordpress.com/2010/08/images.jpg?w=225Continuous attention to technical excellence
and good design enhances agility

معنی لفظی این آیه : توجه مداوم به برتری فنی و طراحی خوب باعث افزایش چابکی می شود . اگر بخواهیم این اصل را از اصول توسعه چابک تفسیر نماییم به این نقطه خواهیم رسید که در توسعه چابک مسائل تکنیکی و فنی ( که در متدلوژی های دیگر در نظر گرفته نمی شدند) با ارزش و کلا جزو پروسه چابک سازی نامیده  شده اند .  به عبارت ساده تر در این اصل تیم های Agile را به حفظ برتری فنی و تکنیکی مداوم دعوت کرده اند و در این حد این قضیه مهم خوانده شده است که گفته اند : «باعث افزایش سطح چابکی می شود » که در هیچ یک از اصول توسعه چابک به صراحت به این مسئله اشاره نشده است یعنی این مورد تاثیر بیشتری نسبت به بقیه خواهد داشت .

ولی طبق تجربه من عرض می کنم که این اصل را قبول ندارم و این را می توان بیان کنم که : » بدون Technical Excellence چابک بودن امکان پذیر نخواهد بود » . و دغدغه نوشتن پستی فقط و فقط بیان لزوم برتری فنی برای تیم های Agile می باشد .

قبل از بیان لزوم برتری فنی لازم است تعریفی از Technical Excellence داشته باشیم :

Technical Excellence یا همان برتری فنی به معنی استفاده از ابزارها ,  روش ها ,  تکنیک ها ,  متد ها و … برتر در پروسه طراحی ,  تست و کد نویسی می باشد . از جمله Technical Excellence ها مورد بحث و مهم در زمینه چابک Unit Testing , Refactor , Continues Integration  , Clear Code , Automated Tests , TDD , … .و البته که تمام موارد فنی جزو این برتری فنی حساب خواهند شد .

برای اثبات مطلب ارائه شده (بدون Technical Excellence چابک بودن امکان پذیر نخواهد بود) کافی است با هم یک مثال کوچک را بررسی نماییم : در ارزش 4 ام بیانیه توسعه چابک آمده است :

Responding to change over following a plan

بیان شده است که ما به عنوان یک تیم چابک باید بتوانیم پذیرای تغییرات باشیم .

همانطور که می دانید تغییرات آفت توسعه نرم افزار هستند و این تغییرات باعث شکست پروژه های خیلی بزرگ شده اند و البته اگر بتوانیم این تغییرات را کنترل و مدیریت کنیم  علاوه بر رضایت مشتری به سود آوری خوبی خواهیم رسید .دقیقا دو روی  یک سکه هستند  یک رو رضایت مشتری و سود آوری و یک روی دیگر نارضایتی و  ضرر و زیان .

فرض کنید ما یک تیم Agile هستیم که اعتقادی به Technical Excellence نداریم و این را هم می دانیم که برای پذیرایی از تغییرات باید کد های تمیزی داشته باشیم . برای داشتن کد تمیز باید کدها Refactor  شده باشند . برای رفاکتور شدن کد های نیاز به تست های اتوماتیک و کلا Unit Testing داریم . Unit Test ها باید برروی یک Continues Integration قرار بگیرند .

https://sirasad.files.wordpress.com/2010/08/b5391b73f65841c4a9c49d0e2c9aec2d1.jpg?w=376حالا ما به عنوان یک تیم Agile چگونه می خواهیم بدون Technical Excellence پذیرای تغییرات باشیم ؟ اگر نمی خواهیم پذیرای تغییرات باشیم ,  پس چگونه اسم خودمان را تیم Agile یا چابک نامیده ایم ؟

این فقط یک مثال کوچک از لزوم Technical Excellence بود که خواستم از این طریق عرض کنم : موارد و اصولی که در بیانیه توسعه چابک بیان شده است ,  همینطوری کشکی نیست و نمی شود گفت که این به درد ما نمی خورد بنداز دور . نوشتن چنین نوشته هایی از آنجایی برای من اهمیت پیدامی کند که می شنوم : » ما Agile کار می کنیم  ,  ولی Unit Test نداریم . «

البته این معضل فقط برای Agile نیست ,  بنده تیم هایی (گردن کلفت) را دیدم که ادعای کار با RUP را می کردند ولی در واقع همان سنت حسنه Waterfall را ادامه می دادند . پیشنهاد من این است که  Agile  کار نکنیم بلکه Agile باشیم که اینگونه همه چیز حل خواهد شد .

به امید تیم های Agile در سرتاسر جهان .

یاشیاسیز

مطالب مرتبط با این بحث :

تست محصول در Agile

مه 28, 2010 5 دیدگاه

همیشه به خاطر می آورم , زمانی که برنامه نویس بودم و یا به عنوان رهبر تیم توسعه نرم افزار فعالیت می کردم با مقوله تست برنامه مشکل داشتیم . نرم افزار که توسعه می دادیم یا اصلا تست نمی شد و یا اگر هم می شد به صورت دستی توسط خود برنامه نویس ها یا یک سری افراد متفرقه مانند اسپانسر پروژه تست می گردید که چندان روش با اعتباری نبود. معمولا برنامه ای که پر از باگ باشد مستعد از دست دادن مشتری هست و از دست دادن مشتری مصادف با عصبانیت مدیران شرکت خواهد شد . برنامه نویس ها معمولا علت باگ های زیاد برنامه را  فقدان نقش Tester در تیم توسعه اعلام می کنند و فکر می کنند اگر کسی با عنوان Tester به تیم توسعه اضافه شود , تمام مشکلات حل خواهد شد و البته آنها متعقد هستند که تست برنامه به هیچ وجه وظیفه برنامه نویس نیست .

https://sirasad.files.wordpress.com/2010/05/doctorninja-tm.jpg?w=275بنده به دو دلیل با تئوری بالا مخالف هستم و عقیده دارم باز هم  اگر Tester به تیم توسعه اضافه گردد دوباره برنامه ها پر از باگ خواهند بود : 1- Tester خوب در ایران وجود ندارد و یا خیلی کم است 2-  Tester نمی تواند تمام آزمایش های لازم را انجام بدهد و آزمایشات کامل زمانی می تواند اتفاق بیفتید که برنامه نویس هم تست نماید .

البته بنده لزوم بودن Tester را در تیم های توسعه نرم افزار نفی نمی کنم بلکه اعتقاد دارم زمانی باید Tester به تیم توسعه ملحق شود که فرهنگ مناسبی نسبت به تست در تیم توسعه و سازمان نهادینه شده باشد .

تمام مطالبی که در بالا ذکر شد پیش گفتاری برای بحث اصلی مقاله می باشد که نرم افزار و یا محصول در محیط چابک چگونه تست می شود و چه نقش هایی برای این منظور نیاز است .

به طور کلی Agile دید مثبت و خوبی نسبت به تست دارد و کلا این مقوله در ارزش ها و اصول بیانیه توسعه چابک پیش بینی شده است .  اصل 9 بیانیه توسعه چابک اشاره غیر مستقیمی به لزوم تست دارد .TDD روشی می باشد که در متدهای Agile به عنوان روش تست معرفی شده است .

همانطور که در مقالات قبلی در مورد TDD عرض شد در این روش اول تست ها نوشته می شوند و بعدا براساس تست های نوشته شده ,  کدها تولید می شوند . شاید بپرسید که فرق ندارد که تست در اول نوشته شود و یا در آخر ,  بالاخره هدف ایجاد تست برای نرم افزار می باشد و حتی شاید در ایجاد تست در آخر راحتتر و بهتر عمل کنیم ؟

مزیت اصلی نوشتن تست در اول و قبل از کد نویسی این می باشد که ما به اندازه و تمیز کد خواهیم نوشت . فقط هدف از کدنویسی پاس کردن  تست  ها می باشد و به عبارت دیگر می توان گفت که برادر ما می خواهیم رفع تکلیف کنیم با پاس کردن این تست ها ,  کمتر کد بنویس با ضواید کم که فقط این تست ها پاس شود . مزیت دیگر نوشتن تست قبل از کدنویسی ایجاد یک الگو و هدف برای کدنویسی می باشد . یعنی ما دقیقا می دانیم که فقط هدف ما نوشتن این تکه کد برای پاس کردن این تست با این مضمون می باشد و این دوباره باعث Refactoring خواهد شد .ولی اگر تست در آخر نوشته شود کمی تست ها متفاوت خواهند شد : زیرا ما برای کدهایی که ایجاد شده تست می نویسیم و در واقع کدهای نوشته شده فرمانده و الگوی تست نویسی خواهند شد در حالی که شاید کد نوشته شده درست نیست ,  یعنی انتظار مشتری بر آورده نشده است و پس تست این قسمت که دقیقا معلوم نیست انتظار مشتری را بر آورده می کند یا نه چه فایده ای می تواند داشته باشد ؟

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

هدف Agile ارائه ارزش های مورد نیاز تجارت , کسب و کار مشتری طی یک محصول نرم افزاری می باشد . بحث از ارزش گردید , یعنی هدف ما ارائه و فقط ارائه ارزش ها مورد انتظار مشتری می باشد . ارزش مشتری همان User Story هایی می باشد که آن ها را در اول و یا طی  پروژه جمع آوری می نماییم . مثلا  : » کاربران سیستم باید در هنگام ثبت نام از رمز عبور امن (Secure) استفاده نمایند» : این می تواند یک ارزش یا User Story برای مشتری باشد ; ولی در تعریف Agile گفتیم که : » هدف ما ارائه و فقط ارائه ارزش ها مورد انتظار مشتری می باشد » . ما ارزش را به صورت یک User Story بیان کردیم ولی انتظار مشتری را از این ارزش بیان نکردیم . به عبارت ساده تر این ارزش چه ویژگی هایی باید داشته باشد تا نیاز مشتری برآورده شود؟

برای وضوح بیشتر به این مثال توجه نمایید : فرض کنید ما یک مشتری داریم که او می خواهد یک کارخانه اتومبیل سازی راه بیندازد و ما هم راه انداز کارخانه هستیم . در فاز تحلیل و یا در راه اندازی کارخانه در می یابیم که  برای کارخانه نیاز به لیفت تراک می باشد .  این یک ارزش برای کارخانه می تواند باشد . اما مشتری اذعان دارد که این لیفت تراک باید بتواند در یک نقطه 360 درجه بچرخد و باید بتواند بارهای بالای 20 تن را بردارد . این ها هم ویژگی های این ارزش می توانند می باشند . زمان تحویل لیفت تراک ما باید تست بکنیم ببینیم که آیا این لیفت تراک می تواند این باید ها را پاس کند ؟ به این حالت اصطلاحا  Acceptance Test می گویند .

پیاده سازی یک ارزش در محیط چابک می تواند به صورت زیر می باشد :

  • ارزش یا User Story شناسایی می شود و مستند می شود.
  • ویژگی های ارزش شناسایی و مستند سازی می شود.
  • هر کدام از ویژگی های یک ارزش به صورت تست هایی پیاده سازی می شوند.
  • ارزش بر اساس الگوی تست موجود کد نویسی می شود .

همانطور که مستحضر می باشید گام های بالا همان گام های TDD می باشند ولی این گام های وظیفه چه کسی می باشد ؟

  • گام اول – ارزش یا User Story شناسایی می شود و مستند می شود : وظیفه کل تیم توسعه می باشد .
  • گام دوم – ویژگی های ارزش شناسایی و مستند سازی می شود : وظیفه Tester های تیم و توسعه دهندگان می باشد .
  • گام سوم و چهارم-  وظیفه برنامه نویسان عزیز می باشد .

داشتن تست برای هر ویژگی بسیار سودمند و با ارزش می باشد که در محیط چابک اگر تست نباشد کار تقریبا امکان پذیر نخواهد بود . یکی از ارزشها و شعارهای اصلی توسعه چابک «قبول و پذیرایی از تغییرات» است . بنده به صراحت عرض می کنم که اگر تست نداشته باشید این شعار قابل انجام نخواهد بود . بدلیل اینکه هر تغییر ویرانی هایی را بدنبال خواهد داشت . اگر تا به حال برنامه نوشته باشید و محصول توسعه داده باشید باید به خاطر بیاورید که در هر تغییر (جزئی و یا کلی) قسمت هایی از برنامه درست و قسمت هایی از برنامه ویران شده است . اگر تست داشته باشیم ,  در هر تغییر می توانیم بعد از اعمال تغییرات تمام تست ها را اجرا نماییم ,  اگر کدی در یک جایی ویران شده باشد ,  تست آن قسمت پاس نخواهد شد و قرمز رنگ خواهد شد ,  پس می توان به راحتی از ویران کردن دیگر بخش ها مطلع شد و تصحیحات لازم را به موقع و قبل از ارائه آن به مشتری انجام داد .

چابک شوید  , TDD کار کنید ,  تغییرات را با آغوش باز پذیرا باشید و چابک بمانید .

یاشیاسیز

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

ژانویه 13, 2010 بیان دیدگاه

همان‌طور که می‌دانید 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();
}


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

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

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

یاشیاسیز