یکشنبه , ۳۰ اردیبهشت ۱۴۰۳

تست بازنویسی نرم‌افزار

Software Rewriting
Software Rewriting

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

as-is System(سیستم موجود) ما را به جایی می‌برد که می‌خواهیم برویم، اما چیزی که ما بدان نیاز داریم to-be System(سیستم آتی) است تا بدینوسیله همان کارها را به صورت موثرتر انجام دهد.

من چند سال پیش با یک Code-Base مواجه شدم. باید گفت که کد بدی نبود؛ کد مذبور با بهترین ابزار موجود در زمان خود ساخته شده بود. اما با گذشت زمان، استانداردهای تجربه کاربری(User Exprience-UX)، سازگاری(Adaptability)، تست، و نگهداشت‌پذیری(Maintainability) به طور چشمگیری افزایش یافته بود. ابزار قدیمی در برآوردن این خواسته‌های جدید ناتوان بود. علاوه بر این، as-is System بدون هیچگونه Unit Test نوشته شده بود. این قابل درک است، زیرا توسعه تست محور(Test Driven Development-TDD) در آن زمان چیزی نبود که امروز هست.

پس از مدتی ذینفعان به بازنویسی نرم‌افزار مذبور با استفاده از ابزارهای جدید و بهترین شیوه‌های فعلی موافقت کردند. ممکن است شما نیازمندی‌ها را اینچنین ببینید: “همان کاری را انجام دهید که سیستم قدیمی انجام می‌دهد، اما آنرا به شکلی جدید و پر زرق و برق انجام دهید.”

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

هر چه سیستم موجود شما جدیدتر باشد، خوش‌شانسی شما محتملتر است. ممکن است پیاده‌سازهای as is System در زمان بازنویسی همچنان در دسترس باشند، تا بتوان با آنها صحبت کرد. چنین چیزی قطعا از خوش اقبالیست.

اما فرض کنید ما درگیر بازنویسی سیستمی هستیم که ذینفعان هیچ یک از اسناد مهندسی اصلی را ندارند. در این حالت چه می‌توانیم بکنیم؟

به خوبی به خاطر دارم که برای بازنویسی سیستم جدید نه مشخصات اصلی سیستم را در اختیار داشتیم، و نه حتی یک سیستم Issue Tracker قدیمی که به ما در مورد Bug Fixها و Feature Requestها اطلاعات بدهد. البته در مورد Source Code Repository وضع بهتر بود. چرا که آنرا در اختیار داشتیم. اگر ما می‌توانستیم ببینیم که هر ماژول‌ در چه حد بررسی شده است، می‌توانستیم نقاطی را در کد پیدا کنیم که پیاده‌سازهای و کدنویس‌های اولیه در آن با مشکلاتی برخورد داشته‌اند. چنین قسمت‌هایی در کد جاهای خوبی بود که ما می‌توانستیم مشکلات سیستم جدید را در آنجا بیابیم، چرا که اصلا بعید نبود که ما هم با همین مشکلات در کد برخورد کنیم. اما وقتی متوجه شدیم که کد سیستم در Repository ما قرار گرفته است اما تاریخچه اصلاحات در آن منتقل نشده است، متوجه شدیم که بدبختی‌های ما تمام شدنی نیست، چون دیگر نمی‌توانستیم بفهمیم کدام قسمت‌های کد بیشتر مورد مراجعه و طبعا مشکل‌دار بوده‌اند.

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

خب. بالاخره بعضی وقت‌ها هم شانس همراهتان نیست. اما نکته طلایی این است که اگر نمی‌توانیم خوش شانس باشیم، باید شانس را خودمان بسازیم.

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

خب همین اطلااعات زمانی که در سیستم قدیمی قرار می‌گرفتند پس از پردازش خروجی‌هایی را به ما می‌دادند، که ما آنها را به عنوان Expected Resultها ذخیره می‌کردیم. به این ترتیب ما مقدار قابل توجهی از داده‌های اولیه را برای تست پذیرش سیستم جدید خود فراهم کردیم.

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

با چنین وضعیتی شما باید یک الگوی رفتاری در تست برای خود ایجاد کنید. اگر تست شما Pass شد با آن کاری نداشته باشید. اما اگر تست شما Fail شد باید این نکته را در نظر بگیرید که شاید نتیجه شما واقعا Fail نباشد، و صرفا یک تفاوت دیدگاه در دو سیستم وجود دارد. در حقیقت ممکن است آنها دو داده مساوی را ارائه دهند که فقط مشابه نیستند(مانند صفر درجه سلسیوس و ۳۲ درجه فارنهایت). در این وضعیت باید روی موارد Fail شده بررسی کنید تا اگر توانستید تناسب این دو خروجی با یکدیگر را بیابید. در غیر اینصورت احتمالا پیاده‌سازی شما در سیستم جدید غلط بوده.

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

در آخر به چند نکته مهم اشاره می‌کنیم:

  1. هر سندی را که می‌بینید و هر شخصی را که می‌دانید از افراد قدیمی سیستم Legacy شماست را از دست ندهید. آنها به هر ترتیب می‌توانند اطلاعاتی را به شما منتقل نمایند.
  2. داده‌های اولیه سیستم جدید را از سیستم قدیمی بگیرید، و نتایجی که بر اساس این داده‌ها از دو سیستم استخراج می‌شود را به عنوان Expected Result(خروجی سیستم قدیمی) و Actual Result(خروجی سیستم جدید) در نظر بگیرید.
  3. در نظر داشته باشید ممکن است این داده‌های خروجی با هم یکسان باشند، اما مشابهت نداشته باشند. با این اوصاف هر تستی که Fail می‌شود باید مورد بررسی قرار بگیرد، چون ممکن است هر دو سیستم در حال ارائه یک نتیجه باشند، اما خروجی آنها با هم متفاوت باشد.
  4. توجه داشته باشید که این کار را نباید با تمام قسمت‌های سیستم انجام داد. بلکه صرفا آن بخش‌هایی از سیستم قدیمی که مدتهاست روی آنها گزارش باگ ارائه نشده است، و از صحت عملکردی مناسبی برخوردار هستند، برای این کار مناسب می‌باشند.

سمیه اویسی

همچنین ببینید

Test Data Bottleneck

تنگنای داده های تست و راهکار آن

زمان زیادی برای یافتن کیس های مناسب برای داده های تست هدر می شود، چندین …

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *