آموزش تست توابع internal در سالیدیتی

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

در ابزار تست Foundry، به این نوع قرارداد فرزند اصطلاحاً harness گفته می‌شود، گرچه برخی منابع آن را fixture نیز می‌نامند.

توجه: هرگز برای راحتی تست، تابع مورد نظر را از internal به public یا virtual تغییر ندهید. زیرا هدف از تست، بررسی همان کدی است که واقعاً قرار است روی بلاک چین مستقر شود، نه نسخه‌ای تغییریافته از آن.

در اینجا یک مثال وجود دارد:

تابع بالا یک نرخ پاداش خطی را نسبت به زمان سپرده‌گذاری محاسبه می‌کند.

حال برای تست این تابع، یک قرارداد فرزند ایجاد می‌کنیم:

در این‌جا از کلیدواژه super استفاده شده است تا به نسخه والد تابع دسترسی پیدا کنیم. اگر از super استفاده نکنیم و مستقیماً calculateReward را صدا بزنیم، چون نام‌ها یکسان هستند، فراخوانی به خودش باز می‌گردد و در نهایت منجر به حلقه بی‌نهایت و خطا خواهد شد.

به‌جای استفاده از همان نام تابع اصلی، می‌توان برای تابع تستی نام متفاوتی انتخاب کرد تا احتمال اشتباه کاهش یابد:

در پروژه‌های واقعی، استفاده از روش harness برای تست توابع internal در سالیدیتی باعث می‌شود که هم هزینه تست کاهش یابد و هم ساختار ماژولار قراردادها حفظ شود. این رویکرد نه تنها وابستگی به پیاده‌سازی را کم می‌کند، بلکه امکان تست دقیق منطق داخلی را بدون تغییر در سطح دسترسی یا افزایش حجم کد فراهم می‌سازد؛ روشی که در فرآیند برنامه نویسی قراردادهای سالیدیتی کاربردی و مؤثر است.

چرا نباید تابع internal را public کنیم؟

تغییر سطح دسترسی از internal به public به‌ظاهر ساده و کاربردی است، اما از نظر فنی توصیه نمی‌شود:

  • باعث افزایش حجم کد بایت‌کد (bytecode) می‌شود.

  • هزینه استقرار (Deployment Gas) را بالا می‌برد.

  • به دلیل افزایش تعداد توابع قابل شناسایی، جستجوی selector تابع نیز طولانی‌تر می‌شود و این به افزایش هزینه اجرای سایر توابع منجر می‌شود.

چرا نباید تابع virtual را در fixture بازنویسی کنیم؟

فرض کنید تابع داخلی مورد نظر به شکل زیر تعریف شده باشد:

ممکن است وسوسه شوید آن را در قرارداد harness بازنویسی (override) کنید. اما این کار اشتباه است:
مشکل این‌جاست که شما ناخواسته منطق تابع را کپی-پیست کرده‌اید. اگر بعداً تابع اصلی تغییر کند اما نسخه کپی‌شده در harness را به‌روزرسانی نکنید، تست‌ها دیگر منطق اصلی قرارداد را بررسی نخواهند کرد و اعتبار تست‌ها زیر سؤال می‌رود.

آیا می‌توان توابع private را تست کرد؟

خیر. توابع private حتی در قراردادهای مشتق شده نیز قابل مشاهده نیستند، بنابراین به‌هیچ‌وجه نمی‌توان آن‌ها را مستقیماً تست کرد.

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

در مثال زیر، اگر تابع foo را از private به internal تغییر دهید، مصرف گس همچنان ثابت می‌ماند:

به طور خلاصه، اگر قصد دارید تست توابع internal در سالیدیتی را به شکلی اصولی و بهینه انجام دهید، بهتر است از تغییر سطح دسترسی خودداری کرده و از قراردادهای harness بهره ببرید. این روش، هم از نظر مصرف گس به‌صرفه است و هم دقت تست‌های شما را حفظ می‌کند.

5/5 - (1 امتیاز)

راستی! برای دریافت مطالب جدید در کانال تلگرام یا پیج اینستاگرام سورس باران عضو شوید.

دوره آموزش پروژه محور طراحی وب سایت پزشک یاب با بوت استرپ
  • انتشار: ۵ خرداد ۱۴۰۴

دسته بندی موضوعات

آخرین محصولات فروشگاه

مشاهده همه

نظرات

بازخوردهای خود را برای ما ارسال کنید