מדריך לבדיקות פרמטריות של JUnit 5

1. סקירה כללית

JUnit 5, הדור הבא של JUnit, מאפשר כתיבת מבחני מפתח עם תכונות חדשות ומבריקות.

תכונה אחת כזו היא עמ 'בדיקות arameterized. תכונה זו מאפשרת לנו לבצע שיטת בדיקה אחת מספר פעמים עם פרמטרים שונים.

במדריך זה אנו נבדוק לעומק מבחנים פרמטרים, אז בואו נתחיל!

2. תלות

על מנת להשתמש בבדיקות פרמטריות של JUnit 5, עלינו לייבא את ה- צומת-צדק-פאראמס חפץ מפלטפורמת JUnit. פירוש הדבר שכאשר משתמשים ב- Maven, נוסיף את הדברים הבאים שלנו pom.xml:

 org.junit.jupiter junit-jupiter-params 5.7.0 test 

כמו כן, כאשר משתמשים ב- Gradle, נפרט זאת מעט אחרת:

testCompile ("org.junit.jupiter: junit-jupiter-params: 5.7.0")

3. רושם ראשוני

נניח שיש לנו פונקציית שירות קיימת ואנחנו רוצים להיות בטוחים בהתנהגותה:

מחלקה ציבורית מספרים {בוליאני סטטי ציבורי isOdd (int מספר) {return number% 2! = 0; }}

מבחנים פרמטריים הם כמו בדיקות אחרות, אלא שאנחנו מוסיפים את ה- @ParameterizedTest ביאור:

@ParameterizedTest @ValueSource (ints = {1, 3, 5, -3, 15, Integer.MAX_VALUE}) // שישה מספרים בטלים isOdd_ShouldReturnTrueForOddNumbers (int מספר) {assertTrue (Numbers.isOdd (number)); }

רץ המבחן JUnit 5 מבצע את הבדיקה הנ"ל - וכתוצאה מכך, ה- isOdd שיטה - שש פעמים. ובכל פעם, זה מקצה ערך אחר מזה @ValueSource מערך ל מספר פרמטר השיטה.

לכן, דוגמה זו מראה לנו שני דברים שאנו צריכים לצורך בדיקה פרמטרית:

  • מקור לוויכוחים, int מערך, במקרה זה
  • דרך לגשת אליהם, במקרה זה, מספר פָּרָמֶטֶר

יש גם דבר נוסף שלא ניכר בדוגמה זו, אז הישאר מעודכן.

4. מקורות ויכוחים

כפי שאנו צריכים לדעת עד כה, בדיקה פרמטרית מבצעת את אותה בדיקה מספר פעמים עם ארגומנטים שונים.

ואני מקווה שנוכל לעשות יותר מסתם מספרים - אז בואו נחקור!

4.1. ערכים פשוטים

עם ה @ValueSource ביאור, אנו יכולים להעביר מערך ערכים מילולי לשיטת הבדיקה.

לדוגמה, נניח שנבדוק את הפשטות שלנו ריק שיטה:

מחרוזות מחלקה ציבורית {בוליאני סטטי ציבורי isBlank (קלט מחרוזת) קלט החזרה == null}

אנו מצפים משיטה זו לחזור נָכוֹן ל ריק לחוטים ריקים. לכן אנו יכולים לכתוב מבחן פרמטריאלי כדלקמן כדי לקבוע התנהגות זו:

@ParameterizedTest @ValueSource (strings = {"", ""}) void isBlank_ShouldReturnTrueForNullOrBlankStrings (קלט מחרוזת) {assertTrue (Strings.isBlank (קלט)); } 

כפי שאנו רואים, JUnit יפעיל את הבדיקה הזו פעמיים ובכל פעם מקצה ארגומנט אחד מהמערך לפרמטר השיטה.

אחת המגבלות של מקורות ערך היא שהם תומכים רק בסוגים הבאים:

  • קצר (עם ה מִכְנָסַיִים קְצָרִים תְכוּנָה)
  • בתים (עם ה בתים תְכוּנָה)
  • int (עם ה ints תְכוּנָה)
  • ארוך (עם ה מייחל תְכוּנָה)
  • לָצוּף (עם ה צף תְכוּנָה)
  • לְהַכפִּיל (עם ה זוגות תְכוּנָה)
  • לְהַשְׁחִיר (עם ה צ'ארס תְכוּנָה)
  • מיתר (עם ה מיתרים תְכוּנָה)
  • java.lang.Class (עם ה שיעורים תְכוּנָה)

גַם, אנו יכולים להעביר רק טיעון אחד לשיטת הבדיקה בכל פעם.

ולפני שהמשיך הלאה, מישהו שם לב שלא עברנו ריק כוויכוח? זו מגבלה נוספת: אנחנו לא יכולים לעבור ריק דרך א @ValueSource, אפילו בשביל חוּט ו מעמד!

4.2. ערכים אפסים וריקים

נכון ל- JUnit 5.4, אנו יכולים להעביר יחיד ריק ערך לשיטת בדיקה פרמטרית באמצעות @NullSource:

@ParameterizedTest @ NullSource בטל isBlank_ShouldReturnTrueForNullInputs (קלט מחרוזת) {assertTrue (Strings.isBlank (קלט)); }

מאחר וסוגי נתונים פרימיטיביים אינם יכולים לקבל ריק ערכים, איננו יכולים להשתמש ב- @NullSource לוויכוחים פרימיטיביים.

באופן די דומה, אנו יכולים להעביר ערכים ריקים באמצעות ה- @ EmptySource ביאור:

@ParameterizedTest @EmptySource חלל isBlank_ShouldReturnTrueForEmptyStrings (קלט מחרוזת) {assertTrue (Strings.isBlank (קלט)); }

@ EmptySource מעביר טיעון ריק יחיד לשיטה המבוארת.

ל חוּט טיעונים, הערך שהועבר יהיה פשוט כמו ריק חוּט. יתר על כן, מקור פרמטר זה יכול לספק ערכים ריקים עבור אוסף סוגים ומערכים.

על מנת לעבור את שניהם ריק וערכים ריקים, נוכל להשתמש במורכב @NullAndEmptySource ביאור:

@ParameterizedTest @ NullAndEmptySource חלל isBlank_ShouldReturnTrueForNullAndEmptyStrings (קלט מחרוזת) {assertTrue (Strings.isBlank (קלט)); }

כמו עם @ EmptySource, ההערה המורכבת עובדת עבור חוּטס,אוסףס, ומערכים.

על מנת להעביר עוד כמה וריאציות מחרוזות ריקות למבחן הפרמטרי, אנחנו יכולים לשלב @ValueSource, @NullSource ו- @EmptySource יַחַד:

@ParameterizedTest @NullAndEmptySource @ValueSource (מחרוזות = {"", "\ t", "\ n"}) ריק הוא Blank_ShouldReturnTrueForAllTypesOfBlankStrings (קלט מחרוזת) {assertTrue (Strings.isBlank (קלט)); }

4.3. Enum

על מנת להריץ בדיקה עם ערכים שונים מספירה, אנו יכולים להשתמש ב- @EnumSource ביאור.

לדוגמא, אנו יכולים לקבוע כי כל מספרי החודשים הם בין 1 ל -12:

@ParameterizedTest @EnumSource (חודש.קלאס) // עובר את כל 12 החודשים בטל getValueForAMonth_IsAlwaysBetweenOneAndTwelve (חודש חודש) {int monthNumber = month.getValue (); assertTrue (monthNumber> = 1 && monthNumber <= 12); }

לחלופין, נוכל לסנן מספר חודשים באמצעות ה- שמות תְכוּנָה.

מה דעתך לטעון את העובדה שאפריל, ספטמבר, יוני ונובמבר אורכים 30 יום:

@ParameterizedTest @EnumSource (value = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER"}) בטל someMonths_Are30DaysLong (חודש חודש) {בוליאני אחרון isALeapYear = false; assertEquals (30, month.length (isALeapYear)); }

כברירת מחדל, ה- שמות ישמור רק על ערכי האנומר המותאמים. אנו יכולים להפוך זאת על ידי הגדרת ה- מצב מייחס ל בלעדי:

@ParameterizedTest @EnumSource (value = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER", "FEBRUARY"}, mode = EnumSource.Mode.EXCLUDE) בטל למעט FourMonths_OthersAre31DaysLong (חודש חודש) בוליאני סופי isALeapYear = שקר; assertEquals (31, month.length (isALeapYear)); }

בנוסף למיתרים מילוליים, אנו יכולים להעביר ביטוי קבוע ל שמות תְכוּנָה:

@ParameterizedTest @EnumSource (value = Month.class, names = ". + BER", mode = EnumSource.Mode.MATCH_ANY) בטל fourMonths_AreEndingWithBer (חודש חודש) {EnumSet חודשים = EnumSet.of (חודש. SEPTEMBER, חודש. OCTOBER, חודש . נובמבר, חודש. דצמבר); assertTrue (חודשים. מכיל (חודש)); }

די דומה ל @ValueSource, @EnumSource רלוונטי רק כאשר אנו מעבירים טיעון אחד בלבד לכל ביצוע בדיקה.

4.4. ספרות CSV

נניח שנדאג ש- toUpperCase () שיטה מ חוּט מייצר את הערך הראשי הצפוי. @ValueSource לא יספיק.

על מנת לכתוב בדיקה פרמטרית לתרחישים כאלה, עלינו:

  • לעבור ערך קלט ו an ערך צפוי לשיטת הבדיקה
  • מחשבים את התוצאה בפועל עם ערכי קלט אלה
  • לִטעוֹן הערך בפועל עם הערך הצפוי

לכן, אנו זקוקים למקורות טיעון המסוגלים להעביר טיעונים מרובים. ה @CsvSource הוא אחד מאותם מקורות:

@ParameterizedTest @CsvSource ({"test, TEST", "tEst, TEST", "Java, JAVA"}) בטל toUpperCase_ShouldGenerateTheExpectedUppercaseValue (קלט מחרוזת, מחרוזת צפויה) {String actualValue = input.toUpperCase (); assertEquals (צפוי, actualvalue); }

ה @CsvSource מקבל מערך של ערכים המופרדים בפסיקים וכל ערך מערך תואם שורה בקובץ CSV.

מקור זה לוקח ערך מערך אחד בכל פעם, מחלק אותו בפסיק ומעביר כל מערך לשיטת הבדיקה המאושרת כפרמטרים נפרדים. כברירת מחדל, הפסיק הוא מפריד העמודות אך אנו יכולים להתאים אותו באמצעות ה- תוחם תְכוּנָה:

@ParameterizedTest @CsvSource (value = {"test: test", "tEst: test", "Java: java"}, delimiter = ':') void toLowerCase_ShouldGenerateTheExpectedLowercaseValue (קלט מחרוזת, צפוי מחרוזת) {String actualValue = input.toLowerCase ( ); assertEquals (צפוי, actualvalue); }

עכשיו זה המעי הגסערך מופרד, עדיין CSV!

4.5. קבצי CSV

במקום להעביר את ערכי ה- CSV בתוך הקוד, אנו יכולים להתייחס לקובץ CSV בפועל.

לדוגמה, נוכל להשתמש בקובץ CSV כמו:

קלט, מבחן צפוי, TEST tEst, TEST Java, JAVA

אנחנו יכולים לטעון את קובץ ה- CSV ו- התעלם מעמודת הכותרת עם @ CSVsvileSource:

@ParameterizedTest @CsvFileSource (resources = "/data.csv", numLinesToSkip = 1) בטל toUpperCase_ShouldGenerateTheExpectedUppercaseValueCSVFile (קלט מחרוזת, צפוי מחרוזת) {String actualValue = input.toUpperCase (); assertEquals (צפוי, actualvalue); }

ה אֶמְצָעִי המאפיין מייצג את משאבי קובץ ה- CSV שבדרך לקריאה. ונוכל להעביר אליו מספר קבצים.

ה numLinesToSkip המאפיין מייצג את מספר השורות שעליהם לדלג בעת קריאת קבצי ה- CSV. כברירת מחדל, @ CSVsvileSource לא מדלג על שום שורות, אך בדרך כלל תכונה זו שימושית לדילוג על שורות הכותרת, כמו שעשינו כאן.

בדיוק כמו הפשוטים @CsvSource, המפריד ניתן להתאמה אישית עם ה- תוחם תְכוּנָה.

בנוסף למפריד העמודות:

  • ניתן להתאים את מפריד הקווים באמצעות lineSeparator תכונה - שורה חדשה היא ערך ברירת המחדל
  • קידוד הקובץ ניתן להתאמה אישית באמצעות הַצפָּנָה תכונה - UTF-8 הוא ערך ברירת המחדל

4.6. שיטה

מקורות הטיעון שסיקרנו עד כה הם מעט פשוטים וחולקים מגבלה אחת: קשה או בלתי אפשרי להעביר עצמים מורכבים באמצעותם!

גישה אחת ל מתן טיעונים מורכבים יותר הוא להשתמש בשיטה כמקור ארגומנט.

בואו נבדוק את ריק שיטה עם @MethodSource:

@ParameterizedTest @MethodSource ("provideStringsForIsBlank") חלל הוא Blank_ShouldReturnTrueForNullOrBlankStrings (קלט מחרוזת, צפוי בוליאני) {assertEquals (צפוי, Strings.isBlank (קלט)); }

השם שאנו מספקים לו @MethodSource צריך להתאים לשיטה קיימת.

אז בוא נכתוב בהמשך supplyStringsForIsBlank, א סטָטִי שיטה המחזירה א זרם שֶׁל טַעֲנָהס:

זרם סטטי פרטי provideStringsForIsBlank () {return Stream.of (Arguments.of (null, true), Arguments.of ("", true), Arguments.of ("", true), Arguments.of ("לא ריק", שקר)); }

כאן אנחנו ממש מחזירים זרם של ויכוחים, אבל זה לא דרישה קפדנית. לדוגמה, אנחנו יכולים להחזיר כל ממשק אחר כמו אוסף רשימה.

אם אנו מספקים טיעון אחד בלבד לכל קריאה למבחן, אין צורך להשתמש ב- ויכוחים הַפשָׁטָה:

@ParameterizedTest @MethodSource // hmm, אין שם של שיטה ... void isBlank_ShouldReturnTrueForNullOrBlankStringsOneArgument (קלט מחרוזת) {assertTrue (Strings.isBlank (קלט)); } זרם סטטי פרטי isBlank_ShouldReturnTrueForNullOrBlankStringsOneArgument () {return Stream.of (null, "", ""); }

כאשר אנו לא מספקים שם ל- @MethodSource, JUnit יחפש שיטת מקור בשם זהה לשיטת הבדיקה.

לפעמים כדאי לשתף ויכוחים בין שיעורי מבחן שונים. במקרים אלה, אנו יכולים להתייחס לשיטת מקור מחוץ למחלקה הנוכחית בשמה המלא:

class StringsUnitTest {@ParameterizedTest @MethodSource ("com.baeldung.parameterized.StringParams # blankStrings") void isBlank_ShouldReturnTrueForNullOrBlankStringsExternalSource (קלט מחרוזת) {assertTrue (Strings.isBlank); }} מחלקה ציבורית StringParams {סטטי זרם ריק סטרינגס () {החזר Stream.of (null, "", ""); }}

משתמש ב FQN # methodName פורמט אנו יכולים להתייחס לשיטה סטטית חיצונית.

4.7. ספק ארגומנטים מותאם אישית

גישה מתקדמת נוספת להעברת טיעוני מבחן היא שימוש ביישום מותאם אישית של ממשק שנקרא ספקים:

מחלקה BlankStringsArgumentsProvider מיישמת ArgumentsProvider {@Override Public stream supplyArguments (הקשר ExtensionContext) {return Stream.of (Arguments.of ((String) null), Arguments.of (""), Arguments.of ("")); }}

אז נוכל להוסיף הערה למבחן שלנו באמצעות ה- @ ארגומנטים מקור הערה לשימוש בספק המותאם אישית הזה:

@ParameterizedTest @ArgumentsSource (BlankStringsArgumentsProvider.class) חלל isBlank_ShouldReturnTrueForNullOrBlankStringsArgProvider (קלט מחרוזת) {assertTrue (Strings.isBlank (קלט)); }

בואו נהפוך את הספק המותאם אישית ל- API נעים יותר לשימוש עם ביאור מותאם אישית!

4.8. ביאור מותאם אישית

מה דעתך לטעון את טיעוני הבדיקה ממשתנה סטטי? משהו כמו:

טיעוני זרם סטטי = Stream.of (Arguments.of (null, true), // מחרוזות null צריכים להיחשב ריק Arguments.of ("", true), Arguments.of ("", true), Arguments.of (" לא ריק ", שקר)); @ParameterizedTest @VariableSource ("טיעונים") חלל isBlank_ShouldReturnTrueForNullOrBlankStringsVariableSource (קלט מחרוזת, צפוי בוליאני) {assertEquals (צפוי, Strings.isBlank (קלט)); }

בעצם, JUnit 5 אינו מספק זאת! עם זאת, אנו יכולים לגלגל את הפתרון שלנו.

ראשית, אנו יכולים ליצור הערה:

@Documented @Target (ElementType.METHOD) @Retention (RetentionPolicy.RUNTIME) @ArgumentsSource (VariableArgumentsProvider.class) public @interface VariableSource {/ ** * שם המשתנה הסטטי * / ערך מחרוזת (); }

ואז אנחנו צריכים איכשהו צורכים את ההערה פרטים ו לספק טיעוני מבחן. JUnit 5 מספק שתי הפשטות כדי להשיג את שני הדברים האלה:

  • הערה צרכנית לצרוך את פרטי ההערה
  • ספקי טיעונים לספק טיעוני מבחן

אז הבא עלינו להכין את VariableArgumentsProvider המחלקה נקראה מהמשתנה הסטטי שצוין ומחזירה את ערכה כטיעוני מבחן:

class VariableArgumentsProvider מיישם ArgumentsProvider, AnnotationConsumer {private String variableName; @Override זרם ציבורי supplyArguments (ExtensionContext context) {return context.getTestClass () .map (this :: getField) .map (this :: getValue) .orElseThrow (() -> IllegalArgumentException ("נכשל טעינת טיעוני הבדיקה") ); } @ קביעת חלל ציבורי על ביטול (VariableSource variableSource) {variableName = variableSource.value (); } שדה פרטי getField (clazz class) {נסה {return clazz.getDeclaredField (variableName); } לתפוס (חריג ה) {להחזיר null; }} @SuppressWarnings ("לא מסומן") זרם פרטי getValue (שדה שדה) {Object Object = null; נסה {value = field.get (null); } לתפוס (התעלם מהחרגה) {} ערך החזר == null? null: (זרם) ערך; }}

וזה עובד כמו קסם!

5. המרת ויכוח

5.1. המרה מרומזת

בואו נכתוב מחדש אחד מאלה @EnumTests עם @מקור CSV:

@ParameterizedTest @CsvSource ({"אפריל", "JUNE", "SEPTEMBER", "NOVEMBER"}) // מחרוזות מזויפות בטלות someMonths_Are30DaysLongCsv (חודש חודש) {בוליאני אחרון isALeapYear = false; assertEquals (30, month.length (isALeapYear)); }

זה לא אמור לעבוד, נכון? אבל, איכשהו זה קורה!

אז, JUnit 5 ממיר את חוּט טיעונים לסוג enum שצוין. כדי לתמוך במקרים של שימוש כזה, JUnit Jupiter מספק מספר ממירי סוג מרומזים מובנים.

תהליך ההמרה תלוי בסוג המוצהר של כל פרמטר שיטה. ההמרה המרומזת יכולה להמיר את חוּט מקרים לסוגים כמו:

  • UUID
  • אזור
  • LocalDate, LocalTime, LocalDateTime, שנה, חודש וכו '.
  • קוֹבֶץ ו נָתִיב
  • כתובת אתר ו URI
  • Enum מחלקות משנה

5.2. המרה מפורשת

לפעמים אנחנו צריכים לספק ממיר מותאם אישית ומפורש לוויכוחים.

נניח שאנחנו רוצים להמיר מחרוזות באמצעות ה- yyyy / mm / ddפורמט ל- LocalDate מקרים. ראשית, עלינו ליישם את ממיר ארגומנטים מִמְשָׁק:

class SlashyDateConverter מיישם ArgumentConverter {@Override public Object convert (מקור אובייקט, הקשר ParameterContext) זורק ArgumentConversionException {if (! (source instanceof String)) {זרוק IllegalArgumentException חדש ("הטיעון צריך להיות מחרוזת:" + מקור); } נסה את {String [] parts = ((String) source). split ("/"); int שנה = Integer.parseInt (חלקים [0]); int חודש = Integer.parseInt (חלקים [1]); int int = Integer.parseInt (חלקים [2]); החזר LocalDate.of (שנה, חודש, יום); } לתפוס (חריג e) {לזרוק IllegalArgumentException חדש ("נכשל המרה", ה); }}}

אז עלינו להתייחס לממיר דרך ה- @ConvertWith ביאור:

@ParameterizedTest @CsvSource ({"2018/12 / 25,2018", "2019/02 / 11,2019"}) בטל getYear_ShouldWorkAsExpected (@ConvertWith (SlashyDateConverter.class) תאריך LocalDate, צפוי int) {assertEquals (צפוי, תאריך. getYear ()); }

6. אביזר לוויכוחים

כברירת מחדל, כל ארגומנט המסופק לבדיקה פרמטרית תואם לפרמטר של שיטה אחת. כתוצאה מכך, כאשר מעבירים קומץ טיעונים דרך מקור ארגומנט, חתימת שיטת הבדיקה נהיית גדולה ומבולגנת מאוד.

גישה אחת לטיפול בבעיה זו היא לצמצם את כל הטיעונים שהועברו למופע של ArgumentsAccessor ואחזר טיעונים לפי אינדקס וסוג.

לדוגמא, בואו ניקח בחשבון שלנו אדם מעמד:

אדם בכיתה {String firstName; מחרוזת middleName; שם משפחה מחרוזת; // constructor public String fullName () {if (middleName == null || middleName.trim (). isEmpty ()) {return String.format ("% s% s", firstName, lastName); } להחזיר String.format ("% s% s% s", firstName, middleName, lastName); }}

ואז, כדי לבדוק את שם מלא() נעביר ארבעה טיעונים: שם פרטי שם אמצעי שם משפחה, וה שם מלא צפוי. אנחנו יכולים להשתמש ב- ArgumentsAccessor כדי לאחזר את טיעוני הבדיקה במקום להכריז עליהם כפרמטרים של שיטה:

@ParameterizedTest @CsvSource ({"אייזק ,, ניוטון, אייזק ניוטון", "צ'ארלס, רוברט, דרווין, צ'רלס רוברט דרווין"}) בטל fullName_ShouldGenerateTheExpectedFullName (ArgumentsAccessor argumentsAccessor) {String firstName = argumentAccessor.getString (0); מחרוזת middleName = (מחרוזת) argumentAccessor.get (1); שם מחרוזת = argumentAccessor.get (2, String.class); מחרוזת expectFullName = argumentAccessor.getString (3); אדם אדם = אדם חדש (שם פרטי, שם אמצעי, שם משפחה); assertEquals (expectFullName, person.fullName ()); }

כאן אנו עוטפים את כל הטיעונים שהועברו ל ArgumentsAccessor מופע ואז, בגוף שיטת הבדיקה, מאחזר כל טיעון שהועבר עם האינדקס שלו. בנוסף להיותו רק אביזר, המרת סוג נתמכת באמצעות לקבל* שיטות:

  • getString (אינדקס) מאחזר אלמנט באינדקס ספציפי וממיר אותו ל חוּטtהדבר נכון גם לגבי טיפוסים פרימיטיביים
  • קבל (אינדקס) פשוט מאחזר אלמנט באינדקס ספציפי כ- לְהִתְנַגֵד
  • קבל (אינדקס, סוג) מאחזר אלמנט באינדקס ספציפי וממיר אותו לנתון סוּג

7. צבר ויכוחים

משתמש ב ArgumentsAccessor הפשטה ישירה עשויה להפוך את קוד הבדיקה לקריא או לשימוש חוזר פחות. על מנת לטפל בבעיות אלה, אנו יכולים לכתוב צובר מותאם אישית לשימוש חוזר.

לשם כך אנו מיישמים את ארגומנטים צבירה מִמְשָׁק:

מחלקה PersonAggregator מיישמת ArgumentsAggregator {@Override Public Object aggregateArguments (ArgumentsAccessor accessor, ParameterContext context) זורק ArgumentsAggregationException {להחזיר אדם חדש (accessor.getString (1), accessor.getString (2), accessor.getString (3)); }}

ואז אנו מתייחסים אליו באמצעות ה- @AggregateWith ביאור:

@ParameterizedTest @CsvSource ({"אייזיק ניוטון, אייזק, ניוטון", "צ'רלס רוברט דארווין, צ'רלס, רוברט, דרווין"}) ריק fullName_ShouldGenerateTheExpectedFullName (מחרוזת expectFullName, @AggregateWith (PersonAggregator.class) אדם אישי) person.fullName ()); }

ה PersonAggregator לוקח את שלושת הטיעונים האחרונים ומייצר א אדם כיתה מתוכם.

8. התאמה אישית של שמות תצוגה

כברירת מחדל, שם התצוגה של בדיקה פרמטרית מכיל אינדקס קריאה יחד עם a חוּט ייצוג של כל הטיעונים שהועברו, משהו כמו:

├─ someMonths_Are30DaysLongCsv (חודש) │ │ ├─ [1] אפריל │ │ ├─ [2] יוני E │ ├─ [3] SEPTEMBER │ │ └─ [4] נובמבר

עם זאת, אנו יכולים להתאים אישית את התצוגה באמצעות שֵׁם תכונה של @ParameterizedTest ביאור:

@ParameterizedTest (name = "{index} {0} אורך 30 יום") @EnumSource (value = Month.class, names = {"APRIL", "JUNE", "SEPTEMBER", "NOVEMBER"}) בטל someMonths_Are30DaysLong ( חודש חודש) {final boolean isALeapYear = false; assertEquals (30, month.length (isALeapYear)); }

אורך חודש אפריל אין ספק שהוא שם תצוגה קריא יותר:

├─ someMonths_Are30DaysLong (חודש) │ │ ├─ 1 אפריל אורך 30 יום │ │ ├─ 2 ביוני אורך 30 יום │ │ ├─ 3 SEPTEMBER אורך 30 יום │ │ └─ 4 NOVEMBER אורך 30 יום

מצייני המיקום הבאים זמינים בעת התאמה אישית של שם התצוגה:

  • {אינדקס} יוחלף באינדקס הפתיחה - במילים פשוטות, אינדקס הפנייה לביצוע הראשון הוא 1, עבור השני הוא 2, וכן הלאה
  • {טיעונים} הוא מציין מקום לרשימת הטיעונים המלאה ומופרדת בפסיקים
  • {0}, {1}, ... הם מצייני מקום לוויכוחים פרטניים

9. מסקנה

במאמר זה בחנו את האומים והברגים של בדיקות פרמטריות ב- JUnit 5.

למדנו שמבחנים פרמטרים שונים מהבדיקות הרגילות בשני היבטים: הם מוסברים עם ה- @ParameterizedTest, והם זקוקים למקור לטיעונים המוצהרים שלהם.

כמו כן, כעת עלינו כי JUnit מספקת כמה מתקנים להמרת הטיעונים לסוגי יעד מותאמים אישית או להתאמה אישית של שמות הבדיקה.

כרגיל, קודי המדגם זמינים בפרויקט GitHub שלנו, אז דאגו לבדוק זאת!


$config[zx-auto] not found$config[zx-overlay] not found