Proof of Concept - PoC

 

فردا 15 نفر مهمان دارید و می خواهید برای آنها غذایی را آماده کنید که برای اولین بار می خواهید پخت آن را تجربه کنید. فرض کنید خورش فسنجان

مواد اولیه خورش شامل مقدار زیادی گردو، رب انار، مرغ، برنج و دیگر مواد لازم را تهیه کرده اید و دستور پخت را هم در اختیار دارید. حال چه می کنید؟

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

اما راه امن تر و کم هزینه تر این است که خورش را در مقیاس بسیار کمتر، مثلا برای یک نفر، آماده کرده و در صورت حصول نتیجه مطلوب این کار را در مقیاس اصلی و برای 15 نفر تکرار کنید. در صورت عدم حصول نتیجه مطلوب هم تنها یک پانزدهم مواد اولیه از دست رفته است.

هر چند این رویکرد زمان بیشتری طلب می کند اما ریسک پخت غذای اصلی به میزان قابل توجهی کمتر بوده و نتیجه نهایی بسیار قابل پیش بینی تر و نزدیکتر به آنچه مطلوب است خواهد بود.

Facebook at 13 Million Queries Per Second Recommends: Minimize Request Variance

Facebook gave a MySQL Tech Talk where they talked about many things MySQL, but one of the more subtle and interesting points was their focus on controlling the variance of request response times and not just worrying about maximizing queries per second.

But first the scalability. Facebook's OLTP performance numbers were as usual, quite dramatic:

- Query response times: 4ms reads, 5ms writes.

- Rows read per second: 450M peak

- Network bytes per second: 38GB peak

- Queries per second: 13M peak

- Rows changed per second: 3.5M peak

- InnoDB disk ops per second: 5.2M peak

Some thoughts on creating quality, not quantity:

- They don't care about average response times, instead, they want to minimize variance. Every click must be responded to quickly. The quality of service for each request matters.

- It's OK if a query is slow as long as it is always slow.

- They don't try to get the highest queries per second out of each machine. What is important is that the edge cases are not the bad.

- They figure out why the response time for the worst query is bad and then fix it.

- The performance community is often focussed on getting the highest queries per second. It's about making sure they have the best mix of IOPs available, cache size, and space.

Read more..

Yahoo Goof

چند روز پیش در Yahoo Mailbox خودم مشغول خواندن نامه ها بودم. هنگامی که می خواستم یکی از Email ها را برای دوستانم Forward کنم به مورد زیر برخوردم کردم:

Yahoo Goof

لیست باز شده به جای اینکه Emailهای دوستان و همکارانم را نشان دهد، contact های یکی دیگر از کاربران Yahoo را نمایش می دهد!

اشتباه بزرگی است، نه؟!

Separation of Concerns و اثر آن در تست نرم افزار

Separation of Concerns به طور خلاصه به معنی فرآیند جداسازی وجوه و موضوعات مختلف یک سیستم از یکدیگر است. به عبارت ساده تر، تمرکز بر روی فرآیند یا عملکردی از یک سیستم و عدم توجه به کارکرد و جزییات دیگر آن.

به عنوان مثال، شما و همسرتان در خیابان قدم می زنید که یک اتومبیل (برای جذابیت بیشتر موضوع تصور کنید یک BMW آخرین مدل!) از کنار شما به سرعت رد می شود. ممکن است شما به خلاقیت سازندگان در طراحی بدنه اتومبیل مزبور توجه کرده باشید در صورتی که در همان زمان همسر شما در مورد اینکه قیمت چنین اتومبیلی چند می تواند باشد می اندیشد. در واقع شما دو نفر یک اتومبیل را از دو منظر متفاوت نگاه کرده اید (Separation of Concerns).

نمونه ای نرم افزاری از این مفهوم، الگوی طراحی MVC است.

 Separation of Concerns  - به نظر من - یکی از مفاهیم زیر بنایی برای انجام موفق تست های مختلف نرم افزار است. معمولا یک سیستم نرم افزاری در حین تولید و پس از آن تحت تست های مختلفی قرار می گیرد که از آن جمله می توان به تست ماژول های برنامه (Unit Test)، تست فشار (Stress Test) و تست پذیرش (Acceptance Test) و بسیاری دیگر اشاره کرد.

در واقع انواع مختلف تستهای یک سیستم، خود گویای مفهوم (Separation of Concerns) است. اما هدف من از نگارش این مطلب طرفداری از ایده انجام تستهای مختلف به صورت مجزاست. هر چند با توجه به ماهیت برخی از گونه های تست اصولا نمی توان آنها را با هم اجرا کرد (مثل Unit Test و User Acceptance Test) اما برخی دیگر را می توان به صورت همزمان انجام داد (مثل تست عملکرد برنامه و واسط کاربری).

ایده اصلی این است:

تا حد امکان از انجام تست های مختلف یک برنامه به صورت همزمان پرهیز کنید.

هر چند که گاهی انجام همزمان تست ها در کاهش زمان تست یک سیستم تاثیر دارد اما تاثیر منفی آن در کیفیت تست های انجام شده قابل چشم پوشی نیست.

25 خطای خطرناک در نرم افزار

در وبلاگ آقای مهندس مهرداد مطلب جالبی درج شده بود در مورد تحقیقی صورت گرفته در رابطه با ۲۵ خطای خطرناک و شایع در نرم افزارها که بسیاری از تیم های برنامه سازی مرتکب آن می شوند. خواندن آنرا به همه دوستان نرم افزارچی(!) توصیه می کنم:

The Top 25 Errors are listed below in three categories:
Category: Insecure Interaction Between Components (9 errors)
Category: Risky Resource Management (9 errors)
Category: Porous Defenses (7 errors)

CATEGORY: Insecure Interaction Between Components
CWE-20: Improper Input Validation
CWE-116: Improper Encoding or Escaping of Output
CWE-89: Failure to Preserve SQL Query Structure (aka 'SQL Injection')
CWE-79: Failure to Preserve Web Page Structure (aka 'Cross-site Scripting')
CWE-78: Failure to Preserve OS Command Structure (aka 'OS Command Injection')
CWE-319: Cleartext Transmission of Sensitive Information
CWE-352: Cross-Site Request Forgery (CSRF)
CWE-362: Race Condition
CWE-209: Error Message Information Leak
CATEGORY: Risky Resource Management
CWE-119: Failure to Constrain Operations within the Bounds of a Memory Buffer
CWE-642: External Control of Critical State Data
CWE-73: External Control of File Name or Path
CWE-426: Untrusted Search Path
CWE-94: Failure to Control Generation of Code (aka 'Code Injection')
CWE-494: Download of Code Without Integrity Check
CWE-404: Improper Resource Shutdown or Release
CWE-665: Improper Initialization
CWE-682: Incorrect Calculation
CATEGORY: Porous Defenses
CWE-285: Improper Access Control (Authorization)
CWE-327: Use of a Broken or Risky Cryptographic Algorithm
CWE-259: Hard-Coded Password
CWE-732: Insecure Permission Assignment for Critical Resource
CWE-330: Use of Insufficiently Random Values
CWE-250: Execution with Unnecessary Privileges
CWE-602: Client-Side Enforcement of Server-Side Security

برای مشاهده اصل گزارش اینجا را کلیک کنید.

Verification در برابر Validation

در آوریل 1990، تلسکوپ فضایی هابل به مدار زمین فرستاده شد. هدف اصلی این تلسکوپ فضایی، بزرگنمایی اهداف مورد مشاهده با استفاده از یک آینه بزرگ بود. تولید آینه مزبور امری دشوار و نیازمند صحت و دقت بسیار بالایی بود (رجوع کنید به تفاوت صحت و دقت در مطالب گذشته وبلاگ). آزمایش این آینه از این جهت که قرار بود محیط واقعی آن در فضا باشد، در محل ساخت آن در زمین بسیار مشکل می نمود. در نتیجه تنها راه تست، اندازه گیری دقیق مشخصات محصول ساخته شده و مقایسه آن با مشخصات تعیین شده برای محصول مورد نظر بود. این آزمایشات با موفقیت صورت گرفته و هابل آماده پرتاب اعلام شد.

متاسفانه به محض عملیاتی شدن این تلسکوپ مشخص شد که تصاویر ارسال شده توسط آن به هیچ وجه فوکوس نیست. در تحقیقات صورت گرفته مشخص شد که ساخت آینه به درستی صورت نگرفته است. آینه مزبور بر اساس مشخصات تعیین شده (Specifications) تولید شده بود اما این مشخصات نادرست بوده است. این آینه به طور کامل دقیق (Precise) ساخته شده بود اما از صحت لازم (Accuracy) برخوردار نبود.

آزمایشات تایید کرده بود که آینه مزبور مشخصات لازم را تامین کرده است (Verification) اما درستی خود مشخصات اولیه را مورد بررسی قرار نداده بود (Validation).

به عبارت دیگر Verification به فرآیند مطابقت محصول با مشخصات آن گفته می شود اما Validation فرآیند مقایسه مشخصات محصول با نیازمندی های واقعی کاربر است.

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

اصول اساسی تست نرم افزار

 

 

 

اصل 1: هدف از تست نرم افزار یافتن خطا است، نه اطمینان از درستی کارکرد نرم افزار.

اصل 2: برنامه نویس باید از تست برنامه خود اجتناب کند.

اصل 3: آزمایش موارد قابل انتظار در برنامه نیمی از ماجراست. نیم دیگر آزمایش مواردی است که انتظار میرود برنامه آن را انجام ندهد.

اصل 4: با فرض اینکه هیچ نقصی در برنامه نخواهید یافت تست را آغاز نکنید.

اصل 5: احتمال اینکه اشکالات بیشتری در قسمتی از برنامه کشف شود متناسب با تعداد اشکالات کشف شده  قبلی در آن بخش از برنامه است (به عبارت دیگر هرچه در ماژولی از برنامه خطاهای بیشتری پیدا کنید، احتمال وجود خطاهای دیگر در آن ماژول بیشتر است).

اصل 6: غیر ممکن است که بتوان یک برنامه را به طور کامل تست کرد.

اصل 7: تست نمیتواند نشان دهد که اشکالی وجود ندارد، بلکه تنها قادر است نشان دهد که اشکال وجود دارد!

اصل 8: برنامه پس از مدتی در برابر تستهای تکراری مقاوم خواهد شد (همانگونه که آفت ها پس از مدتی در مقابل یک آفت کش ثابت مصون میگردند).

References:

1.      The Art of Software Testing, Second Edition, Glenford J. Myers, Wiley Pub.

2.      Software Testing, Ron Patton, Sams Pub.

 

صحت در برابر دقت (Accuracy vs. Precision)

 

دو مفهوم صحت و دقت در شکل زیر به خوبی به تصویر کشیده شده اند:

 

 

 

·         شکل بالا – چپ: شلیک ها نه صحیح و نه دقیق است. تیرها به شکل غیر مجتمع بوده و به مرکز هدف نیز نزدیک نیست.

·         شکل بالا – راست: شلیک ها صحیح است اما از دقت کافی برخوردار نیست.

·         شکل پایین – چپ: شلیک ها به شکل مجتمع و دقیق انجام شده اما با هدف فاصله دارد. لذا دارای دقت و فاقد صحت است.

·         شکل پایین – راست: شلیک ها هم از ویژگی دقت و هم صحت برخوردار است.

 

در آزمون نرم افزار، هر چند واضح است که یک آزمون دارای صحت و دقت ایده آل است، اما با توجه به هزینه بالای اجتماع این دو ویژگی، گاهی باید با توجه به ماهیت و نیازمندیهای نرم افزار، یکی از این دو مفهوم را به شکل کم  رنگ تر به کار گرفت.

تولید فاقد خطا

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

 

                                               

 

هر چند ماهیت نرم افزار با دیگر انواع محصولات تاحدی متفاوت است (در جایی خواندم که اجرای ساختمان را به ساخت لگو و تولید نرم افزار را به درست کردن شکلی با خمیر بازی کودکان تعبیر کرده بود)، اما آیا می توان طراحی نرم افزار را طوری انجام داد که احتمال خطای کاربر به صفر برسد؟ آیا در سطح تولید نرم افزار می توان خط تولید را طوری طراحی کرد که احتمال خطای تیم توسعه منتفی گردد؟

رسوایی های ناشی از کاستی در تست نرم افزار (3)

 

اشکال تقسیم با ممیز شناور Intel Pentium (1994)

 

معادله زیر را در ماشین حساب PC خود وارد کنید:

 

(4195835 / 3145727) * 3145727 - 4195835

 

در صورتی که پاسخ صفر است پردازنده شما بدون عیب است. در صورتی که هر پاسخ دیگری مشاهده کردید، پردازنده دستگاه شما یک Intel Pentium  قدیمی است که در کلیه پردازنده های سری ساخت پردازنده شما تکرار شده است.

در 30 اکتبر 1994، دکتر Thomas R. Nicely  از کالج Lynchburg (ویرجینیا) در یکی از آزمایشات خود پاسخ غیر منتظره ای در تقسیم معادله مورد آزمایش بر روی Pentium PC خود مشاهده کرد. وی این کشف را بر روی اینترنت قرار داد و پی از آن خیل عظیمی از دیگر افرادی که در محاسبات خود به مشکل مشابه برخورد کرده بودند این مشکل را گزارش کردند. خوشبختانه این مشکل تنها در محاسبات پیچیده­ نمود پیدا می­کرد و بیشتر برنامه های محاسبه ای تجاری نظیر محاسبه مالیات و سود و زیان به چنین مشکلی برخورد نکرده بودند.

چیزی که این داستان را برجسته می سازد نه اشکال یاد شده، بلکه نحوه برخورد Intel با این مشکل بود:

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

·         هنگامی که این مشکل فاش گردید، Intel از طریق رسانه های جمعی سعی در کم اهمیت نشان دادن مشکل مزبور کرد.

·         شرکت Intel تحت فشار رسانه ها و افکار عمومی اعلام کرد که پردازنده های دارای مشکل را تعویض می کند اما به شرطی که دارنده آن بتواند ثابت کند که از این اشکال متاثر شده است.

پس از آن، موج اعتراض مشتریان خشمگین روانه این شرکت شد. گروه های خبری در اینترنت مملو از نوشته های  اعتراض آمیز شد که خواستار رفع این مشکل از طرف Intel شده بودند و اخبار و نشریات، شرکت Intel را متهم به بی توجهی و بی تفاوتی به خواست مشتریان نمودند.

در نهایت Intel از نحوه برخورد خود با این مشکل عذرخواهی کرده و متحمل هزینه ای بالغ بر 400 میلیون دلار برای تعویض پردازنده های معیوب خود گردید. در حال حاضر Intel کلیه مشکلات شناخته شده را بر روی وب سایت خود قرار می دهد و به دقت بازخورد مشتریان خود را در گروههای خبری اینترنتی دنبال می کند.

رسوایی های ناشی از کاستی در تست نرم افزار (2)

 

کاوشگر مریخ ناسا 1999 (NASA Mars Polar Lander - 1999)

 

در 3 دسامبر سال 1999 کاوشگر مریخ که قرار بود روی سطح کره مریخ فرود بیاید ناپدید شد. هیئت بررسی شروع به تحقیق در مورد علت این امر نمود و مشخص شد که علت، ست شدن نادرست یک بیت (!) بوده است. همه اتهامات متوجه تیم تست نرم افزار این کاشف شد.

برنامه فرود به این شکل تعیین شده بود: در زمانی که کاوشگر باید فرود می آمد، یک پاراشوت (چتر) می بایست باز میشد تا سقوط کاوشگر را کند نماید. چند ثانیه بعد باید سه پایه از زیر کاوشگر خارج می شد و در جهت فرود قرار می گرفت. هنگامی که کاوشگر در ارتفاع 1800 متری مریخ قرار می گرفت، باید پاراشوت رها می شد و موتور فرود وسیله در جهت عکس سقوط روشن می شد تا کاوشگر به آرامی در روی سطح مریخ فرود آید.

یکی از مهترین مسائل در این فرآیند این است که کاوشگر تشخیص دهد که چه زمانی بر روی سطح مورد نظر فرود آمده تا به موقع موتور فرود خود را خاموش کند. برای این منظور ناسا که در دیگر سفینه های خود از رادارهای گرانقیمتی بهره برده بود تصمیم گرفت که برای کاهش هزینه ها، از مکانیزم ساده تری استفاده کند. به این شکل که در زیر سه پایه فرود کاوشگر سوییچ های تماسی (Contact Switch) تعبیه کردند تا به محض برخورد این سوییچ ها با سطح مریخ، یک بیت ست شده و در اثر قطع شدن سوخت، موتور فرود خاموش شود.

هیئت بررسی پس از تحقیق متوجه شد که هنگام باز شدن سه پایه فرود کاوشگر، در اثر لرزش حاصله از این عمل، بیتی که باید پس از تماس با سطح ست می شد به اشتباه ست شده و کاوشگر که تصور کرده به سطح رسیده است موتور خود را خاموش کرده و از ارتفاع 1800 متری سقوط کرده است. به همین سادگی (!)

نتیجه فاجعه بار بود اما علت ساده. کاوشگر توسط تیم های مختلفی مورد آزمایش قرار گرفته بود که هر تیم مسئول تست بخشی از عملکرد کاوشگر بودند. یک تیم فرآیند باز شدن پایه ها را مورد آزمایش قرار داده بود و تیم دیگر فرآیند فرود را از زمان باز شدن پایه ها. تیم اول آزمایش نکرده بود که آیا بیت مورد نظر ست شده است یا خیر. تیم دوم نیز همواره کامپیوتر را Reset می کرده و بیت مورد نظر را به مقدار اولیه برمی گردانده و سپس آزمایش خود را به انجام می رسانده است.

هر دو تیم به طور مجزا کار خود را بدون نقص انجام داده بود اما اشکال مزبور تنها هنگامی بروز میکرد که دو تیم باهم ترکیب شوند  (Integration Test).

 

(منبع: Software Testing,Ron Patton, Sams Publishing, 2005)

رسوایی های ناشی از کاستی در تست نرم افزار (1)

شاید شما هم مثل من فکر کنید: تست نرم افزار حلقه مظلوم و مهجور فرآیند تولید نرم افزار است. بیشتر مدیران به آن علاقه ندارند چون هزینه زیادی می طلبد بدون آنکه خروجی قابل تحویلی به کارفرما داشته باشد و بیشتر برنامه نویسان از آن فراری هستند چرا که آنرا کاری تکراری و خسته کننده میدانند (در نوشته های آتی اشاره خواهم کرد که اساسا این کار نباید توسط مجری تولید نرم افزار انجام شود – البته به استثنای آزمون هایی معدود). هر چه اهمیت و گستردگی استفاده از نرم افزار بیشتر باشد، لزوم به کارگیری آزمونهای مختلف بیشتر احساس می شود. در این نوشته و نوشته های آینده به چند نمونه جالب (و البته دردناک) از اثرات مخرب آزمون ناکافی یا با رویکرد نادرست اشاره خواهم کرد:

 

نرم افزار بازی شیر شاه دیزنی (Disney’s Lion King Game)

در پاییز سال 1994 شرکت دیزنی اولین CD بازی خود تحت عنوان شیر شاه (Lion King) که بر اساس کارتونی به همین نام ساخته شده بود را وارد بازار کرد. بسیاری از شرکتهای دیگر تا آن زمان اقدام به ساخت بازیهای رایانه ای کرده بودند اما این اولین بار بود که شرکت دیزنی وارد این تجارت شده بود. دیزنی برای فروش این بازی دست به تبلیغات گسترده ای زد و در نتیجه این محصول با فروش بسیار بالایی مواجه شد. اما اتفاقات پس از آن تبدیل به کابوسی برای این شرکت شد. در 26 دسامبر، روز پس از کریسمس تلفن های بخش پشتیبانی مشتریان شرکت دیزنی شروع کرد به زنگ زدن و زنگ زدن و زنگ زدن! متصدیان پاسخگویی به تماس ها با خیل عظیمی از والدین عصبانی با بچه های گریان مواجه شدند که ادعا می کرند نرم افزار مزبور کار نمی کند. این خبر به سرعت در مطبوعات و تلویزیون نیز پخش شد و کریسمس آن سال را برای بسیاری از پرسنل دیزنی تلخ کرد.

علت چه بود؟ پس از بررسی مشخص شد که دیزنی نرم افزار خود را بر روی بسیاری از مدل های PC تست نکرده بود و در نتیجه تنها بر روی سیستمهایی کار می کرد که برنامه نویسان دیزنی روی آن سیستم ها نرم افزار خود را توسعه داده بودند و نه دستگاههای متداولی که عموم مردم از آن استفاده می کردند.

 

(منبع: Software Testing,Ron Patton, Sams Publishing, 2005)