
تست کارایی نام عمومی تستهایی است که نحوه رفتار و عملکرد سیستم را تحت بار خاصی بررسی میکنند. این تست به منظور یافتن اشکالات نرمافزاری استفاده نمیشود، بلکه یک تکنیک تست نرمافزاری غیر عملکردی(non-functional) است که تعیین میکند چگونه پایداری ،سرعت ، مقیاس پذیری و پاسخگویی یک برنامه، تحت حجم کاری معینی حفظ میشود. این یک گام کلیدی برای اطمینان از کیفیت نرمافزار قبل از استقرار نهایی آن است. برای سیستمهای بزرگی که تعداد زیادی کاربر همزمان از آن ها استفاده میکنند،اندازهگیری و بررسی نحوه برخورد آنها با حجم بارهای زیاد بسیار حائز اهمیت است. در واقع تست بار نوعی آزمایش کارایی میباشد که تعداد زیادی کاربر همزمان را شبیه سازی کرده و سپس نحوه عملکرد سیستم را در مدت زمان معینی بررسی میکند. در نهایت با آنالیز نتایج میتوان تصمیم گرفت که آیا سیستم عملکرد قابل قبولی خواهد داشت و یا خیر و در صورت عملکرد ضعیف سیستم، میتوان برای بهبود آن برنامهریزی کرد. برای انجام تست بار، چندین ابزار منبع باز وجود دارد که JMeter محبوبترین آنهاست. JMeter یک ابزار متنباز و مبتنی بر Java میباشد که نتایج رفتار مرورگر را با ارسال درخواست به سرورهای وب یا برنامه شبیهسازی میکند.در این پست به آموزش اولیه در مورد نحوه کار با JMeter و همچنین نحوه انجام یک تست بار ساده میپردازیم. جهت آشنایی بیشتر با این ابزار و اطلاع از مزایا و معایب آن میتوانید به مقاله مقدمه و آشنایی با جیمیتر و مزایا مراجعه کنید.
در این مقاله برای آموزش بهتر سعی میکنیم یک تست بار ساده را بر روی یک سیستم واقعی انجام دهیم. سیستم مورد آزمون ما در اینجا سایت دیوار است. با ورود به صفحه فروش آپارتمان در مرورگر خود یک درخواست از نوع HTTP با متد Get به سمت سرور ارسال و پاسخ آن از سرور دریافت میشود. با مراجعه به بخش developer tools در مرورگر خود میتوان URL مربوطه را مشاهده کنید. این آدرس به صورت زیر است:
https://api.divar.ir/v8/web-search/tehran/buy-apartment
با توجه به این که تعداد کاربران زیادی به صورت همزمان از این صفحه استفاده میکنند تا لیست آگهیهای فروش آپارتمان را در سایت دیوار مشاهده کنند، قصد داریم که فرایند تست بار بر روی این درخواست را بررسی کنیم. یعنی کاربران مجازی را شبیهسازی کنیم که بصورت همزمان به این آدرس مراجعه کرده و از صفحه « فروش آپارتمانهای دیوار» دیدن میکنند.

در ابتدا نیاز است که جیمیتر را دانلود و راهاندازی کنید. برای آشنایی کامل با این مرحله میتوانید از مقاله نصب و پیکربندی جیمیتر استفاده نمایید.
پس از اجرای جیمیتر صفحهای مشابه شکل زیر نمایش داده میشود که شامل یک Test Plan میباشد. Test Plan کامپوننت اصلی جیمیتر است، در واقع مانند ظرفی است که شامل المانهای مورد نیاز برای اجرای تست میباشد و جریان تست بار شما را نمایش میدهد. یک Test Plan کامل از یک یا چند المان مانند Thread Group ،Logic Controllers، Samplers، Listeners، Timers، Assertions و Configuration Elements تشکیل میشود. در نظر داشته باشید که هر Test Plan باید حداقل یک Thread Group داشته باشد.

Thread Group جریان کاربران و رفتار آنها را در برنامه شبیهسازی کرده و تعداد آنها را در طول تست کنترل میکند. در واقع هر thread نشان دهنده یک کاربر است. Thread Groupهای متعددی در دسترس هستند که نحوه تعامل کاربران با برنامه ، چگونگی حفظ بار و مدت زمان اجرا را شبیهسازی میکنند. برای ساخت و طراحی یک تست ابتدا یک Thread Group به Test Plan اضافه کنید. روی Test Plan کلیک راست کرده و از مسیر Add ->Threads (Users) ->Thread Group آن را به تست اضافه کنید.

سپس Thread Group را با توجه به نیازمندی های خود پیکربندی کنید:

برای ارسال درخواست های مختلفی به سرور و دریافت نتیجه به Thread Group اضافه میشود. از آنجا که Sampler بعد از ارسال درخواست و دریافت نتیجه، متریکهایی همچون درستی این عمل، زمان طول کشیدن عملیات و جزيبات دیگری را ثبت میکند به آن نمونهگیر میگویند. در واقع از مجموع نمونههای جمعآوری شده در طول آزمون در نهایت نتایج آزمون استخراج میشود. JMeter از تست HTTP ، FTP ، JDBC و بسیاری از پروتکلهای دیگر پشتیبانی میکند. با توجه به اینکه ما میخواهیم یک HTTP Request ارسال کنیم، بنابراین یک HTTP Request Sampler به Thread Group اضافه میکنیم. روی Thread Group کلیک راست کرده و از مسیر Add -> Sampler ->HTTP Request آن را به تست خود بیافزایید.

برای تکمیل مثال تست سایت دیوار، در این بخش نیاز است که برای درخواست دریافت لیست آگهی ها یک HTTP Request را به Thread Group اضافه کنید. سپس Sampler خود را با توجه به موارد زیر تنظیم کنید (در عکس زیر مقادیر لازم برای این بخش نشان داده شده است):

با استفاده از Configuration Element می توان پیش فرض ها و متغیرهایی که توسط Sampler استفاده میشوند را ایجاد کنید. آنها قبل از هر Sampler ای که در یک scope قرار دارند اجرا میشوند.اگر یک Config Element در یک node از یک درخت تعریف شده باشد در زمان اجرا اولویت بیشتری نسبت به Config Element مشابه خود در لایه های بالاتر دارد. همچنین یک Config Element فقط داخل شاخه ای که در آن قرار دارد قابل دسترسی است.طبق شکل زیر، از مسیر Add -> Config Element می توان انواع Config Element ها را به Sampler اضافه کرد.

Config Elementها انواع مختلفی دارن که یکی از مهمترین آنها HTTP Header Manager است. در هر HTTP Header Manager میتوان هدرهای مورد نیاز هر درخواست رامشخص کرد. در هنگام ارسال هر درخواست به سرور، این مقادیر در بخش هدردرخواست به سرور ارسال میشوند. انواع مختلفی از هدرها موجود میباشد که میتوان به User-Agent، Accept، Content-Type و … اشاره کرد. این مقادیر را میتوانید در بخش Request Header در تب Network مشاهده کنید.

در ادامهی تکمیل مثال سایت دیوار، برای تنظیم کردن Header درخواست، یک HTTP Header Manager به Sampler اضافه کردیم و هدرهای مورد نیاز را مشخص نمودیم.

Assertionها به شما اجازه می دهند پاسخ درخواستهایی که به سمت سرور ارسال کردید را ارزیابی و تایید کرده و برای مقایسه نتیجه واقعی و نتیجه مورد انتظار تست از آن ها استفاده کنید. انواع مختلفی Assertion وجود دارد که برای اهداف خاصی طراحی شدهاند. برای اضافه کردن آن، روی Sampler کلیک راست کرده و از مسیر Add -> Assertions یک Assertion به Sampler اضافه کنید. درخواست دریافت لیست آگهیهای سایت دیوار اگر با موفقیت اجرا شود response code آن برابر 200 خواهد بود. بنابراین یک Response Assertion اضافه میکنیم و مقادیر فیلدهای آن را طبق شکل زیر مشخص میکنیم:

پس از اجرای این درخواست، اگر response code چیزی غیر از 200 باشد، این Assertion رد میشود و مشخص میشود که این درخواست به درستی اجرا نشده است و به عنوان خطا در نتایج ثبت میشود. سپس میتوانید علت اجرای نادرست را بررسی کنید.همچنین میتوانید Response Message و موارد دیگری را هم با استفاده از این Assertion ارزیابی کنید. مثلا اینکه در پاسخ عبارت مورد انتظاری وجود داشته باشد.
وقتی کاربران با وب سایت یا برنامه شما کار می کنند ، طبیعتاً مکث و تاخیر دارند. این زمان را میتوان با تایمر شبیهسازی کرد. با کمک تایمر میتوانید مدت زمان تاخیر را از یک درخواست به درخواست دیگر تنظیم کنید. گاهی به این زمان تاخیر بین درخواستهای کاربر زمان تفکر یا thick time نیز میگوییم. مثلا چه مدت زمانی برای انتقال از صفحه اصلی به صفحه دیگر نیاز دارید. Constant Timers یا تایمرهای ثابت یکی از پرکاربردترین تایمرها محسوب میشود. روی HTTP Request کلیک راست کرده و از مسیر Add -> Timers -> Constant Timers آن را انتخاب کنید. در این مثال ما 300 میلی ثانیه بین هر درخواست صبر میکنیم.

پس از اجرای تست نتایج را میتوان با استفاده از Listener ها مشاهده نمود. شنوندهها درواقع به سمپلهای گرفته شده گوش میدهند و میتوانند آنها را جمعآوری کنند، آنها را نمایش دهند یا نتایج کلی و جزئی آزمون را از آنها استخراج کنند. آن ها را میتوان به هر کدام از کامپوننتها از جمله Thread Group اضافه کرد. Listener ها انواع مختلفی دارند که نتایج را میتوانند به صورت درخت، جدول، گراف و یا در یک فایل نمایش دهند. View Results Tree یکی از رایجترین آنها میباشد که نتایج را بصورت جزیی نمایش میدهد. برای تکمیل مثال خود، با کلیک راست روی Thread Group و از مسیر Add -> Listeners ->View Results Tree میتوان آن را به Thread Group افزود. همچنین ما یک Summary Result هم اضافه میکنیم که وظیفه آن استخراج نتایج خلاصه و کلی آزمون است. در این listener سطری به تفکیک درخواستها و یا تراکنشها ایجاد میشود و نتایج را برای تمام درخواستهای مشابه به صورت خلاصه نشان میدهد.

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

اکنون برای اجرای تست بر روی دکمه start که در شکل زیر نشان داده شده است، کلیک میکنیم. (همچنین توجه کنید که در صورتی که قبلا تست را اجرا کردیم و دوباره میخواهیم اجرای جدیدی انجام دهیم، میتوانیم با زدن دکمه clear که با آیکون یک جارو نشان داده شده است، نتایج تست قبلی را پاک کنیم تا بتوان نتایج اجرای جدید را بصورت مشخص مشاهده کرد.)

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

طبق شکل، بخشی از درخواستها با رنگ قرمز مشخص شدند. یعنی اجرای آن ها موفقیت آمیز نبوده است. در Assertion مشخص کرده بودیم که باید Response Code برابر 200 باشد ولی در اینجا Response Code 429 (Too Many Requests) دریافت کردیم. در نتیجه Assertion با شکست مواجه شده است. ارور دریافتی به این دلیل است که اگر تعداد درخواستهای ارسالی از یک ip از حدی بیشتر شود سایت آنها را بلاک میکند و به آنها پاسخ نمیدهد.

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

همانطور که در تصویر بالا مشخص است این درخواست به تعداد 816 مرتبه به سرور ارسال شده است. در هر تست پارامترهای توان خروجی(Throuput)، متوسط زمان پاسخ (Average Response Time) و نرخ خطا (Error Rate) از اساسیترین و ابتداییترین نتایج تست کارایی میباشند. توان خروجی به تعداد درخواستهایی که به سرور ارسال میشود در واحد زمان گفته میشود که در این مثال برابر 13.5 میباشد. همچنین زمان پاسخ زمانی است که طول میکشد سرور به درخواست ارسالی پاسخ دهد. هر چه زمان پاسخ کمتر باشد کارایی سیستم بیشتر است. در تست اجرا شده این زمان برابر با 375 میلی ثانیه میباشد. همچنین نرخ خطا باید در کمترین میزان ممکن باشد تا تست کارایی موفقیت آمیز باشد. نرخ خطا به نسبت تعداد درخواستهایی که با خطا مواجه شدهاند به تعداد کل درخواستها گفته میشود. این مقدار همیشه به صورت درصد مشاهده میشود که در این تست 95.22٪ است. بنابراین نتیجه گرفته میشود سیستمی که نرخ خطا و زمان پاسخ کم و توان خروجی بالایی داشته باشد کارایی بالاتری دارد.