בית למפתחת האוטומציה
ציבורי קהילה
ציבורי קהילה
פעילות אחרונה: לפני 3 שבועות
מקום לשיתוף וקבלת מידע מקצועי בתחום האוטומציה
ציבורי קהילה
תשתית אוטומציה סלניום java – junit 5
קדם ‹ Forums ‹ בית למפתחת האוטומציה ‹ תשתית אוטומציה סלניום java – junit 5
-
תשתית אוטומציה סלניום java – junit 5
פורסם ע"י פייגי סברסקי חברה on 06/10/2021 ב3:56 pmהיי,
אני כותבת תשתית אוטומציה בסלניום java עם junit5
יש לי פרויקט maven) framework) עם קלאס BaseTest שבו הפונקציות
@BeforeAll
@AfterAll
public class BaseTest {
public static ExtentTest test;
public static ExtentReports report;
protected WebDriver driver;
@BeforeAllu
public static void setupClass() throws IOException {
String url = System.getProperty(“user.dir”)+”/reports/”;
String filename = Helper.getCurrentDatetimeStringByFormat(“yyyyMMdd_HHmmss”) + “_Report.html”;
report = new ExtentReports(url + filename);
}
@AfterEach
public void teardown() {
if (driver != null) {
driver.quit();
}
}
@AfterAll
public static void endTest(){
report.endTest(test);
report.flush();
}
}
ובפרויקט אחר מקושר יש לי את קלאס עבור טסטים למערכת הנבדקת
public class SanityTests extends BaseTest {
@BeforeEach
public void setupTest() throws IOException {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//system to test
String url = “”;
driver.get(url);
driver.manage().window().maximize();
}
@DisplayName(“loginTest”)
@Test
public void loginTest(TestInfo testInfo) {
test = report.startTest(testInfo.getDisplayName());
LoginPage lg = new LoginPage(driver);
HomePage hp = lg.login(“user”, “pass”);
if(lg.isOnPage(“Home Page”) == true)
test.log(LogStatus.PASS, “on home page”);
else
test.log(LogStatus.FAIL, “fail to login”);
}
}
כאשר אני מריצה – הפונקציות @AfterAll ו @AfterEach לא מתבצעות משום מה, וגם לא נזרקת הודעת שגיאה.
רק כשאר אני מעבירה אותן לקלאס SanityTests, או לקלאס בסיסי שבתוך הפרויקט – הן מתבצעות
האם למשהי יש מידע בעניין? ניסיתי לחפש המון ולא מצאתי
תודה,
פייגי
פייגי סברסקי הגיבה לפני 3 שנים, 3 חודשים 2 חברות · 6 תגובות -
6 תגובות
-
000חברה חדשה
פייגי שלום,
הסיבה היא שימוש לא נכון ב- Junit5
הסבר:
Junit5 נועד במקור לבצע unit tests, לא להוות תשתית לכלי אוטומציה.אנחנו, בודקי האוטומציה עושים ממנו תשתית לכלי אוטומציה.
אז בראייה של Java, נניח בראיה של מי שמפתח Java, קבצי test אמורים להיות בתיקיית Testולא בתיקיית main. ליתר דיוק, Junit לא סורק אחר התגיות @BeforeEach וכו’ עבור קבצים בתיקיית ה- main כי הם לא אמורים להיות שם.
אבל, אם את כותבת תשתית ואת רוצה לשים בפרויקט התשתית את ה- class שכתבת, את לא יכולה לשים אותו ב- test כי פרויקט הטסטים לא יראה אותו. אז את חייבת לשים אותו ב- main, ואז אמנם הפרויקט יראה אותו, אבל הוא לא יריץ אותו, כי לא נסרקה תיקיית ה- main בעת הריצה.יש פה בעיית שורש – כל מה שקשור לתגיות טסטים של junit מראש לא צריך להיות בתשתית.
אם רוצים לשים חלקים כאלה, הדרך הנכונה היא לכתוב extensions או listeners ואותם לשים בתשתית, ולקרוא להם מהטסטים.
בהצלחה רבה
-
-
000חברה חדשה
בוקר טוב,
להלן CLASS GenericExampleExtension שאת יכולה לכתוב בתשתית. ולהגדיר מה לבצע בכל שלב של הטסט.
הוא ממש INTERFACE ש JUNIT מספק,
AfterAll, AFTER EACH וכו. המתודות מקבלות אוביקט CONTEXT – זהו אוביקט של JUNIT והוא מכיל מידע על הטסט שרץ .
בכל מתודה כתבי קוד מתאים לצרכים שלך וכשהטסט יהיה בשלב המתאים למתודה – הוא יבצע את המתודה.
וזאת בתנאי שב CLASS טסט תצהירי שאת משתמש ב EXTENTION הזה .
כך:
@ExtendWith({GenericExampleExtension .class})
שורה זו תופיעה מעל חתימת ה CLASS טסט.
בהצלחה רבה
מוזמנת לשאול אם משהו לא ברור
דוגמה ל EXTENTION.
/**
* A generic extension implementation.
* This class is meant to serve as an example to copy parts from it and use them for other extension
* implementations.
* Note!! You don’t have to implement all the listed methods for all the extensions. Use this class as example only,
* choose the method that fit your needs and implements it’s interface only in the extension
*
* Some considerations when implementing extensions:
* 1. You must register the extension at the class level in order for it to be invoked.
* 2. afterAll and beforeAll work per container, which means that if you run several tests from different test
* classes these methods will be invoked more than once.
* 3. You may use more than 1 extension. Junit 5 guarantees that all extension methods will be executed.
* 4. However! Junit 5 does not guarantee the order of execution. So keep the single responsibility and
* independence of extensions.
*
*
* Some useful links to refer to:
* 1. Understanding Junit 5 extension model, from Junit5 user guide
* 2. Test lifecycle callback order is listed here
* 3. An example of VeriSoft: @see co.verisoft.selenium.framework.extensions.junit.PageSourceSaverExtension
* 4. Junit extension package javadoc
*
*
* @author Nir Gallner @ http://www.VeriSoft.co
* @since 2.0.3.9
*
*/
public class GenericExampleExtension implements
AfterTestExecutionCallback,
AfterAllCallback,
AfterEachCallback,
BeforeAllCallback,
BeforeEachCallback,
BeforeTestExecutionCallback,
TestWatcher {
private static final Logger logger = new ExtendedLog(Helper.class);
/**
* Callback that is invoked once after all tests in the current
* container.
*
* @param context the current extension context; never {@code null}
*/
@Override
public void afterAll(ExtensionContext context) throws Exception {
logger.info(“GeneralExampleExtension- In afterAll”);
}
/**
* Callback that is invoked after an individual test and any
* user-defined teardown methods for that test have been executed.
*
* @param context the current extension context; never {@code null}
*/
@Override
public void afterEach(ExtensionContext context) throws Exception {
logger.info(“GeneralExampleExtension- In afterEach”);
}
/**
* Callback that is invoked immediately after an individual test has
* been executed but before any user-defined teardown methods have been
* executed for that test.
*
* @param context the current extension context; never {@code null}
*/
@Override
public void afterTestExecution(ExtensionContext context) throws Exception {
logger.info(“GeneralExampleExtension- In afterTestExecution”);
}
/**
* Callback that is invoked once before all tests in the current
* container.
*
* @param context the current extension context; never {@code null}
*/
@Override
public void beforeAll(ExtensionContext context) throws Exception {
logger.info(“GeneralExampleExtension- In beforeAll”);
}
/**
* Callback that is invoked before an individual test and any
* user-defined setup methods for that test have been executed.
*
* @param context the current extension context; never {@code null}
*/
@Override
public void beforeEach(ExtensionContext context) throws Exception {
logger.info(“GeneralExampleExtension- In beforeEach”);
}
/**
* Callback that is invoked immediately before an individual test is
* executed but after any user-defined setup methods have been executed
* for that test.
*
* @param context the current extension context; never {@code null}
*/
@Override
public void beforeTestExecution(ExtensionContext context) throws Exception {
logger.info(“GeneralExampleExtension- In beforeTestExecution”);
}
/**
* Invoked after a disabled test has been skipped.
*
*
The default implementation does nothing. Concrete implementations can
* override this method as appropriate.
*
* @param context the current extension context; never {@code null}
* @param reason the reason the test is disabled; never {@code null} but
* potentially empty
*/
@Override
public void testDisabled(ExtensionContext context, Optional<String> reason) {
String s = “GeneralExampleExtension- Test ” + context.getDisplayName() + ” was disabled”;
if (reason.isPresent())
s += “, reason: ” + reason.toString();
logger.info(s);
}
/**
* Invoked after a test has completed successfully.
*
*
The default implementation does nothing. Concrete implementations can
* override this method as appropriate.
*
* @param context the current extension context; never {@code null}
*/
@Override
public void testSuccessful(ExtensionContext context) {
String s = “GeneralExampleExtension- Test ” + context.getDisplayName() + ” passed”;
logger.info(s);
}
/**
* Invoked after a test has been aborted.
*
*
The default implementation does nothing. Concrete implementations can
* override this method as appropriate.
*
* @param context the current extension context; never {@code null}
* @param cause the throwable responsible for the test being aborted; may be {@code null}
*/
@Override
public void testAborted(ExtensionContext context, Throwable cause) {
String s = “GeneralExampleExtension- Test ” + context.getDisplayName() + ” aborted”;
s += “, cause: ” + cause.getMessage();
logger.info(s);
}
/**
* Invoked after a test has failed.
*
*
The default implementation does nothing. Concrete implementations can
* override this method as appropriate.
*
* @param context the current extension context; never {@code null}
* @param cause the throwable that caused test failure; may be {@code null}
*/
@Override
public void testFailed(ExtensionContext context, Throwable cause) {
String s = “GeneralExampleExtension- Test ” + context.getDisplayName() + ” failed”;
s += “, cause: ” + cause.getMessage();
logger.info(s);
}
}
-
-
000חברה חדשה
היי יעל
תודה על המענה!
השאלה שלי היא איך בדיוק הטסט קלאס שלי יכיר במשתנים שאני מגדירה ומאתחלת בextention?
אני מעוניינת בגישה ישירה שם ובטסט קלאס לwebdriver ולextetntTest וextentReports,
בצורה זאת של של הצהרת שימוש בextention – אין לי גישה ישירה
כלומר – אינני מעוניינת לכתוב עבור כל טסט קלאס את האתחולים וסגירת המשאבים, אך עדיין אני מעוניינת בגישה ישירה אליהם מהקלאס.
תודה,
פייגי
-
000חברה חדשה
שלום פייגי,
אני מקווה שהמענה הקודם עזר לך,
והוא אמור לפתור את השאלה הקודמת שלך.
ולשאלת הנוכחית – איך את מאפשרת באופן תשתיתי גישה ל webDriver ול Report
מכל מקום בפרויקט (טסטים, Main וכו’)
את צריכה מבני נתונים שניתן לחלוק בין מחלקות.
לדוגמא הדוח צריך להיות singletone. (במידה ואת לא משתמשת בהרצה פרללית)
הדרייבר צריך להיות ב hash table לפי thread.
את מוזמנת להצטרף למפגשי האוטומציה – בפרטים שנשלח היום בע”ה,
שם תוכלי לקבל מענה לשאלותייך בנושא זה ובנושאים נוספים בתשתיות אוטומציה
בהצלחה רבה
-
-
000חברה חדשה
היי יעל!
בהחלט הועיל לי
גם הפוסט ששלחת אתמול הוסיף לי
מחכה לעדכונים על המפגשים…
תודה!
פייגי
Log in to reply.