خلاصه: تست API مبتنی بر داده(Data-Driven API Testing) این قابلیت را دارد که منجر به بازخورد سریعتر در طول توسعه نرمافزار شود. روشهای زیادی برای تست API وجود دارد که نباید از آن ترسید. تسترها که به دنبال ارتقای حرفهای خود هستند باید به منظور تست برنامههای خود در سطح API، توجه خاصی به برنامهنویسی داشته باشند.
تست نرمافزار دارای انواع مختلفیست اما مهمترین تمایز بین گونههای مختلف تست، دیدگاه موجود در تست نرمافزار است. این بدین معنیست که دیدگاه تست، مبتنی بر کد باشد یا دیدگاه مبتنی بر تعامل با محصول. در صنعت تست دو دیدگاه مشهور به نام دیدگاه مبتنی بر جعبه سیاه(Black Box) و دیدگاه مبتنی بر جعبه سفید(White Box) وجود دارد. در دیدگاه مبتنی بر جعبه سیاه، تنها ورودی و خروجی حائز اهمیت است، در حالیکه در دیدگاه مبتنی بر جعبه سفید علاوه بر ورودی و خروجی آنچه در داخل جعبه اتفاق میافتد نیز مهم است.
در حال حاضر سیستمهای نرمافزاری مدرن به صورت جعبههایی تو در تو هستند. در این راستا برنامهنویسان از کتابخانههای ثالث(Third-Party Library) بدون دانش در مورد کد آنها استفاده میکنند. محصولات از طریق پروتکلهای Integration با هم در ارتباط هستند و در همان زمان، بازخورد تست(قبل از اینکه محصول دارای یک UI شود) نیز مورد نیاز است. بعضی محصولات مانند محصولات IoT(اینترنت اشیا) از قبیل Wearableها فاقد UI هستند.
در حالیکه از این منظر برنامهنویسان مسئولیت تست محصول را دارند اما تسترها نیز قصد دارند با استفاده از تکنیکهای بیشتری در زمینه تست، ارزش کار خود را افزایش دهند. این شامل استفاده از ابزارهای توسعه و یادگیری برنامهنویسی برای انجام یک کدنویسی اندک به منظور تست برنامهها در سطح API است.
مقدمهای سریع برای تست API
API، یک مجموعه از قوانین تعریف پروتکل بین جعبههای نرمافزاری میباشد. تست API نیز نوعی تست جعبه سیاه است که به معنی تست تعامل با یک Function است که(با در نظر گرفتن این موضوع که هیچ دانشی در مورد آنچه در داخل جعبه اتفاق میافتد وجود ندارد) بواسطه ارزیابی ورودی و خروجی میباشد.
Internet Applicationها از Web Service API در فرمت پروتکلهای SOAP و یا REST استفاده میکنند. اگر چه از نظر برنامهنویسان این دو پروتکل دارای تفاوتهای فنی و معماری بسیاری هستند اما از منظر تسترها این دو پروتکل هر دو در جعبه سیاه قرار میگیرند. از نظر ورودی و خروجی هر دو پروتکل از فرمت مبتنی بر متن(Text-Based) استفاده میکنند. SOAP از فرمت XML استفاده میکند، در حالیکه REST ازفرمت JSON بهره میگیرد. یادگیری هر دو فرمت آسان است. تسترها به منظور آمادهسازی ورودی و ارزیابی خروجی باید خواندن و نوشتن فرمت قابل استفاده هر پروتکل را بیاموزند.
فرض کنید فرم وب با فیلدهای دادهای نام، نام خانوادگی و تاریخ تولد مشخص شده است. در ارتباط با ورودی تست تسترها به جای استفاده دستی، نیاز به آمادهسازی داده به شکل زیر دارند. قطعه داده در XML به شکل زیر است:
<firstname> John </firstname>
<lastname>Smith</lastname>
<dob>1980/06/04</dob>
قطعه داده JSON به شکل زیر است:
{
” firstname “:” John ”
” lastname “:” Smith ”
” dob “:”1980/06/04”
}
همانطور که میبینید، نمونهها برای شروع کار بسیار آسان هستند.
روشها و ابزار برای تست API
چندین روش برای تست API وجود دارد. در سادهترین حالت، شما میتوانید نشانی(URL) وبسرویس را در خط آدرس مرورگر مقداردهی کرده و پاسخ آن را در خروجی مرورگر مشاهده کنید. افزونههای اساسی و پیشرفته به صورت رایگان در مرورگرهای محبوب در دسترس هستند. همچنین ابزارهای مستقل و رایگان و به صرفه در مرورگرها ارائه شده است. در نهایت چارچوب خودکارسازی(Automation Framework) وجود دارد که از زبانهای مختلف پشتیبانی میکند.
در ادامه، مثالی آورده شده است که استفاده از افزونه مرورگر فایرفاکس را برای قراردادن یک درخواست(Request) و بررسی پاسخ از سرویس آنلاین رایگان JSON TEST را نمایش میدهد.
هر متدی ارزش خود را دارد. اغلب اوقات نیاز به چند تست سریع و غیرتکراری با استفاده از روشهای ساده و ابزار صحیح است. اگر بعد از هر تغییر کد و استقرار نیاز به تست مداوم(Continuous Testing) باشد، بهتر است از ابزار پیشرفته و خودکارسازی تست استفاده شود.
در اینجا نقطه اشتراکی، ریسکها هستند. در این راستا تمامی تستها با ارزیابی صریح و یا ضمنی ریسک انجام میشوند. گاهی اوقات تغییر کد در یک قسمت، اثرات مخربی را در قسمتهای دیگر محصول اعمال میکند. پس باید پس از اعمال تغییرات با استفاده از تکنیکهای تست نرمافزار، محصول مورد بررسی مجدد قرار گیرد.
در ارتباط با یک API Component مانند وبسرویس اساسیترین سوال، این است که آیا وبسرویس در حال اجراست یا نه؟ این سوال را میتوان با استفاده از فراخوانی API پاسخ داد. در صورت مثبت بودن پاسخ، ممکن است توسعهدهندگان در مورد درستی و نادرستی ورودی و نتایج مورد انتظار سوال کنند. این سوالات ممکن است مورد به مورد با ترکیبات دادهای مختلف بیشتر تصفیه شوند.
طراحی تست و اجرا
طراحی تست برای پاسخگویی به این سوالات است. در واقع طراحی و شبیهسازی تعاملات مختلف API برای بررسی رفتار آنهاست.
اگر سوالات خود را از پایه سازماندهی کنیم، با یک دستهبندی به شکل زیر مواجه خواهیم شد:
دسترسپذیری
این مورد به بررسی در دسترس بودن یک API Function خاص میپردازد. این را میتوان با یک فراخوانی API پاسخ داد.
Functionality
بررسی اینکه آیا دنبالهای از API Callها که در یک سناریو کار میکنند در دسترس نبوده و یا نادرست رفتار میکند. این کار با نگرش کم عمق، اما گسترده انجام میشود.
مثال ۱٫ یک مثال پیمایش مداوم نقشه است، و این در حالی انجام میشود که اپلیکیشن نقاط مورد علاقه در اطراف میدان دید شما را به تصویر میکشد. این عملیات با دنبالهای از فراخوانی APIهایی انجام میشود که یک موقعیت جغرافیایی را تغذیه میکنند.
مثال ۲٫ یک مثال دیگر میتواند ارسال یک درخواست جستجو در یک فروشگاه آنلاین، بررسی نتایج جستجو و بازیابی اطلاعات یک مورد یافت شده باشد. این عملیات با دنبالهای از فراخوانی APIهایی شبیهسازی میشود که ممکن است دادههای بازیابی شده از فراخوانی قبلی را به عنوان پارامترهایی برای فراخوانی بعدی استفاده کنند.(مثلا “item id”).
همچنین پوشش گسترده، به بررسی این موضوع میپردازد که آیا فراخوانیهای معمولی مانند دادههای معتبر، منجر به یک پاسخ نادرست(یا در برخی موارد نادرست) میشود یا خیر؟ این موضوع در حقیقت همان تست مثبت است.
پارامترهای ورودی
ورودی، موردیست که هنگام ارسال فراخوانی به یک API Function ارسال میشود. تست از منظر ورودی نیاز دارد همه نوع دادههای ورودی را پوشش دهد، از جمله تمام کلاسهای هم ارزی(Equivalence Class) اعم از ورودی معتبر و ورودی نامعتبر .
برای مثال، تست نقاط مرزی(Boundary Testing) برای فیلد عددی، شامل تست کمترین نقطه مرزی، یک نقطه کمتر از نقطه مرزی، بیشترین نقطه مرزی و یک نقطه بیشتر از نقطه مرزی است.
همچنین شما میتوانید تست انواع دادهها را با درست و یا نادرست بودن قالب، صحت رمزگذاری و سایر قوانین کسب و کاری سیستم انجام دهید. برای مثال برای تست پارامتر ID در وبسرویس GetUserByID نیاز به دنبالهای از فراخوانیهای زیر است:
- مقداردهی ID معتبر
- بدون ID(ورودی Null)
- مقداردهی با ID غیرعددی
- مقداردهی ID به صورت معتبر اما غیرمستقیم
- مقداردهی ID به صورت معتبر با کمترین تعداد کاراکتر
- مقداردهی ID به صورت معتبر با بیشترین تعداد کاراکتر
پارامترهای خروجی
دادههای Return شده از فراخوانی API، خروجی نامیده میشوند. دادهها ممکن است در فرمتهای مختلف مانند Response Code، Response Header، و Response Body توسط وبسرویس Return شوند.
تست کردن روی جنبههای خروجی نیاز به بازتولید انواع خروجی دارد. برای ایجاد یک خروجی دلخواه باید بدانید چه Requestای داده شده است که خروجی موردنظر تولید گردیده است. در این راستا استفاده از پایگاه داده به شما کمک میکند. مثلا برای Web Serviceها، شما باید تمامی HTTP Response Codeها پاسخ داده شده را باز تولید کنید.
هر بار که یک مجموعه داده Return میشود، مواردی مانند none، one و max تولید میشود. به عنوان مثال، نتیجه جستحوی فروشگاه آنلاین را بررسی کنید که لیستی از موارد مورد نظر را نمایش میدهد. این لیست میتواند خالی باشد، یا تنها یک مورد در خروجی نمایش داده شود و یا ممکن است دادههای Return شده از حداکثر تعداد قابل نمایش در یک صفحه بیشتر باشند. برای مواردی که ممکن است خروجی لیست خیلی بزرگ باشد، میتواند منجر کندی و یا حتی اختلال(Crash) در Front-End سیستم شود.
وضعیت سیستم(System State)
آیا تا به حال مواردی مانند “پربینندهترین مقاله” و یا “بیشترین مورد جستجو” را مشاهده کردهاید؟ همانطور که مشتریان از نرمافزار استفاده میکنند، آمارِ جمعآوری شده بر رفتار سیستم تاثیر میگذارد. تاثیرات دیگری بر روی وضعیت سیستم نیز وجود دارد که در این ارتباط میتوان به نشت حافظه، سرریز بافر و صف(Queue) و موارد مشابه دیگر اشاره کرد.
تست جریان(Flow Testing)
یک جنبه ویژه تست، شبیهسازی استفاده مداوم از API است. فرض کنید کاربران دائما در فروشگاه آنلاین جستجو کنند. هدف از این شبیهسازی، اعتبارسنجی یک مورد خاص نیست بلکه ردیابی این موضوع است که آیا نرمافزار به طور مداوم در طول زمان پاسخ میدهد و یا اینکه با بروز خطاهای مختلف، سیستم متوقف میشود.
قابل ذکر است که تست جریان، شامل شبیهسازی فراخوانی Interruptها و Time-Out میباشد. اگر سیستم شما دارای Functionalityهایی برای مردودسازی(Rejection) و عقبگرد(Rollback) تراکنشها(Transaction) است، حتما اطمینان حاصل کنید که آنها را Reproduce(تولید مجدد) کردهاید، و علاوه بر آن آنچه با این رکوردهای دادهای اتفاق افتاده است را Verify(تائید) نمایید. همچنین نیاز است تا بررسی شود که چه اتفاقی برای دادهها رخ داده است. فرض کنید شما قصد رزرو آنلاین بلیت یک فیلم سینمایی را دارید. به طور معمول این سناریو از دنباله عملیاتی مشتمل بر انتخاب فیلم، تاریخ و زمان انتخابی، انتخاب صندلی و پرداخت هزینه بلیت تشکیل شده است. به محض انتخاب صندلی، آنها رزرو میشوند. حال اگر عملیات پرداخت با موفقیت انجام نشود، چه تعداد صندلی به دلیل رزرو نادرست یا جعلی بلااستفاده خواهند بود؟ برای رفع چنین مشکلی و برای پاس شدن هر مرحله از عملیات، زمانی تعیین شده است که اگر فراخوانی نهایی طی آن مدت با موفقیت انجام نشود، باید تمامی رزروها کنسل شده و بدین ترتیب مشتری الزامی بر پرداخت صورتحساب نخواهد داشت. در حالی که از طریق API، تست را انجام میدهید، باید اطمینان حاصل کنید که موقعیتهایی مثل این را مجدد تولید و بررسی کردهاید. همچنین باید بررسی کنید که سیستم چگونه Time-Out را اداره کرده و Rollback میکند.
یکی دیگر از جنبههای معمول، تست با حجم زیادی از اطلاعات ورودی و خروجی است. این تست با تزریق یکباره حجم زیادی از اطلاعات یا تزریق مستمر دادهها برای یک Request صورت میپذیرد. این تست مشابه با تست وضعیت سیستم است اما در اینجا تمرکز بر میزان دادهایست که سیستم باید آنرا مدیریت کند.
ساختار موردنیاز شما برای تست API
لیست ایدههای طراحی تست که در بالا ذکر شد ممکن است ترسناک به نظر برسد، اما این به این دلیل است که ما نمونههای بسیار گستردهای را که برای بسیاری از ریسکها مورد استفاده قرار گرفتهاند، بررسی کردیم. در عمل سطح پوشش شما احتمالا محدودتر خواهد بود.
عاقلانه است که تست Functionهای اصلی سیستم را سریعتر انجام داده و زمان بیشتری را صرف بررسی جنبههای حیاتی یک محصول کنید. در این حالت همانطور که پروژه توسعه نرمافزار گسترش یافته و وسیعتر میشود، وجود مدل ساختاری برای رفع ریسکها و اولویتها و نظارت بر این موضوعات ضروری مینماید.
سلام
ممنونم از مطلب دقیق و جزئی تان. منتظر مقاله های بیشتر هستیم
سلام
مرسی خیلی مقاله سودمندی بود.
باتشکر.