JavaRush /בלוג Java /Random-HE /JUnit עבור JavaRush או קצת על בדיקות בבית.
Sdu
רָמָה

JUnit עבור JavaRush או קצת על בדיקות בבית.

פורסם בקבוצה
נמאס לך להקליד נתוני בדיקה בקונסולה עשרות פעמים כדי לבדוק את המשימה שלך? ברוך הבא לחתול, אני אגיד לך מה אתה יכול לעשות איתו. המטרה הסופית של חומר זה תהיה להפוך את ההשקה של המשימה הנפתרת עם פרמטרים שונים ובדיקת התוצאות ללא ביצוע שינויים בקוד המקור שלה. כפי שבטח כבר הבנתם מהכותרת, העוזר הראשי שלנו בעניין הפשוט הזה יהיה JUnit . אם עדיין לא שמעתם על בדיקות יחידות ומבחני יחידות , אני מציע לכם לעשות הפסקה קטנה ולהכיר את המושגים הללו, למרבה המזל יש מספיק מידע באינטרנט. לא, אתה לא רוצה? ובכן, בסדר, אני חושב שזה לא יהפוך לבעיה גדולה להבין מה קורה. הרי אתה יודע מה זה מבחן ובדיקה בכלל? אתה עושה זאת בכל פעם שאתה מפעיל את המשימה שלך, מזין את הנתונים הראשוניים ומשווה את התוצאה המתקבלת עם מה שציפית לראות.
שלום, JUnit עולמי !
מה זה JUnit? באתר הרשמי של הפרויקט נוכל לקרוא את התיאור הבא:
JUnit היא מסגרת פשוטה לכתיבת מבחנים שניתנים לחזרה. זהו מופע של ארכיטקטורת xUnit עבור מסגרות לבדיקת יחידות.
עבורנו, משמעות הדבר היא היכולת לכתוב מחלקות מעוצבות במיוחד שהשיטות שלהן יפעלו באינטראקציה עם התוכנית שלנו, להשוות את התוצאה המתקבלת עם ההפניה ולהודיע ​​לנו אם הן אינן תואמות. כדי להבין את העיקרון, שקול דוגמה פשוטה. נניח שיש לנו מחלקת עזר, שאחת מהשיטות שלה לוקחת שני משתנים מסוג int ומחזירה את הסכום שלהם: JUnit עבור JavaRush או קצת על בדיקות בבית.  - 1 זו הפונקציונליות שננסה לבדוק. למרבה המזל, ל-IDEA האהוב עלינו כבר יש את כל מה שאתה צריך כדי ליצור במהירות מבחנים, כל מה שאנחנו צריכים זה למקם את הסמן בשורת הצהרת הכיתה, הקש "Alt + Enter" ובחר "צור מבחן" בתפריט ההקשר: לאחר שתציין JUnit עבור JavaRush או קצת על בדיקות בבית.  - 2 היכן כדאי ליצור מבחן, IDEA מציעה לבחור ספריית בדיקה (בחומר זה אני משתמש ב-JUnit4; כדי ששיעורי הספרייה יתחברו לפרויקט, יש ללחוץ על כפתור "תיקון"), שיטות לבדיקה ועוד. אפשרויות. JUnit עבור JavaRush או קצת על בדיקות בבית.  - 3 ה-IDE יצור תבנית מחלקת בדיקה: ClassName = TestClassName + "Test" MethodName = "test" + TestMethodName JUnit עבור JavaRush או קצת על בדיקות בבית.  - 4 אנחנו רק צריכים למלא את גוף השיטה. מה שמכונה "הצהרות" , שיטות המסופקות על ידי JUnit , יעזרו בכך . בצורה פשוטה, עבודתם נראית כך: התוצאה הצפויה והתוצאה של הקריאה לשיטה הנבדקת מועברות לשיטת .assert*, מטעמי נוחות, ניתן להוסיף הודעת הסבר כפרמטר ראשון. אם הפרמטרים אינם תואמים במהלך הבדיקה, תקבלו מידע על כך. אתה יכול להפעיל מחלקה בדיקה לביצוע בדיוק כמו מחלקה רגילה, אני מעדיף להשתמש בשילוב המקשים Ctrl+Shift+F10 JUnit עבור JavaRush או קצת על בדיקות בבית.  - 5
בוא נפרט את המשימה
בתיאוריה, הכל פשוט ויפה, אבל בהקשר של הדוגמה המוצעת, זה לא ממש הכרחי; אנחנו יכולים לסמוך על המחשב שיוסיף שני מספרים. אנחנו מתעניינים יותר איך הדברים יסתדרו עם בעיות אמיתיות שיפתרו על ידי תלמידי JavaRush; לדוגמה, אני מציע לקחת את הרמה האהובה05.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. העברת ההיגיון למציאת המקסימום לשיטה נפרדת.
    • יתרונות: גישה נכונה במונחים של refactoring
    • חסרונות: התוכנה מגודלת בקוד, מבנים מיותרים, לפחות מתווסף מערך או ArrayList (תלוי בטעם ובצבע...). רק המנגנון למציאת המקסימום נבדק; קלט ופלט נתונים אינם נבדקים.
  2. כתיבת עטיפות עבור System.in/System.out.
    • יתרונות: אנחנו לא משתמשים בספריות של צד שלישי.
    • חסרונות: השביל אינו מיועד למתחילים. המורכבות היחסית של יישום הבדיקה; כמות הקוד בבדיקה עשויה להיות גדולה יותר מאשר במשימה הנבדקת.
  3. שימוש בספריות נוספות למבחנים.
    • יתרונות: קוד נקי במבחנים, קלות יחסית בכתיבת מבחן. קוד המקור של המחלקה הנבדקת לא משתנה.
    • חסרונות: צריך לחבר ספריות של צד שלישי לפרויקט.
למען האמת, הכי אהבתי את האפשרות השלישית, אז בואו ננסה ליישם אותה.
כללי מערכת
חיפוש קצר הוביל אותי לעמוד http://stefanbirkner.github.io/system-rules/ , ומיד התברר שזה מה שאני צריך.
אוסף כללי JUnit לבדיקת קוד המשתמש ב-java.lang.System.
אז בואו נוריד את הספרייה . הורד את ספריית Commons IO הנדרשת כדי שחוקי המערכת יפעלו . אנו מחברים את שתי הספריות לפרויקט שלנו (קובץ -> מבנה פרויקט -> ספריות -> + -> ג'אווה) ומתחילים לפסל: לאחר ההשקה, המשימה שלנו מבקשת מכם להזין מספרים 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