JavaRush /وبلاگ جاوا /Random-FA /JUnit برای JavaRush یا کمی در مورد آزمایش در خانه.
Sdu
مرحله

JUnit برای JavaRush یا کمی در مورد آزمایش در خانه.

در گروه منتشر شد
از تایپ کردن داده های آزمایشی در کنسول ده ها بار برای بررسی کار خود خسته شده اید؟ به گربه خوش آمدید، من به شما می گویم که با آن چه کاری می توانید انجام دهید. هدف نهایی این ماده، خودکار کردن راه اندازی کار حل شده با پارامترهای مختلف و بررسی نتایج بدون ایجاد تغییر در کد منبع آن خواهد بود. همانطور که احتمالاً قبلاً از عنوان فهمیده اید، دستیار اصلی ما در این موضوع نسبتاً ساده JUnit خواهد بود . اگر هنوز در مورد تست واحد و تست واحد چیزی نشنیده اید ، پیشنهاد می کنم کمی استراحت کنید و با این مفاهیم آشنا شوید، خوشبختانه اطلاعات کافی در اینترنت وجود دارد. نه، شما نمی خواهید؟ خوب، خوب، من فکر می کنم این مشکل بزرگی برای درک آنچه اتفاق می افتد نخواهد بود. بالاخره میدونی تست و تست به طور کلی چیه؟ این کار را هر بار که کار خود را راه اندازی می کنید، انجام می دهید، داده های اولیه را وارد کرده و نتیجه حاصل را با آنچه انتظار داشتید ببینید، مقایسه کنید.
سلام، جهانی JUnit!
JUnit چیست؟ در وب سایت رسمی پروژه می توانیم توضیحات زیر را مطالعه کنیم:
JUnit یک چارچوب ساده برای نوشتن تست های تکرارپذیر است. این نمونه ای از معماری xUnit برای چارچوب های تست واحد است.
برای ما، این به معنای توانایی نوشتن کلاس های طراحی شده ویژه است که روش های آنها با برنامه ما تعامل داشته باشد، نتیجه حاصل را با مرجع مقایسه کنیم و در صورت عدم تطابق به ما اطلاع دهیم. برای درک اصل، یک مثال ساده را در نظر بگیرید. فرض کنید یک کلاس کمکی داریم که یکی از متدهای آن دو متغیر از نوع int را می گیرد و مجموع آنها را برمی گرداند: JUnit برای JavaRush یا کمی در مورد آزمایش در خانه.  - 1 این همان عملکردی است که سعی می کنیم آن را آزمایش کنیم. خوشبختانه، IDEA مورد علاقه ما در حال حاضر همه چیزهایی را که برای ایجاد سریع تست ها نیاز دارید، دارد، تنها چیزی که ما نیاز داریم این است که مکان نما را در خط اعلام کلاس قرار دهیم، "Alt + Enter" را فشار داده و "Create Test" را در منوی زمینه انتخاب کنیم: JUnit برای JavaRush یا کمی در مورد آزمایش در خانه.  - 2 پس از اینکه مشخص کردید کجا شما باید یک آزمایش ایجاد کنید، IDEA انتخاب یک کتابخانه آزمایشی را پیشنهاد می‌کند (در این مطالب از JUnit4 استفاده می‌کنم؛ برای اینکه کلاس‌های کتابخانه به پروژه متصل شوند، باید روی دکمه «Fix» کلیک کنید)، روش‌هایی که باید آزمایش شوند و موارد اضافی. گزینه ها. JUnit برای JavaRush یا کمی در مورد آزمایش در خانه.  - 3 IDE یک الگوی کلاس آزمایشی ایجاد می کند: ClassName = TestClassName + "Test" MethodName = "test" + TestMethodName JUnit برای JavaRush یا کمی در مورد آزمایش در خانه.  - 4 فقط باید بدنه متد را پر کنیم. روش های به اصطلاح "Assertions" که توسط JUnit ارائه شده است ، به این امر کمک می کند . در یک روش ساده، کار آنها به این صورت است: نتیجه مورد انتظار و نتیجه فراخوانی روش مورد آزمایش به روش .assert* منتقل می شود؛ برای راحتی، می توانید یک پیام توضیحی را به عنوان اولین پارامتر اضافه کنید. در صورت عدم تطابق پارامترها در حین تست، در این مورد به شما اطلاع داده خواهد شد. شما می توانید یک کلاس آزمایشی را برای اجرا درست مانند یک کلاس معمولی راه اندازی کنید، من ترجیح می دهم از کلید ترکیبی Ctrl+Shift+F10 استفاده کنم. JUnit برای JavaRush یا کمی در مورد آزمایش در خانه.  - 5
بیایید تکلیف را مشخص کنیم
در تئوری، همه چیز ساده و زیبا است، اما در زمینه مثال پیشنهادی، واقعاً ضروری نیست؛ می‌توانیم به رایانه اعتماد کنیم تا دو عدد را اضافه کند. ما بیشتر به این موضوع علاقه مندیم که مشکلات واقعی حل شده توسط دانش آموزان JavaRush چگونه پیش می رود؛ به عنوان مثال، من پیشنهاد می کنم که level05.lesson12.bonus03 را انتخاب کنید.
/* مشکل در الگوریتم ها برنامه ای بنویسید که: 1. عدد N > 0 را از کنسول 2 وارد کند. سپس N عدد را از کنسول وارد کند 3. حداکثر N عدد وارد شده را نمایش دهد. */
باید سه تست برای اعداد مثبت، منفی و یک مجموعه مختلط بنویسیم.
هر چه جلوتر به جنگل ...
اینجاست که چند سورپرایز در انتظار ماست: public class UtilApp { public static void main(String[] args) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); //напишите здесь ваш code int n; int maximum; /* Конечно же я не буду размещать решение задачи ;) Код приведенный тут переработан для наглядности, и не в коем случае не означает что он должен присутствовать в "правильном решении" */ System.out.println(maximum); } }
  • منطق برنامه در متد main() قرار می گیرد
  • داده های منبع به متد ارسال نمی شود، بلکه از صفحه کلید وارد می شود.
  • متد main() نتیجه را بر نمی گرداند، بلکه آن را به کنسول خروجی می دهد.
اگر نکته اول به خصوص مشکل ساز نباشد (مثلاً می توانیم متد main() را فراخوانی کنیم، دو مورد بعدی ما را مجبور می کنند تا عمیق تر به موضوع برویم و مغزمان را تحت فشار قرار دهیم. من چندین راه حل برای مشکل پیدا کردم:
  1. انتقال منطق برای یافتن حداکثر به یک روش جداگانه.
    • مزایا: رویکرد صحیح از نظر بازسازی مجدد
    • معایب: برنامه مملو از کد، ساختارهای غیر ضروری می شود، حداقل یک آرایه یا ArrayList اضافه می شود (بسته به سلیقه و رنگ ...). فقط مکانیسم برای یافتن حداکثر آزمایش می شود؛ ورودی و خروجی داده بررسی نمی شود.
  2. نوشتن لفاف برای System.in/System.out.
    • مزایا: ما از کتابخانه های شخص ثالث استفاده نمی کنیم.
    • معایب: مسیر برای مبتدیان نیست. پیچیدگی نسبی اجرای آزمون؛ مقدار کد موجود در آزمون ممکن است بیشتر از کار مورد آزمایش باشد.
  3. استفاده از کتابخانه های اضافی برای تست ها
    • مزایا: کد پاک در تست ها، سهولت نسبی نوشتن تست. کد منبع کلاس مورد آزمایش تغییر نکرده است.
    • معایب: نیاز به اتصال کتابخانه های شخص ثالث به پروژه.
صادقانه بگویم، من گزینه سوم را بیشتر دوست داشتم، بنابراین بیایید سعی کنیم آن را اجرا کنیم.
قوانین سیستم
یک جستجوی کوتاه مرا به صفحه http://stefanbirkner.github.io/system-rules/ هدایت کرد و بلافاصله مشخص شد که این همان چیزی است که من به آن نیاز داشتم.
مجموعه ای از قوانین JUnit برای تست کد که از java.lang.System استفاده می کند.
بنابراین، بیایید کتابخانه را دانلود کنیم . کتابخانه Commons IO مورد نیاز برای اجرای قوانین سیستم را دانلود کنید . ما هر دو کتابخانه را به پروژه خود متصل می کنیم (File -> Project Structure -> Libraries -> + -> Java) و مجسمه سازی را شروع می کنیم: پس از راه اندازی، وظیفه ما از شما می خواهد اعداد N+1 را از کنسول وارد کنید، جایی که شماره اول به شما می گوید چند عدد او را دنبال خواهند کرد. در System Rules از کلاس TextFromStandardInputStream برای این منظور استفاده می شود.در ابتدا باید یک فیلد از این نوع را به کلاس تست خود اضافه کنیم و آن را با حاشیه نویسی @Rule علامت گذاری کنیم: @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); سپس مستقیماً در روش تست داده های لازم را نشان می دهیم: systemInMock.provideText("4\n2\n6\n1\n3\n"); همانطور که می بینید، اعداد به صورت متن ارسال می شوند و با یک رشته خط فاصله "\n" از هم جدا می شوند. بر این اساس معلوم می شود که N برابر با 4 خواهد بود و از اعداد {2، 6، 1، 3} به دنبال حداکثر خواهیم بود. در مرحله بعد، باید یک نمونه از کلاس تحت آزمایش ایجاد کنیم و متد main() را فراخوانی کنیم. برنامه ما داده ها را از systemInMock می خواند، آنها را پردازش می کند و نتیجه را چاپ می کند و تنها کاری که باید انجام دهیم این است که آن را بخوانیم و با استاندارد مقایسه کنیم. برای انجام این کار، قوانین سیستم کلاس StandardOutputStreamLog را در اختیار ما قرار می دهد. یک فیلد از نوع مشخص شده اضافه می کنیم: @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); می توانید داده های چاپ شده را با استفاده از روش .getLog() بخوانید، در حالی که باید حضور کاراکترهای خط جدید را در نظر بگیرید، گزینه های نهایی می توانند به این صورت باشند: assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); // or assertEquals("{2, 6, 1, 3}, max = 6", "6\r\n", log.getLog()); بین تست ها، به منظور از لایه بندی داده ها اجتناب کنید، باید لاگ را پاک کنید log.clear(); متن کامل کلاس آزمایشی من: import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.StandardOutputStreamLog; import org.junit.contrib.java.lang.system.TextFromStandardInputStream; import static org.junit.Assert.*; import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.emptyStandardInputStream; public class UtilAppTest { @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); @Test public void testAddition() throws Exception { systemInMock.provideText("4\n2\n6\n1\n3\n"); UtilApp utilApp = new UtilApp(); utilApp.main(new String[]{}); assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); systemInMock.provideText("5\n-100\n-6\n-15\n-183\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{-100, -6, -15, -183, -1}, max = -1", "-1", log.getLog().trim()); systemInMock.provideText("3\n2\n0\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{2, 0, -1}, max = 2", "2", log.getLog().trim()); } } راه اندازی می کنیم و لذت می بریم. -=!!! مهم!!!=- این مطالب فقط برای مقاصد اطلاعاتی ارائه شده است؛ اگر یک کلاس اضافی در بسته همراه با کار وجود داشته باشد، تست موفقیت آمیز کار روی سرور را تضمین نمی کنم. قبل از ارسال یک کار برای تأیید به سرور، همه چیزهای اضافی را حذف کنید: فایل های غیر ضروری، کلاس های غیر ضروری، کدهای نظر داده شده. انجام موفقیت آمیز تست هایی که ایجاد کرده اید، تضمینی برای تکمیل موفقیت آمیز تست های روی سرور نیست. من عمداً مطالب نظری را نجویدم: تئوری تست واحد، حاشیه نویسی JUnit، ادعا و غیره، همه مطالب در لینک های ارائه شده در متن موجود است. شاید شما روش های خود را برای آزمایش وظایف داشته باشید، خوشحال خواهم شد که در نظرات با شما در مورد آنها صحبت کنم.
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION