تست End-To-End یک روش متداول برای تست این موضوع است که آیا جریان یک برنامه همانطور که طراحی شده است از آغاز تا پایان اجرا میشود یا خیر. هدف از انجام تستهای End-To-End یافتن و شناسایی وابستگیهای سیستم و حصول اطمینان از این موضوع است که آیا اطلاعات مناسب بین کامپوننتهای سیستمی مختلف و بین زیر سیستمها تبادل میشود یا نه.
یکی از بزرگترین چالشهایی که در پروژههای خود با آن مواجه هستم، دستکاری مناسب دادههای تست(Test Data) در تستهای خودکار و به ویژه در اتوماسیون End-To-End است. برای تست Unit و Integration، یک ایده خوب اغلب متوسل شدن به ماک کردن(Mocking) یا خراش دادن لایه دادهها برای کنترل دادههای آزمون است. این دادهها در تست مورد استفاده قرار گرفته و برای اجرای تستها مورد نیاز هستند. با این حال، هنگام انجام تستهای End-To-End، نگه داشتن تمام Test Dataهای مورد نیاز در وضعیت Check in آن هم در حالت تست اتومات کار آسانی نیست. اینجا راجع به”حالت خودکار” صحبت میکنم، زیرا هنگامی که شما بر مداخله دستی جهت آمادهسازی و یا پاکسازی دادههای تست تکیه میکنید، خود را از توانایی تست بر اساس درخواست(Test On Demand) دور میکنید، که این موضوع به طور کلی خوب نیست. اگر میخواهید تستهای خود را به طور واقعی بر اساس تقاضا اجرا کنید، نیاز به تکیه بر شخص(یا یک فرآیند ثالث) برای مدیریت دادههای تست میتواند یک تنگنای جدی باشد. حتی بیشتر برنامههای توزیع شده، که در آن تیمها اغلب به اندازه کافی روی وابستگیها کنترل ندارند، باز هم نیاز دارند قادر به انجام تست End-To-End(یا حتی Integration) باشند.
در این پست، میخواهم تعدادی از استراتژیهای ممکن برای مواجهه با دادههای تست در آزمونهای End-To-End را مطرح نمایم. به همین دلیل نگاهی خواهیم داشت به مزایا و نقاط ضعف آنها تا به این ترتیب ببینیم آیا یک استراتژی که همه چیز را دربر بگیرد وجود دارد یا خیر(احتمالا نه).
ایجاد دادههای تست در هنگام اجرای تست
یک رویکرد شروع برای هر تست، Test Suite یا اجرای تست، در نظر گرفتن یک مرحله ستاپ است که در آن دادههای تست مورد نیاز برای آن تست، Test Suite یا اجرای خاص ایجاد میشوند. این را میتوان با هر وسیله فنیِ در دسترس انجام داد: از طریق INSERT مستقیم در یک پایگاه داده، یک سری درخواست API Call که کاربران جدید را ایجاد میکند، Orderها یا هر نوع Test Data Object، یا(اگر هیچ جایگیزینی وجود ندارد) از طریق User Interface. مزیت اصلی این رویکرد این است که یک اتصال و جفت شدگی قوی بین Test Dataهای ایجاد شده و تست واقعی وجود دارد، به این معنی که Test Data درست همیشه در دسترس است. اما در این روش، مشکلات بزرگی نیز وجود دارد:
- ستاپ کردن Test Dataها زمان بیشتری را صرف میکند، به ویژه وقتی که از طریق User Interface انجام میشود.
- ستاپ کردن Test Dataها نیاز به کد اضافی دارد، که باعث افزایش مسئولیت نگهداشت(Maintenance) تستهای خودکار شما میشود.
- اگر یک خطا در طول دوره ستاپ کردن Test Data رخ دهد، نتیجه تست واقعی(Actual Test Resukt) شما غیر قابل پیش بینی بوده و بنابراین قابل اعتماد نخواهد بود. این بدین معنیست که شما آرزو خواهید کرد کاش تست شما قبل از اجرای کل مراحل تست به صورت کامل، به سادگی در میانه راه شکست بخورد…
- این رویکرد به طور بالقوه نیازمند تستهاییست که به لحاظ توالی در اجرا به یکدیگر متصل باشند و البته این یک ضد الگوی قطعی در اتوماسیون تست است.
من این رویکرد را چندین بار در پروژههای خودم با نتایج ترکیبی استفاده کردهام. گاهی اوقات خوب است، و گاهی اوقات کمتر. این مورد اغلب زمانی به کار میآید که مدل داده واقعا پیچیده است و روش دیگری برای تقلید از تعامل کاربر با استفاده از ابزارهایی مانند Selenium برای تهیه دادهها وجود ندارد.
Query کردن Test Data قبل زا اجرای آزمون
روش دوم برای مواجهه با Test Dataها پیرامون تستهای خودکار، Query کردن دادهها قبل از تست واقعیست. این کار میتواند به صورت مستقیم بر روی پایگاه داده و یا احتمالا از طریق یک API(یا حتی یک User Intefrace) انجام شود که به شما امکان میدهد که مثلا در یک سیستم مالی مشتریها، آرتیکلها یا هر شیء دادهای که برای تست نیاز دارید را بازیابی کنید. مزیت اصلی چنین رویکردی این است که در شرایطی که همه آن چیزی که مورد توجه شماست Test Result است، شما زمان خود را برای ساخت Test Data از دست نمیدهید. به علاوه این رویکرد منجر به نگهداشت(Maintenance) کمتر روی کد Test Automation میشود، مخصوصا زمانی که میتوانید به طور مستقیم از پایگاه داده Query بگیرید. در اینجا نیز چند معضل وجود دارد که منجر میشود این رویکرد هم ایدهآل نباشد:
- هیچ تضمینی وجود ندارد که داده دقیقی که شما برای یک Test Case(به ویژه با موارد لبه) نیاز دارید در پایگاه داده موجود باشد. برای مثال، به طور واقعی چند مشتری در ۱۷٫۵ سال گذشته در فلان شهر همراه با همسر و طوطی آبی خود زندگی کردهاند، که در پایگاه داده شما وجود داشته باشد؟
- گاهی اوقات گرفتن Query درست برای حصول اطمینان صد درصدی از اینکه Test Data درست را دریافت کردهاید یک کار دیوانه کننده است که نیاز به دانش خاص و عمیقی روی سیستم دارد. این ممکن است باعث شود این روش برای برخی تیمها خیلی هم ایدهآل نباشد.
- علاوه بر این، حتی زمانی که Query دقیقی درست میکنید، آیا واقعا تضمینی وجود دارد که شما نتایجی را خواهید یافت که ۱۰۰٪ مطمئن باشید برای Test Case شما مناسب هستند؟
وضعیت Test Data را قبل یا بعد از اجرای تست تنظیم کنید
من فکر میکنم این روش به صورت بالقوه بهترین روش برای مواجهه با Test Dataها در تستهای End-To-End است:
“تنظیم پایگاه داده Test Data به وضعیت دقیق و مورد نظر ما بوسیله Restore کردن Database Backup یا پاکسازی پایگاه داده تست پس از انجام تست”.
این موضوع Test Data درستی را تضمین میکند، که همیشه در همان حالت قبل/بعد از اجرای تست قرار دارد. این کار به شدت پیشبینی پذیری و تکرار تستهای شما را بهبود میبخشد. اشکال اصلی این است که اغلب، در این گزینه کسی که به اندازه کافی در مورد مدل دادهای شناخت ندارد که مجاز به انجام آن باشد، و یا دسترسی وی به پایگاه داده به دلایلی محدود شده است. همچنین هنگامی که شما با پایگاههای دادهای بزرگ برخورد میکنید، بازنشانی(Reset) پایگاه داده یا عقبگرد(Rollback) آن ممکن است چند ساعت طول بکشد، که به طور قابل توجهی حلقه بازخورد شما را کند میکند و هنگامی که تستهای شما بخشی از یک مسیر تحویل مداوم(Continuous Delivery Pipline) است، نمیتوانید بر این منوال حرکت کنید.
مجازیسازی لایه داده(Data Layer)
امروزه راهکارهای متعددی در بازار وجود دارد که به شما اجازه میدهد به طور موثر لایه داده خود را برای اهداف تست مجازیسازی کنید. یک مثال ساده از چنین راهکاری، Delphix است، اما در بازار نیز چندین ابزار دیگر وجود دارد. من هیچکدام از اینها را برای مدت طولانی تجربه نکردم تا بتوانم یک دیدگاه آموزشی ارائه دهم، اما چیزی که واقعا درباره این رویکرد دوست ندارم این است که مجازیسازی لایه داده(با وجود اینکه کارآمد است)، مفهوم اجرای یک تست End-To-End را تهی میکند، زیرا هیچ لایه داده واقعی در آن وجود ندارد. ممکن است برای انواع دیگر تست، چنین موضوعی یک مفهوم بسیار خوب باشد، درست همانطور که مجازیسازی سرویس برای شبیهسازی رفتاری روی وابستگیهای حیاتی Hard-To-Access(مثلا تست یک امکان سیستم کارگزاریهای بورسی که باید به هسته معاملات دسترسی داشته باشند) خوب است، چرا که انجام آن به سختی در محیط های تست قابل اِعمال است.
پس چه کار کنیم؟
به طور خلاصه، من هنوز راه حل ایدهآل و بدون مشکل پیدا نکردهام. واقعا دوست دارم در مورد رویکردهایی که افراد دیگر و تیمها در مورد مدیریت دادههای تست در تستهای اتوماتیک End-To-End انجام دادهاند مطلب ببینم و بخوانم. امیدوارم در این رابطه با هم تماس داشته باشیم. شما میتوانید با ارسال ایمیل به آدرس a.dizaji@tisten.ir با بنده در تماس باشید.